Parsed: 128433

  public function create_item( $request ) {
    global $wp_filesystem;

    require_once ABSPATH . 'wp-admin/includes/file.php';
    require_once ABSPATH . 'wp-admin/includes/plugin.php';
    require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    require_once ABSPATH . 'wp-admin/includes/plugin-install.php';

    $slug = $request['slug'];

    // Verify filesystem is accessible first.
    $filesystem_available = $this->is_filesystem_available();
    if ( is_wp_error( $filesystem_available ) ) {
      return $filesystem_available;
    }

    $api = plugins_api(
      'plugin_information',
      array(
        'slug'   => $slug,
        'fields' => array(
          'sections'       => false,
          'language_packs' => true,
        ),
      )
    );

    if ( is_wp_error( $api ) ) {
      if ( str_contains( $api->get_error_message(), 'Plugin not found.' ) ) {
        $api->add_data( array( 'status' => 404 ) );
      } else {
        $api->add_data( array( 'status' => 500 ) );
      }

      return $api;
    }

    $skin     = new WP_Ajax_Upgrader_Skin();
    $upgrader = new Plugin_Upgrader( $skin );

    $result = $upgrader->install( $api->download_link );

    if ( is_wp_error( $result ) ) {
      $result->add_data( array( 'status' => 500 ) );

      return $result;
    }

    // This should be the same as $result above.
    if ( is_wp_error( $skin->result ) ) {
      $skin->result->add_data( array( 'status' => 500 ) );

      return $skin->result;
    }

    if ( $skin->get_errors()->has_errors() ) {
      $error = $skin->get_errors();
      $error->add_data( array( 'status' => 500 ) );

      return $error;
    }

    if ( is_null( $result ) ) {
      // Pass through the error from WP_Filesystem if one was raised.
      if ( $wp_filesystem instanceof WP_Filesystem_Base
        && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors()
      ) {
        return new WP_Error(
          'unable_to_connect_to_filesystem',
          $wp_filesystem->errors->get_error_message(),
          array( 'status' => 500 )
        );
      }

      return new WP_Error(
        'unable_to_connect_to_filesystem',
        __( 'Unable to connect to the filesystem. Please confirm your credentials.' ),
        array( 'status' => 500 )
      );
    }

    $file = $upgrader->plugin_info();

    if ( ! $file ) {
      return new WP_Error(
        'unable_to_determine_installed_plugin',
        __( 'Unable to determine what plugin was installed.' ),
        array( 'status' => 500 )
      );
    }

    if ( 'inactive' !== $request['status'] ) {
      $can_change_status = $this->plugin_status_permission_check( $file, $request['status'], 'inactive' );

      if ( is_wp_error( $can_change_status ) ) {
        return $can_change_status;
      }

      $changed_status = $this->handle_plugin_status( $file, $request['status'], 'inactive' );

      if ( is_wp_error( $changed_status ) ) {
        return $changed_status;
      }
    }

    // Install translations.
    $installed_locales = array_values( get_available_languages() );
    
/** This filter is documented in wp-includes/update.php */
    $installed_locales = apply_filters( 'plugins_update_check_locales', $installed_locales );

    $language_packs = array_map(
      static function ( $item ) {
        return (object) $item;
      },
      $api->language_packs
    );

    $language_packs = array_filter(
      $language_packs,
      static function ( $pack ) use ( $installed_locales ) {
        return in_array( $pack->language, $installed_locales, true );
      }
    );

    if ( $language_packs ) {
      $lp_upgrader = new Language_Pack_Upgrader( $skin );

      // Install all applicable language packs for the plugin.
      $lp_upgrader->bulk_upgrade( $language_packs );
    }

    $path          = WP_PLUGIN_DIR . '/' . $file;
    $data          = get_plugin_data( $path, false, false );
    $data['_file'] = $file;

    $response = $this->prepare_item_for_response( $data, $request );
    $response->set_status( 201 );
    $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $file, 0, - 4 ) ) ) );

    return $response;
  }