'object', 'properties' => array( 'multiline' => array( 'type' => 'boolean' ), 'max_length' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => self::MAX_LENGTH, ), 'placeholder' => array( 'type' => 'string' ), 'charge_when_filled' => array( 'type' => 'boolean' ), ), ); } /** * {@inheritDoc} * * @param array $config Raw config. */ public function sanitize_config( array $config ): array { $max = absint( $config['max_length'] ?? 200 ); return array( 'multiline' => rest_sanitize_boolean( $config['multiline'] ?? true ), 'max_length' => max( 1, min( self::MAX_LENGTH, 0 === $max ? 200 : $max ) ), 'placeholder' => sanitize_text_field( (string) ( $config['placeholder'] ?? '' ) ), 'charge_when_filled' => rest_sanitize_boolean( $config['charge_when_filled'] ?? false ), ); } /** * Configured limit. * * @param Extra $extra Extra. */ private function max_length( Extra $extra ): int { $max = (int) ( $extra->type_config['max_length'] ?? 200 ); return max( 1, min( self::MAX_LENGTH, $max ) ); } /** * {@inheritDoc} * * The value is not truncated: an over-long text fails validation so the customer notices. * * @param mixed $raw Raw value. * @param Extra $extra Extra. */ public function sanitize_value( mixed $raw, Extra $extra ): mixed { if ( ! is_string( $raw ) && ! is_int( $raw ) && ! is_float( $raw ) ) { return null; } $raw = mb_substr( (string) $raw, 0, self::HARD_CAP ); $value = ! empty( $extra->type_config['multiline'] ) ? sanitize_textarea_field( $raw ) : sanitize_text_field( $raw ); $value = trim( $value ); return '' === $value ? null : $value; } /** * {@inheritDoc} * * @param Extra $extra Extra. * @param Selection|null $selection Selection. * @param Context $context Context. */ public function validate( Extra $extra, ?Selection $selection, Context $context ): true|\WP_Error { $result = parent::validate( $extra, $selection, $context ); if ( true !== $result ) { return $result; } if ( $selection && is_string( $selection->value ) ) { $max = $this->max_length( $extra ); if ( mb_strlen( $selection->value ) > $max ) { return new \WP_Error( 'extrova_too_long', sprintf( /* translators: 1: extra label, 2: maximum number of characters. */ _n( '%1$s cannot be longer than %2$d character.', '%1$s cannot be longer than %2$d characters.', $max, 'extrova' ), $extra->label, $max ), array( 'extra_id' => $extra->id ) ); } } return true; } /** * {@inheritDoc} * * @param Extra $extra Extra. * @param Selection $selection Selection. */ public function is_chargeable( Extra $extra, Selection $selection ): bool { return ! empty( $extra->type_config['charge_when_filled'] ) && is_string( $selection->value ) && '' !== $selection->value; } /** * {@inheritDoc} * * @param Extra $extra Extra. * @param Selection $selection Selection. */ public function display_value( Extra $extra, Selection $selection ): string { return is_string( $selection->value ) ? $selection->value : ''; } /** * {@inheritDoc} * * @param Extra $extra Extra. * @param Context $context Context. */ public function to_client( Extra $extra, Context $context ): array { return array( 'multiline' => ! empty( $extra->type_config['multiline'] ), 'max_length' => $this->max_length( $extra ), 'placeholder' => (string) ( $extra->type_config['placeholder'] ?? '' ), 'charge_when_filled' => ! empty( $extra->type_config['charge_when_filled'] ), ); } /** * {@inheritDoc} * * @param Extra $extra Extra. */ public function preview_selections( Extra $extra ): array { return ! empty( $extra->type_config['charge_when_filled'] ) ? array( '' => 'x' ) : array(); } /** * {@inheritDoc} * * @param Extra $extra Extra. * @param Selection|null $selection Selection. * @param Context $context Context. */ public function render_classic( Extra $extra, ?Selection $selection, Context $context ): string { $id = $this->field_id( $extra ); $counter_id = $this->field_id( $extra, 'counter' ); $value = $selection && is_string( $selection->value ) ? $selection->value : ''; $max = $this->max_length( $extra ); $placeholder = (string) ( $extra->type_config['placeholder'] ?? '' ); $common = ' id="' . esc_attr( $id ) . '" name="' . esc_attr( $this->field_name( $extra ) ) . '" maxlength="' . esc_attr( (string) $max ) . '" data-extrova-maxlength="' . esc_attr( (string) $max ) . '"' . ( '' !== $placeholder ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '' ) . ( $extra->required ? ' aria-required="true"' : '' ) . $this->describedby_attr( $extra, array( $counter_id ) ); $html = '
' . esc_html( sprintf( /* translators: %d: maximum number of characters. */ _n( 'Maximum %d character.', 'Maximum %d characters.', $max, 'extrova' ), $max ) ) . '
'; $html .= ''; $html .= '