wpdesk/wp-forms

此包的最新版本(3.2.0)没有可用的许可证信息。

WP Forms

维护者

详细信息

gitlab.wpdesk.dev/wpdesk/wp-forms

安装量: 26,496

依赖项: 5

建议者: 0

安全: 0

3.2.0 2023-03-16 09:09 UTC

README

pipeline status coverage report Latest Stable Version Total Downloads Latest Unstable Version License

WordPress 表单集成库

要求

PHP 7.0 或更高版本。

Composer

您可以通过 Composer 安装绑定。运行以下命令

composer require --dev wpdesk/wp-forms

要使用绑定,请使用 Composer 的 自动加载

require_once 'vendor/autoload.php';

用法

假设我们有一个设置标签的抽象

interface SettingsTab {
	/**
	 * Slug name used for unique url and settings in db.
	 */
	public static function get_tab_slug(): string;

	/**
	 * Tab name to show on settings page.
	 */
	public function get_tab_name(): string;

	/**
	 * Render tab content and return it as string.
	 */
	public function render( Renderer $renderer ): string;

	/**
	 * Use to set settings from database or defaults.
	 *
	 * @param ContainerInterface $data Data to render.
	 *
	 * @return void
	 */
	public function set_data( ContainerInterface $data );

	/**
	 * Use to handle request data from POST.
	 * Data in POST request should be prefixed with slug.
	 * For example if slug is 'stefan' and the input has name 'color' and value 'red' then the data should be sent as
	 * $_POST = [ 'stefan' => [ 'color' => 'red' ] ].
	 *
	 * @param array $request Data retrieved from POST request.
	 *
	 * @return void
	 */
	public function handle_request( array $request );

	/**
	 * Returns valid data from Tab. Can be used after ::handle_request or ::set_data.
	 *
	 * @return array
	 */
	public function get_data(): array;
}

然后对这些方法中的大多数进行抽象实现

abstract class FieldSettingsTab implements SettingsTab {
	/** @var FormWithFields */
	private $form;

	/**
	 * @return Field[]
	 */
	abstract protected function get_fields(): array;

	protected function get_form(): FormWithFields {
		if ( $this->form === null ) {
			$fields     = $this->get_fields();
			$this->form = new FormWithFields( $fields, static::get_tab_slug() );
		}

		return $this->form;
	}

	public function render( Renderer $renderer ) {
		return $this->get_form()->render_form( $renderer );
	}

	public function set_data( ContainerInterface $data ) {
		$this->get_form()->set_data( $data );
	}

	public function handle_request( array $request ) {
		$this->get_form()->handle_request( $request );
	}

	public function get_data(): array {
		return $this->get_form()->get_data();
	}
}

然后我们可以创建一个看起来像这样的设置标签

final class GeneralSettings extends FieldSettingsTab {
	protected function get_fields(): array {
		return [
			( new CheckboxField() )
				->set_label( __( 'Subscribe on checkout', 'some-text-domain' ) )
				->set_description( __( 'Ask customers to subscribe to your mailing list on checkout.',
					'some-text-domain' ) )
				->set_description_tip( __( 'Setup Mailchimp or other email service add-on first.',
					'some-text-domain' ) )
				->set_name( 'wc_settings_sm_subscribe_on_checkout' ),

			( new CheckboxField() )
				->set_label( __( 'Help Icon', 'some-text-domain' ) )
				->set_sublabel( __( 'Disable help icon', 'some-text-domain' ) )
				->set_description( __( 'Help icon shows only on pages with help articles and ability to ask for help. If you do not want the help icon to display, you can entirely disable it here.',
					'some-text-domain' ) )
				->set_name( 'disable_beacon' ),

			( new CheckboxField() )
				->set_label( __( 'Usage Data', 'some-text-domain' ) )
				->set_sublabel( __( 'Enable', 'some-text-domain' ) )
				->set_description( sprintf( __( 'Help us improve Application and allow us to collect insensitive plugin usage data, %sread more%s.',
					'some-text-domain' ), '<a href="' . TrackerNotices::USAGE_DATA_URL . '" target="_blank">',
					'</a>' ) )
				->set_name( 'wpdesk_tracker_agree' ),

			( new SubmitField() )
				->set_name( 'save' )
				->set_label( __( 'Save changes', 'some-text-domain' ) )
				->add_class( 'button-primary' )
		];
	}

