*/ public static function sources(): array { return array( Context::SOURCE_ORDER => __( 'Order', 'stock-alibi' ), Context::SOURCE_ORDER_RESTORE => __( 'Order restored', 'stock-alibi' ), Context::SOURCE_REFUND_RESTOCK => __( 'Refund restock', 'stock-alibi' ), Context::SOURCE_ORDER_EDIT => __( 'Order edit', 'stock-alibi' ), Context::SOURCE_ADMIN => __( 'Product screen', 'stock-alibi' ), Context::SOURCE_QUICK_EDIT => __( 'Quick Edit', 'stock-alibi' ), Context::SOURCE_BULK_EDIT => __( 'Bulk Edit', 'stock-alibi' ), Context::SOURCE_REST => __( 'REST API', 'stock-alibi' ), Context::SOURCE_IMPORT => __( 'CSV import', 'stock-alibi' ), Context::SOURCE_CLI => __( 'WP-CLI', 'stock-alibi' ), Context::SOURCE_CRON => __( 'WP-Cron', 'stock-alibi' ), Context::SOURCE_SCHEDULER => __( 'Scheduled action', 'stock-alibi' ), Context::SOURCE_SCHEDULED_SALE => __( 'Scheduled sale', 'stock-alibi' ), Context::SOURCE_PLUGIN => __( 'Plugin or theme', 'stock-alibi' ), Context::SOURCE_META_DIRECT => __( 'Direct meta write', 'stock-alibi' ), Context::SOURCE_EXTERNAL => __( 'Direct database change', 'stock-alibi' ), Context::SOURCE_UNKNOWN => __( 'Unknown', 'stock-alibi' ), ); } /** * Name of a field. * * @param string $field Field key. */ public static function field( string $field ): string { $labels = self::fields(); return $labels[ $field ] ?? $field; } /** * Names of the recorded fields. * * @return array */ public static function fields(): array { return array( Fields::STOCK_QUANTITY => __( 'Stock', 'stock-alibi' ), Fields::STOCK_STATUS => __( 'Stock status', 'stock-alibi' ), Fields::MANAGE_STOCK => __( 'Manage stock', 'stock-alibi' ), Fields::BACKORDERS => __( 'Backorders', 'stock-alibi' ), Fields::REGULAR_PRICE => __( 'Regular price', 'stock-alibi' ), Fields::SALE_PRICE => __( 'Sale price', 'stock-alibi' ), Fields::DATE_ON_SALE_FROM => __( 'Sale starts', 'stock-alibi' ), Fields::DATE_ON_SALE_TO => __( 'Sale ends', 'stock-alibi' ), Fields::PRICE => __( 'Active price', 'stock-alibi' ), ); } /** * Name of an anomaly type. * * @param string $type Type key. */ public static function anomaly( string $type ): string { $labels = self::anomalies(); return $labels[ $type ] ?? $type; } /** * Names of the anomaly types. * * @return array */ public static function anomalies(): array { return array( Anomalies::TYPE_NEGATIVE_STOCK => __( 'Negative stock', 'stock-alibi' ), Anomalies::TYPE_DOUBLE_REDUCTION => __( 'Double reduction', 'stock-alibi' ), Anomalies::TYPE_SYNC_OVERWRITE => __( 'Sale overwritten by a sync', 'stock-alibi' ), Anomalies::TYPE_PRICE_OUTSIDE => __( 'Price changed outside WooCommerce', 'stock-alibi' ), ); } /** * A stored value, for display. NULL ("no value") is shown as a dash. * * @param string $field Field key. * @param string|null $value Stored value. */ public static function value( string $field, ?string $value ): string { if ( null === $value || '' === $value ) { return '—'; } switch ( $field ) { case Fields::STOCK_STATUS: $statuses = function_exists( 'wc_get_product_stock_status_options' ) ? wc_get_product_stock_status_options() : array(); return isset( $statuses[ $value ] ) ? (string) $statuses[ $value ] : $value; case Fields::MANAGE_STOCK: if ( 'parent' === $value ) { return __( 'From the parent product', 'stock-alibi' ); } return 'yes' === $value ? __( 'Yes', 'stock-alibi' ) : __( 'No', 'stock-alibi' ); case Fields::BACKORDERS: $options = function_exists( 'wc_get_product_backorder_options' ) ? wc_get_product_backorder_options() : array(); return isset( $options[ $value ] ) ? (string) $options[ $value ] : $value; case Fields::DATE_ON_SALE_FROM: case Fields::DATE_ON_SALE_TO: return self::time( $value ); default: return $value; }//end switch } /** * A UTC `Y-m-d H:i:s` time in the site's time zone and formats. * * @param string $utc UTC time. * @param string $format PHP date format. Default: the site's date and time formats. */ public static function time( string $utc, string $format = '' ): string { $timestamp = strtotime( $utc . ' UTC' ); if ( false === $timestamp ) { return $utc; } if ( '' === $format ) { $format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); } return (string) wp_date( $format, $timestamp ); } /** * Name of a user, or an empty string. * * @param int|null $user_id User ID. */ public static function user( ?int $user_id ): string { static $names = array(); if ( ! $user_id ) { return ''; } if ( ! isset( $names[ $user_id ] ) ) { $user = get_userdata( $user_id ); /* translators: %d: user ID of a user that no longer exists. */ $names[ $user_id ] = $user ? (string) $user->display_name : sprintf( __( 'User #%d', 'stock-alibi' ), $user_id ); } return $names[ $user_id ]; } /** * Name of a product or variation, with its SKU, or a placeholder for a * product that no longer exists. * * @param int $product_id Product ID. * @param string $sku SKU recorded with the event. */ public static function product( int $product_id, string $sku = '' ): string { $product = function_exists( 'wc_get_product' ) ? wc_get_product( $product_id ) : null; /* translators: %d: product ID. */ $name = $product ? wp_strip_all_tags( $product->get_formatted_name() ) : sprintf( __( 'Deleted product #%d', 'stock-alibi' ), $product_id ); if ( ! $product && '' !== $sku ) { $name .= ' (' . $sku . ')'; } return $name; } }