plugin = $plugin; } /** * The select value that stands for a rule ("skip", "fixed", "ask", "field:brand", "attr:pa_color"). * * @param AttributeRule $rule Rule. */ public static function source_value( AttributeRule $rule ): string { switch ( $rule->type ) { case AttributeRule::FIELD: return 'field:' . $rule->key; case AttributeRule::WC_ATTRIBUTE: return 'attr:' . $rule->key; case AttributeRule::FIXED: return 'fixed'; case AttributeRule::ASK: return 'ask'; } return 'skip'; } /** * The rule type and key for a select value. * * @param string $value Select value. * @return array{type:string, key:string} */ public static function parse_source( string $value ): array { if ( 0 === strpos( $value, 'field:' ) && in_array( substr( $value, 6 ), AttributeRule::FIELDS, true ) ) { return array( 'type' => AttributeRule::FIELD, 'key' => substr( $value, 6 ), ); } if ( 0 === strpos( $value, 'attr:' ) && strlen( $value ) > 5 ) { return array( 'type' => AttributeRule::WC_ATTRIBUTE, 'key' => substr( $value, 5 ), ); } if ( 'fixed' === $value || 'ask' === $value ) { return array( 'type' => $value, 'key' => '', ); } return array( 'type' => AttributeRule::SKIP, 'key' => '', ); } /** * Renders the page. */ public function render(): void { if ( ! current_user_can( Plugin::CAPABILITY ) ) { return; } $channel = $this->plugin->requested_channel(); $channel_label = $channel->label(); $map_cats = array_values( array_unique( array_map( 'intval', array_values( $this->plugin->category_map( $channel->id() )->all() ) ) ) ); sort( $map_cats ); $tree = $channel->taxonomy()->index(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- a read-only choice of what to show. $wanted = isset( $_GET['remote_cat'] ) ? absint( $_GET['remote_cat'] ) : 0; $cat = in_array( $wanted, $map_cats, true ) ? $wanted : ( $map_cats ? $map_cats[0] : 0 ); ?>

' . wp_kses( sprintf( /* translators: %s: link to the category mapping screen */ Text::channel( __( 'No {channel} category is mapped yet. Start with the %s.', 'tidelist' ), $channel_label ), '' . esc_html__( 'category mapping', 'tidelist' ) . '' ), array( 'a' => array( 'href' => array() ) ) ) . '

'; return; } ?>
render_category( $channel, $cat ); ?> label(); $definitions = $channel->taxonomy()->attributes( $cat ); if ( ! $definitions ) { echo '

' . esc_html( Text::channel( __( 'The attributes of this category could not be read from {channel}. Connect the {channel} application (Connect page) and reload.', 'tidelist' ), $channel_label ) ) . '

'; return; } usort( $definitions, static function ( $a, $b ) { return (int) ! empty( $b['validation']['required'] ) <=> (int) ! empty( $a['validation']['required'] ); } ); $values = new ProductValues(); $wc_attrs = $values->attribute_labels(); $saved = $this->plugin->attribute_map( $channel->id() )->rules_for( $cat ); ?>
managed_attributes(), true ) ) { continue; // Set in the channel's own settings. } $required = ! empty( $definition['validation']['required'] ); $allowed = (array) ( $definition['values'] ?? array() ); $rule = $saved[ $code ] ?? AttributeSuggester::suggest( $definition, $wc_attrs ); $current = self::source_value( $rule ); ?>

type ) { $this->render_values( $code, $rule, $allowed, $values->attribute_terms( $rule->key ), $channel_label ); } ?>
has_unmapped( $rule, $allowed, $terms ) ? 'open' : ''; ?>> $term ) : ?> values[ $key ] ?? ''; $suggested = ValueSuggester::suggest( $term, $allowed ); ?>
values[ Normalizer::key( $term ) ] ) && null === ValueSuggester::suggest( $term, $allowed ) ) { return true; } } return false; } /** * Label of a marketplace value. * * @param array $allowed Allowed values. * @param string $code Code. */ private function label_of( array $allowed, string $code ): string { foreach ( $allowed as $value ) { if ( (string) $value['code'] === $code ) { return (string) ( $value['label'] ?? $code ); } } return $code; } /** * Name of a product field. * * @param string $field Field. */ private function field_label( string $field ): string { $labels = array( 'brand' => __( 'Brand', 'tidelist' ), 'sku' => __( 'SKU', 'tidelist' ), 'weight' => __( 'Weight', 'tidelist' ), 'length' => __( 'Length', 'tidelist' ), 'width' => __( 'Width', 'tidelist' ), 'height' => __( 'Height', 'tidelist' ), 'title' => __( 'Product name', 'tidelist' ), ); return $labels[ $field ] ?? $field; } }