	public static function get_tab_slug() {
		return 'general';
	}

	public function get_tab_name() {
		return __( 'General', 'text-domain' );
	}
}

然后像这样的类提供了对这个抽象的表单加载/保存/渲染支持

/**
 * Adds settings to the menu and manages how and what is shown on the settings page.
 */
final class Settings {
	/**
	 * Save POST tab data. Before render.
	 *
	 * @return void
	 */
	public function save_settings_action() {
		if ( isset( $_GET['page'] ) && $_GET['page'] !== self::$settings_slug ) {
			return;
		}
		$tab            = $this->get_active_tab();
		$data_container = self::get_settings_persistence( $tab::get_tab_slug() );
		if ( ! empty( $_POST ) && isset( $_POST[ $tab::get_tab_slug() ] ) ) {
			$tab->handle_request( $_POST[ $tab::get_tab_slug() ] );
			$this->save_tab_data( $tab, $data_container );

			new Notice( __( 'Your settings have been saved.', 'text-domain' ),
				Notice::NOTICE_TYPE_SUCCESS );
		} else {
			$tab->set_data( $data_container );
		}
	}

	/**
	 * @return void
	 */
	public function render_page_action() {
		$tab      = $this->get_active_tab();
		$renderer = $this->get_renderer();
		echo $renderer->render( 'menu', [
			'base_url'   => self::get_url(),
			'menu_items' => $this->get_tabs_menu_items(),
			'selected'   => $this->get_active_tab()->get_tab_slug()
		] );
		echo $tab->render( $renderer );
		echo $renderer->render( 'footer' );
	}

	private function get_active_tab(): SettingTab {
		$selected_tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : null;
		$tabs         = $this->get_settings_tabs();
		if ( ! empty( $selected_tab ) && isset( $tabs[ $selected_tab ] ) ) {
			return $tabs[ $selected_tab ];
		}

		return reset( $tabs );
	}

	/**
	 * @return SettingsTab[]
	 */
	private function get_settings_tabs(): array {
		static $tabs = [];
		if ( empty( $tabs ) ) {
			$tabs = [
				GeneralSettings::get_tab_slug()   => new GeneralSettings(),
				SomeOtherSettings::get_tab_slug() => new SomeOtherSettings()
			];
		}

		return $tabs;
	}

	/**
	 * Returns writable container with saved settings.
	 *
	 * @param string $tab_slug Unique slug of a settings tab.
	 *
	 * @return PersistentContainer
	 */
	public static function get_settings_persistence( string $tab_slug ): PersistentContainer {
		return new WordpressOptionsContainer( 'some-settings-' . $tab_slug );
	}

	/**
	 * Save data from tab to persistent container.
	 */
	private function save_tab_data( SettingsTab $tab, PersistentContainer $container ) {
		$tab_data = $tab->get_data();
		array_walk( $tab_data, static function ( $value, $key ) use ( $container ) {
			if ( ! empty( $key ) ) {
				$container->set( $key, $value );
			}
		} );
	}

	private function get_renderer(): \WPDesk\View\Renderer\Renderer {
		return new SimplePhpRenderer( new DefaultFormFieldResolver() );
	}

	/**
	 * @return string[]
	 */
	private function get_tabs_menu_items(): array {
		$menu_items = [];

		foreach ( $this->get_settings_tabs() as $tab ) {
			$menu_items[ $tab::get_tab_slug() ] = $tab->get_tab_name();
		}

		return $menu_items;
	}
}