4 * Class WP_Installer_Channels
7 class WP_Installer_Channels{
9 const CHANNEL_PRODUCTION = 'production';
10 const CHANNEL_BETA = 'beta';
11 const CHANNEL_DEVELOPMENT = 'development';
13 protected static $_instance = null;
15 function __construct() {
16 add_action( 'init', array( $this, 'init' ), 20 ); // after Installer
20 * @return null|WP_Installer_Channels
22 public static function instance() {
24 if ( is_null( self::$_instance ) ) {
25 self::$_instance = new self();
28 return self::$_instance;
32 * Get the channel literal id based on the numeric id
38 public static function channel_name_by_id( $id ) {
39 if ( self::CHANNEL_DEVELOPMENT === $id ) {
40 $channel = __( 'Development', 'installer' );
41 } elseif ( self::CHANNEL_BETA === $id ) {
42 $channel = __( 'Beta', 'installer' );
44 $channel = __( 'Production', 'installer' );
53 public function init(){
56 if ( defined( 'DOING_AJAX' ) ) {
57 add_action( 'wp_ajax_installer_set_channel', array( $this, 'set_channel' ) );
60 if ( $pagenow === 'plugin-install.php' && isset( $_GET['tab'] ) && $_GET['tab'] === 'commercial' ) {
61 wp_enqueue_script( 'installer-channels', WP_Installer()->res_url() . '/res/js/channels.js', array( 'jquery' ), WP_Installer()->version() );
67 * Ajax handler for channel switching
69 public function set_channel(){
70 $repository_id = sanitize_text_field( $_POST['repository_id'] );
71 $channel = sanitize_text_field( $_POST['channel'] );
75 if( $_POST['nonce'] === wp_create_nonce( 'installer_set_channel:' . $repository_id ) ){
77 if( isset( WP_Installer()->settings['repositories'][$repository_id] ) ){
78 WP_Installer()->settings['repositories'][$repository_id]['channel'] = $channel;
79 WP_Installer()->settings['repositories'][$repository_id]['no-prompt'] = $_POST['noprompt'] === 'true';
80 WP_Installer()->save_settings();
83 WP_Installer()->refresh_repositories_data();
85 $response['status'] = 'OK';
88 echo json_encode( $response );
93 * @param string $repository_id
97 public function get_channel( $repository_id ){
98 $channel = self::CHANNEL_PRODUCTION;
99 if( isset( WP_Installer()->settings['repositories'][$repository_id]['channel'] ) ){
100 $channel = WP_Installer()->settings['repositories'][$repository_id]['channel'];
106 * @param string $repository_id
107 * @param array $downloads
109 public function load_channel_selector( $repository_id, $downloads ) {
111 $available_channels = $this->get_available_channels( $repository_id );
113 if ( $available_channels ) {
115 'can_switch' => $this->can_use_unstable_channels( $downloads ) || $this->get_channel( $repository_id ) > 1,
116 'channels' => $available_channels,
117 'repository_id' => $repository_id,
118 'current_channel' => $this->get_channel( $repository_id ),
119 'no_prompt' => !empty( WP_Installer()->settings['repositories'][ $repository_id ]['no-prompt'] ),
120 'nonce' => wp_create_nonce( 'installer_set_channel:' . $repository_id )
123 include WP_Installer()->plugin_path() . '/templates/channel-selector.php';
128 * The beta and development channels can be used only when already using the most up to date versions
129 * @param array $downloads
133 public function can_use_unstable_channels( $downloads ){
136 foreach( $downloads as $download ){
137 $available_version = $download['version'];
138 $installed_version = WP_Installer()->plugin_is_installed( $download['name'], $download['slug'] );
139 if( $installed_version !== false && version_compare( $available_version, $installed_version, '>' ) ){
149 * Get available updates channels. Only include channels with actual downloads available.
151 * @param string $repository_id
155 public function get_available_channels( $repository_id ) {
160 $downloads = WP_Installer()->settings['repositories'][ $repository_id ]['data']['downloads'];
161 foreach ( $downloads as $type => $download_types ) {
162 foreach ( $download_types as $download ) {
163 $extra_channels = isset( $download['extra_channels'] ) ? array_keys( $download['extra_channels'] ) : array();
164 if ( ! $beta && in_array( self::CHANNEL_BETA, $extra_channels ) ) {
167 if ( ! $dev && in_array( self::CHANNEL_DEVELOPMENT, $extra_channels ) ) {
170 if ( $beta && $dev ) {
177 if ( $beta || $dev ) {
178 $channels[ self::CHANNEL_PRODUCTION ] = self::channel_name_by_id( self::CHANNEL_PRODUCTION );
180 $channels[ self::CHANNEL_BETA ] = self::channel_name_by_id( self::CHANNEL_BETA );
183 $channels[ self::CHANNEL_DEVELOPMENT ] = self::channel_name_by_id( self::CHANNEL_DEVELOPMENT );
191 * @param string $repository_id
192 * @param array $downloads
196 public function filter_downloads_by_channel( $repository_id, $downloads ) {
198 $current_channel = $this->get_channel( $repository_id );
200 foreach ( $downloads as $type => $type_downloads ) {
201 foreach ( $type_downloads as $slug => $download ) {
203 $override_download = array();
204 if ( $current_channel === self::CHANNEL_DEVELOPMENT ) {
205 if( ! empty( $download['channels']['development'] ) ){
206 $override_download = $download['channels']['development'];
207 $override_download['channel'] = self::CHANNEL_DEVELOPMENT;
208 }elseif( ! empty( $download['channels']['beta'] ) ){
209 $override_download = $download['channels']['beta'];
210 $override_download['channel'] = self::CHANNEL_BETA;
212 }elseif ( $current_channel === self::CHANNEL_BETA && ! empty( $download['channels']['beta'] ) ) {
213 $override_download = $download['channels']['beta'];
214 $override_download['channel'] = self::CHANNEL_BETA;
217 if ( $override_download ) {
218 foreach ( $override_download as $key => $value ) {
219 $downloads[ $type ][ $slug ][ $key ] = $value;
222 $downloads[ $type ][ $slug ]['channel'] = self::CHANNEL_PRODUCTION;
224 unset ( $downloads[ $type ][ $slug ]['channels'] );
226 $downloads[ $type ][ $slug ]['extra_channels'] = array();
227 if( isset( $download['channels'] ) ) {
228 foreach( $download['channels'] as $channel_id => $channel ){
229 $downloads[ $type ][ $slug ]['extra_channels'][$channel_id] = array(
230 'version' => $channel['version']
242 * Get the source channel for the installed version when on the Beta or Development channel
243 * @param string $version
244 * @param string $repository_id
245 * @param string $download_id
246 * @param string $download_kind
250 public function get_download_source_channel( $version, $repository_id, $download_id, $download_kind ) {
252 $version_channel = '';
253 $installer_settings = WP_Installer()->get_settings();
254 if ( isset( $installer_settings['repositories'][ $repository_id ] ) ) {
255 $repository_data = $installer_settings['repositories'][ $repository_id ]['data'];
256 if ( isset( $repository_data['downloads'][ $download_kind ][ $download_id ]['extra_channels'] ) ) {
258 foreach ( $repository_data['downloads'][ $download_kind ][ $download_id ]['extra_channels'] as $channel_id => $channel_data ) {
259 if ( $version === $channel_data['version'] ) {
260 $version_channel = self::channel_name_by_id( $channel_id );
269 return $version_channel;