self::SOURCE_TITLE, 'apply_content' => 1, 'apply_attachments' => 1, ); } /** * The alt text sources, as value => label. * * @return string[] */ public static function get_sources() { return array( self::SOURCE_TITLE => __( 'Attachment title', 'devlab-image-alt' ), self::SOURCE_CAPTION => __( 'Caption', 'devlab-image-alt' ), self::SOURCE_DESCRIPTION => __( 'Description', 'devlab-image-alt' ), self::SOURCE_FILENAME => __( 'File name (cleaned up)', 'devlab-image-alt' ), ); } /** * Returns the current settings (cached for the request). * * @return array { * @type string $source One of the SOURCE_* values. * @type int $apply_content 1 to fill alt text inside post content. * @type int $apply_attachments 1 to fill alt text on attachment images * (featured images, template images). * } */ public static function get() { if ( null === self::$cache ) { self::$cache = self::normalise( get_option( self::OPTION, array() ) ); } return self::$cache; } /** * Clears the in-memory copy. * * @return void */ public static function flush_cache() { self::$cache = null; } /** * Fills in defaults and forces the right type on every key. * * The database value is re-validated on every read, because it may have * been written by WP-CLI, another plugin or a restore. * * @param mixed $stored Value read from the database. * @return array Normalised settings. */ public static function normalise( $stored ) { $stored = is_array( $stored ) ? $stored : array(); $defaults = self::defaults(); $out = $defaults; if ( isset( $stored['source'] ) && is_string( $stored['source'] ) && in_array( $stored['source'], self::SOURCES, true ) ) { $out['source'] = $stored['source']; } foreach ( array( 'apply_content', 'apply_attachments' ) as $key ) { if ( array_key_exists( $key, $stored ) ) { $out[ $key ] = self::to_flag( $stored[ $key ] ); } } return $out; } /** * Turns a stored or submitted value into 1 or 0. * * @param mixed $value Raw value. * @return int */ private static function to_flag( $value ) { if ( is_string( $value ) ) { $value = strtolower( trim( $value ) ); return in_array( $value, array( '1', 'true', 'on', 'yes' ), true ) ? 1 : 0; } return empty( $value ) ? 0 : 1; } /** * Registers the option with the Settings API. * * The Settings API form posts to options.php, which checks the nonce and * the manage_options capability before this option is touched. * * @return void */ public function register() { register_setting( self::GROUP, self::OPTION, array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize' ), 'default' => self::defaults(), 'show_in_rest' => false, ) ); } /** * Sanitize callback for the option. * * The file options.php has already run wp_unslash() on the submitted data. * A key that is missing from the submission keeps its current value. * * @param mixed $input Submitted value. * @return array Value to store. */ public function sanitize( $input ) { $new = self::normalise( get_option( self::OPTION, array() ) ); $input = is_array( $input ) ? $input : array(); if ( isset( $input['source'] ) && is_string( $input['source'] ) ) { $source = sanitize_key( $input['source'] ); if ( in_array( $source, self::SOURCES, true ) ) { $new['source'] = $source; } } foreach ( array( 'apply_content', 'apply_attachments' ) as $key ) { if ( array_key_exists( $key, $input ) ) { $new[ $key ] = self::to_flag( $input[ $key ] ); } } if ( ! $new['apply_content'] && ! $new['apply_attachments'] ) { $this->add_notice_once( 'devlab_alt_all_off', __( 'Both options are off, so no alt text is filled in until you switch one on.', 'devlab-image-alt' ), 'warning' ); } $this->add_notice_once( 'devlab_alt_saved', __( 'Settings saved.', 'devlab-image-alt' ), 'success' ); return $new; } /** * Queues a Settings API notice only once per request. * * @param string $code Unique notice code. * @param string $message Already translated, plain-text message. * @param string $type error|warning|success|info. * @return void */ private function add_notice_once( $code, $message, $type ) { // add_settings_error() is an admin-only function; skip the notice if the // callback is ever reached from a context where it is not loaded. if ( isset( self::$notices_added[ $code ] ) || ! function_exists( 'add_settings_error' ) ) { return; } self::$notices_added[ $code ] = true; add_settings_error( 'devlab_alt_messages', $code, $message, $type ); } }