*/ public array $extensions = array(); public string $status = 'active'; public function __construct() { $this->restrictions = new Restrictions(); } /** * @param array|object $row Database row. */ public static function from_row( $row ): self { $row = (array) $row; $campaign = new self(); $campaign->id = (int) ( $row['id'] ?? 0 ); $campaign->slug = (string) ( $row['slug'] ?? '' ); $campaign->name = (string) ( $row['name'] ?? '' ); $campaign->category_id = (int) ( $row['category_id'] ?? 0 ); $campaign->type = self::allowed( $row['type'] ?? '', self::TYPES ); $campaign->discount_type = self::allowed( $row['discount_type'] ?? '', self::DISCOUNT_TYPES ); $campaign->amount = (float) ( $row['amount'] ?? 0 ); $campaign->starts_on = (string) ( $row['starts_on'] ?? '' ); $campaign->expires_on = (string) ( $row['expires_on'] ?? '' ); $campaign->valid_days = (int) ( $row['valid_days'] ?? 0 ); $campaign->code_prefix = (string) ( $row['code_prefix'] ?? '' ); $campaign->max_codes = (int) ( $row['max_codes'] ?? 0 ); $campaign->uses_per_code = max( 1, (int) ( $row['uses_per_code'] ?? 1 ) ); $campaign->max_redemptions = (int) ( $row['max_redemptions'] ?? 0 ); $campaign->max_per_email = (int) ( $row['max_per_email'] ?? 0 ); $campaign->restrictions = Restrictions::from_array( $row['restrictions'] ?? array() ); $campaign->email_restricted = ! empty( $row['email_restricted'] ); $campaign->extensions = self::json_object( $row['extensions'] ?? '' ); $campaign->status = self::allowed( $row['status'] ?? '', self::STATUSES ); return $campaign; } public function is_active(): bool { return 'active' === $this->status; } public function is_shared(): bool { return self::TYPE_SHARED === $this->type; } /** * How many orders may use one code of this campaign, or 0 for no limit. */ public function uses_limit(): int { return $this->is_shared() ? $this->max_redemptions : $this->uses_per_code; } /** * Whether the campaign's first valid day has come, in the site's time zone. * * @param int $now Unix timestamp. */ public function has_started( int $now ): bool { if ( '' === $this->starts_on ) { return true; } $today = ( new \DateTimeImmutable( '@' . $now ) )->setTimezone( wp_timezone() )->format( 'Y-m-d' ); return $today >= $this->starts_on; } /** * An add-on's stored settings. * * @param string $key Add-on key. */ public function extension( string $key ): array { return isset( $this->extensions[ $key ] ) && is_array( $this->extensions[ $key ] ) ? $this->extensions[ $key ] : array(); } /** * @param mixed $value JSON list, array or comma-separated string. * @return int[] */ public static function id_list( $value ): array { if ( is_string( $value ) && '' !== $value && '[' === $value[0] ) { $value = json_decode( $value, true ); } elseif ( is_string( $value ) ) { $value = explode( ',', $value ); } return array_values( array_unique( array_filter( array_map( 'absint', (array) $value ) ) ) ); } /** * @param mixed $value JSON object or array. */ private static function json_object( $value ): array { if ( is_string( $value ) && '' !== $value ) { $value = json_decode( $value, true ); } return is_array( $value ) ? $value : array(); } /** * @param mixed $value Stored value. * @param string[] $allowed Allowed values; the first is the default. */ private static function allowed( $value, array $allowed ): string { return in_array( $value, $allowed, true ) ? (string) $value : $allowed[0]; } }