type = $type; $this->response = $this->get_repo_cache(); $branch = new Branch( $this->response ); if ( ! empty( $type->branch ) ) { $this->type->branch = ! empty( $branch->cache['current_branch'] ) ? $branch->cache['current_branch'] : $type->branch; } $this->set_default_credentials(); $this->settings_hook( $this ); $this->add_settings_subtab(); $this->add_install_fields( $this ); } /** * Set default credentials if option not set. */ protected function set_default_credentials() { $running_servers = Singleton::get_instance( 'Base', $this )->get_running_git_servers(); $set_credentials = false; if ( $this instanceof Bitbucket_API ) { $username = 'bitbucket_username'; $password = 'bitbucket_password'; } if ( $this instanceof Bitbucket_Server_API ) { $username = 'bitbucket_server_username'; $password = 'bitbucket_server_password'; } if ( ! isset( static::$options[ $username ] ) ) { static::$options[ $username ] = null; $set_credentials = true; } if ( ! isset( static::$options[ $password ] ) ) { static::$options[ $password ] = null; $set_credentials = true; } if ( ( empty( static::$options[ $username ] ) || empty( static::$options[ $password ] ) ) && ( ( 'bitbucket_username' === $username && in_array( 'bitbucket', $running_servers, true ) ) || ( 'bitbucket_server_username' === $username && in_array( 'bbserver', $running_servers, true ) ) ) ) { Singleton::get_instance( 'Messages', $this )->create_error_message( 'bitbucket' ); static::$error_code['bitbucket'] = [ 'code' => 401 ]; } if ( $set_credentials ) { add_site_option( 'github_updater', static::$options ); } } /** * Read the remote file and parse headers. * * @access public * * @param string $file The file. * * @return bool */ public function get_remote_info( $file ) { return $this->get_remote_api_info( 'bitbucket', $file, "/2.0/repositories/:owner/:repo/src/:branch/{$file}" ); } /** * Get the remote info for tags. * * @access public * * @return bool */ public function get_remote_tag() { return $this->get_remote_api_tag( 'bitbucket', '/2.0/repositories/:owner/:repo/refs/tags' ); } /** * Read the remote CHANGES.md file. * * @access public * * @param string $changes The changelog filename. * * @return bool */ public function get_remote_changes( $changes ) { return $this->get_remote_api_changes( 'bitbucket', $changes, "/2.0/repositories/:owner/:repo/src/:branch/{$changes}" ); } /** * Read and parse remote readme.txt. * * @return bool */ public function get_remote_readme() { return $this->get_remote_api_readme( 'bitbucket', '/2.0/repositories/:owner/:repo/src/:branch/readme.txt' ); } /** * Read the repository meta from API * * @return bool */ public function get_repo_meta() { return $this->get_remote_api_repo_meta( 'bitbucket', '/2.0/repositories/:owner/:repo' ); } /** * Create array of branches and download links as array. * * @return bool */ public function get_remote_branches() { return $this->get_remote_api_branches( 'bitbucket', '/2.0/repositories/:owner/:repo/refs/branches' ); } /** * Return the Bitbucket release asset URL. * * @return string */ public function get_release_asset() { return $this->get_api_release_asset( 'bitbucket', '/2.0/repositories/:owner/:repo/downloads' ); } /** * Construct $this->type->download_link using Bitbucket API * * @param boolean $branch_switch For direct branch changing. Defaults to false. * * @return string $endpoint */ public function construct_download_link( $branch_switch = false ) { self::$method = 'download_link'; $download_link_base = $this->get_api_url( '/:owner/:repo/get/', true ); $endpoint = ''; // Release asset. if ( $this->type->release_asset && '0.0.0' !== $this->type->newest_tag ) { $release_asset = $this->get_release_asset(); return $this->get_release_asset_redirect( $release_asset, true ); } /* * If a branch has been given, use branch. * If branch is master (default) and tags are used, use newest tag. */ if ( 'master' !== $this->type->branch || empty( $this->type->tags ) ) { if ( ! empty( $this->type->enterprise_api ) ) { $endpoint = add_query_arg( 'at', $this->type->branch, $endpoint ); } else { $endpoint .= $this->type->branch . '.zip'; } } else { if ( ! empty( $this->type->enterprise_api ) ) { $endpoint = add_query_arg( 'at', $this->type->newest_tag, $endpoint ); } else { $endpoint .= $this->type->newest_tag . '.zip'; } } /* * Create endpoint for branch switching. */ if ( $branch_switch ) { if ( ! empty( $this->type->enterprise_api ) ) { $endpoint = add_query_arg( 'at', $branch_switch, $endpoint ); } else { $endpoint = $branch_switch . '.zip'; } } $download_link = $download_link_base . $endpoint; /** * Filter download link so developers can point to specific ZipFile * to use as a download link during a branch switch. * * @since 8.8.0 * * @param string $download_link Download URL. * @param /stdClass $this->type Repository object. * @param string $branch_switch Branch or tag for rollback or branch switching. */ return apply_filters( 'github_updater_post_construct_download_link', $download_link, $this->type, $branch_switch ); } /** * Create Bitbucket API endpoints. * * @param Bitbucket_API|API $git * @param string $endpoint * * @return string|void $endpoint */ public function add_endpoints( $git, $endpoint ) { switch ( $git::$method ) { case 'file': case 'readme': case 'meta': case 'changes': case 'translation': case 'release_asset': case 'download_link': break; case 'tags': case 'branches': $endpoint = add_query_arg( [ 'pagelen' => '100', 'sort' => '-name', ], $endpoint ); break; default: break; } $endpoint = $this->add_access_token_endpoint( $git, $endpoint ); return $endpoint; } /** * Parse API response call and return only array of tag numbers. * * @param \stdClass $response Response from API call. * * @return array|\stdClass Array of tag numbers, object is error. */ public function parse_tag_response( $response ) { if ( ! isset( $response->values ) || $this->validate_response( $response ) ) { return $response; } $arr = []; array_map( function ( $e ) use ( &$arr ) { $arr[] = $e->name; return $arr; }, (array) $response->values ); return $arr; } /** * Parse API response and return array of meta variables. * * @param \stdClass|array $response Response from API call. * * @return array $arr Array of meta variables. */ public function parse_meta_response( $response ) { if ( $this->validate_response( $response ) ) { return $response; } $arr = []; $response = [ $response ]; array_filter( $response, function ( $e ) use ( &$arr ) { $arr['private'] = $e->is_private; $arr['last_updated'] = $e->updated_on; $arr['watchers'] = 0; $arr['forks'] = 0; $arr['open_issues'] = 0; } ); return $arr; } /** * Parse API response and return array with changelog in base64. * * @param \stdClass|array $response Response from API call. * * @return array|\stdClass $arr Array of changes in base64, object if error. */ public function parse_changelog_response( $response ) { } /** * Parse API response and return array of branch data. * * @param \stdClass $response API response. * * @return array Array of branch data. */ public function parse_branch_response( $response ) { if ( $this->validate_response( $response ) ) { return $response; } $branches = []; foreach ( $response as $branch ) { $branches[ $branch->name ]['download'] = $this->construct_download_link( $branch->name ); $branches[ $branch->name ]['commit_hash'] = $branch->target->hash; $branches[ $branch->name ]['commit_timestamp'] = $branch->target->date; } return $branches; } /** * Parse tags and create download links. * * @param \stdClass|array $response Response from API call. * @param string $repo_type * * @return array */ protected function parse_tags( $response, $repo_type ) { $tags = []; $rollback = []; foreach ( (array) $response as $tag ) { // $download_base = implode( // '/', // [ // $repo_type['base_download'], // $this->type->owner, // $this->type->owner, // 'get/', // ] // ); $download_base = "{$repo_type['base_download']}/{$this->type->owner}/{$this->type->owner}/get/"; $tags[] = $tag; $rollback[ $tag ] = $download_base . $tag . '.zip'; } return [ $tags, $rollback ]; } /** * Add settings for Bitbucket Username and Password. * * @param array $auth_required * * @return void */ public function add_settings( $auth_required ) { add_settings_section( 'bitbucket_user', esc_html__( 'Bitbucket Private Settings', 'github-updater' ), [ $this, 'print_section_bitbucket_username' ], 'github_updater_bitbucket_install_settings' ); add_settings_field( 'bitbucket_username', esc_html__( 'Bitbucket Username', 'github-updater' ), [ Singleton::get_instance( 'Settings', $this ), 'token_callback_text' ], 'github_updater_bitbucket_install_settings', 'bitbucket_user', [ 'id' => 'bitbucket_username' ] ); add_settings_field( 'bitbucket_password', esc_html__( 'Bitbucket Password', 'github-updater' ), [ Singleton::get_instance( 'Settings', $this ), 'token_callback_text' ], 'github_updater_bitbucket_install_settings', 'bitbucket_user', [ 'id' => 'bitbucket_password', 'token' => true, ] ); /* * Show section for private Bitbucket repositories. */ if ( $auth_required['bitbucket_private'] ) { add_settings_section( 'bitbucket_id', esc_html__( 'Bitbucket Private Repositories', 'github-updater' ), [ $this, 'print_section_bitbucket_info' ], 'github_updater_bitbucket_install_settings' ); } } /** * Add values for individual repo add_setting_field(). * * @return mixed */ public function add_repo_setting_field() { $setting_field['page'] = 'github_updater_bitbucket_install_settings'; $setting_field['section'] = 'bitbucket_id'; $setting_field['callback_method'] = [ Singleton::get_instance( 'Settings', $this ), 'token_callback_checkbox', ]; return $setting_field; } /** * Add subtab to Settings page. */ private function add_settings_subtab() { add_filter( 'github_updater_add_settings_subtabs', function ( $subtabs ) { return array_merge( $subtabs, [ 'bitbucket' => esc_html__( 'Bitbucket', 'github-updater' ) ] ); } ); } /** * Print the Bitbucket repo Settings text. */ public function print_section_bitbucket_info() { esc_html_e( 'Check box if private repository. Leave unchecked for public repositories.', 'github-updater' ); } /** * Print the Bitbucket user/pass Settings text. */ public function print_section_bitbucket_username() { esc_html_e( 'Enter your personal Bitbucket username and password.', 'github-updater' ); } /** * Add remote install settings fields. * * @param string $type */ public function add_install_settings_fields( $type ) { if ( ( empty( static::$options['bitbucket_username'] ) || empty( static::$options['bitbucket_password'] ) ) || ( empty( static::$options['bitbucket_server_username'] ) || empty( static::$options['bitbucket_server_password'] ) ) ) { add_settings_field( 'bitbucket_username', esc_html__( 'Bitbucket Username', 'github-updater' ), [ $this, 'bitbucket_username' ], 'github_updater_install_' . $type, $type ); add_settings_field( 'bitbucket_password', esc_html__( 'Bitbucket Password', 'github-updater' ), [ $this, 'bitbucket_password' ], 'github_updater_install_' . $type, $type ); } add_settings_field( 'is_private', esc_html__( 'Private Bitbucket Repository', 'github-updater' ), [ $this, 'is_private_repo' ], 'github_updater_install_' . $type, $type ); } /** * Setting for private repo for remote install. */ public function is_private_repo() { ?>