Settings -> Products -> Strikewise. */ final class Settings { const SECTION = 'strikewise'; public function register(): void { add_filter( 'woocommerce_get_sections_products', array( $this, 'add_section' ) ); add_filter( 'woocommerce_get_settings_products', array( $this, 'get_settings' ), 10, 2 ); add_action( 'woocommerce_admin_field_strikewise_intro', array( $this, 'render_intro' ) ); add_filter( 'plugin_action_links_' . plugin_basename( STRIKEWISE_FILE ), array( $this, 'action_links' ) ); } /** * @param array $sections * @return array */ public function add_section( $sections ) { $sections[ self::SECTION ] = __( 'Strikewise', 'strikewise' ); return $sections; } /** * @param array> $settings * @param string $current_section * @return array> */ public function get_settings( $settings, $current_section ) { if ( self::SECTION !== $current_section ) { return $settings; } $fields = array( array( 'type' => 'strikewise_intro', 'id' => 'strikewise_intro', ), array( 'title' => __( 'Display in the shop', 'strikewise' ), 'type' => 'title', 'desc' => __( 'Shows the lowest price of the 30 days before a price reduction, as required by Art. 6a of Directive 98/6/EC (in Germany § 11 PAngV). This is not legal advice.', 'strikewise' ), 'id' => 'strikewise_display', ), array( 'title' => __( 'When to show', 'strikewise' ), 'id' => 'strikewise_mode', 'type' => 'select', 'default' => ReferenceCalculator::MODE_REDUCTION, 'options' => array( ReferenceCalculator::MODE_REDUCTION => __( 'Only for reduced products (legal requirement)', 'strikewise' ), ReferenceCalculator::MODE_ALWAYS => __( 'Always: lowest price of the last 30 days', 'strikewise' ), ), ), array( 'title' => __( 'Show on', 'strikewise' ), 'desc' => __( 'Single product page', 'strikewise' ), 'id' => 'strikewise_show_single', 'type' => 'checkbox', 'default' => 'yes', 'checkboxgroup' => 'start', ), array( 'desc' => __( 'Shop, category and other product lists', 'strikewise' ), 'id' => 'strikewise_show_loop', 'type' => 'checkbox', 'default' => 'yes', 'checkboxgroup' => 'end', ), array( 'title' => __( 'Text', 'strikewise' ), 'desc' => __( '{price} is replaced with the lowest price.', 'strikewise' ), 'id' => 'strikewise_text', 'type' => 'text', 'default' => '', 'placeholder' => self::default_text(), 'css' => 'min-width: 400px;', ), array( 'title' => __( 'Notice without price history', 'strikewise' ), 'desc' => __( 'What to show for a reduced product when no price from before the reduction is known, e.g. directly after installing Strikewise.', 'strikewise' ), 'id' => 'strikewise_fallback', 'type' => 'select', 'default' => 'hide', 'options' => array( 'hide' => __( 'Show nothing', 'strikewise' ), 'text' => __( 'Show a custom text', 'strikewise' ), ), ), array( 'title' => __( 'Custom text', 'strikewise' ), 'id' => 'strikewise_fallback_text', 'type' => 'text', 'default' => '', 'placeholder' => self::default_fallback_text(), 'css' => 'min-width: 400px;', ), Perishable::setting(), array( 'type' => 'sectionend', 'id' => 'strikewise_display', ), ); /** * Filters the Strikewise settings. Premium features add complete groups * (a "title" row, their fields and a "sectionend" row). * * @param array> $fields */ $fields = (array) apply_filters( 'strikewise_settings', $fields ); if ( Licensing::show_upsell() ) { $fields[] = array( 'title' => __( 'Premium', 'strikewise' ), 'type' => 'title', 'desc' => esc_html__( 'The compliance scanner checks your shop every week, the sale planner checks discounts before they start, and the UVP mode labels manufacturer price comparisons.', 'strikewise' ) . ' ' . esc_html__( 'See plans', 'strikewise' ) . '', 'id' => 'strikewise_premium_teaser', ); $fields[] = array( 'type' => 'sectionend', 'id' => 'strikewise_premium_teaser', ); } $fields[] = array( 'title' => __( 'Data', 'strikewise' ), 'type' => 'title', 'id' => 'strikewise_data', ); $fields[] = array( 'title' => __( 'Delete data on uninstall', 'strikewise' ), 'desc' => __( 'Remove the price history and all settings when the plugin is deleted. Leave this off if you may need the history as evidence.', 'strikewise' ), 'id' => 'strikewise_delete_data', 'type' => 'checkbox', 'default' => 'no', ); $fields[] = array( 'type' => 'sectionend', 'id' => 'strikewise_data', ); return $fields; } public function render_intro(): void { echo '
'; echo '

Strikewise
' . esc_html__( 'Key figures, compliance report and import are on the overview page.', 'strikewise' ); echo ' ' . esc_html__( 'Open overview', 'strikewise' ) . ' →

'; } /** * @param string[] $links * @return string[] */ public function action_links( $links ) { $url = admin_url( 'admin.php?page=wc-settings&tab=products§ion=' . self::SECTION ); array_unshift( $links, '' . esc_html__( 'Settings', 'strikewise' ) . '' ); return $links; } public static function mode(): string { $mode = get_option( 'strikewise_mode', ReferenceCalculator::MODE_REDUCTION ); return ReferenceCalculator::MODE_ALWAYS === $mode ? ReferenceCalculator::MODE_ALWAYS : ReferenceCalculator::MODE_REDUCTION; } /** * The legal minimum is 30 days. Filterable for markets with longer periods. */ public static function window_days(): int { return max( 30, (int) apply_filters( 'strikewise_window_days', 30 ) ); } /** * How long closed history rows are kept. Rows a running reduction needs are always kept. */ public static function retention_days(): int { // Evidence for disputes: keep more than a year (claims under § 11 UWG become time-barred after 6 months from knowledge). return max( self::window_days() + 1, (int) apply_filters( 'strikewise_retention_days', 400 ) ); } public static function show_single(): bool { return 'yes' === get_option( 'strikewise_show_single', 'yes' ); } public static function show_loop(): bool { return 'yes' === get_option( 'strikewise_show_loop', 'yes' ); } public static function text(): string { $text = trim( (string) get_option( 'strikewise_text', '' ) ); return '' === $text ? self::default_text() : $text; } public static function fallback(): string { return 'text' === get_option( 'strikewise_fallback', 'hide' ) ? 'text' : 'hide'; } public static function fallback_text(): string { $text = trim( (string) get_option( 'strikewise_fallback_text', '' ) ); return '' === $text ? self::default_fallback_text() : $text; } public static function default_text(): string { if ( ReferenceCalculator::MODE_ALWAYS === self::mode() ) { /* translators: {price} is a placeholder, keep it as is. */ return __( 'Lowest price in the last 30 days: {price}', 'strikewise' ); } // During a reduction "the last 30 days" would include the sale itself. /* translators: {price} is a placeholder, keep it as is. */ return __( 'Lowest price of the 30 days before the reduction: {price}', 'strikewise' ); } public static function default_fallback_text(): string { return __( 'No earlier price available for the last 30 days.', 'strikewise' ); } }