repository->each() as $rule ) { if ( '' !== $group && $rule->group_name !== $group ) { continue; } $rules[] = $this->resolved( $rule ); } $stamp = gmdate( 'Y-m-d' ); $host = sanitize_title( (string) wp_parse_url( home_url(), PHP_URL_HOST ) ); // A group export names its group, so three exports from one afternoon can be told // apart in a downloads folder. if ( '' !== $group && '' !== sanitize_title( $group ) ) { $host .= '-' . sanitize_title( $group ); } return match ( $format ) { 'json' => [ 'filename' => "redirects-{$host}-{$stamp}.json", 'mime' => 'application/json', 'content' => $this->json( $rules ), 'count' => count( $rules ), ], 'apache' => [ 'filename' => "redirects-{$host}-{$stamp}.htaccess.txt", 'mime' => 'text/plain', 'content' => ServerRules::apache_out( $rules ), 'count' => count( $rules ), ], 'nginx' => [ 'filename' => "redirects-{$host}-{$stamp}.nginx.conf", 'mime' => 'text/plain', 'content' => ServerRules::nginx_out( $rules ), 'count' => count( $rules ), ], default => [ 'filename' => "redirects-{$host}-{$stamp}.csv", 'mime' => 'text/csv', 'content' => $this->csv( $rules ), 'count' => count( $rules ), ], }; } /** * A copy of the rule with a linked destination written out as an address on this * site — relative, so the export works on staging and live alike. */ private function resolved( Rule $rule ): Rule { $copy = clone $rule; if ( 'post' === $rule->target_type ) { $copy->target = Engine::post_url( $rule->target_id ) ?? $rule->target; } elseif ( 'term' === $rule->target_type ) { $link = get_term_link( $rule->target_id ); $copy->target = is_string( $link ) ? $link : $rule->target; } $address = Address::parse( $copy->target ); if ( '' !== $copy->target && $address->has_host() && $address->is_local() ) { $copy->target = $address->relative(); } $copy->target_type = 'url'; $copy->target_id = 0; return $copy; } /** * @param list $rules */ private function csv( array $rules ): string { $rows = array_map( static fn( Rule $r ): array => [ 'source' => $r->source, 'target' => $r->target, 'code' => $r->status_code, 'match' => $r->match_type, 'enabled' => $r->enabled, 'group' => $r->group_name, 'note' => $r->note, 'hits' => $r->hits, 'case_sensitive' => $r->case_sensitive, 'pass_query' => $r->pass_query, 'conditions' => [] === $r->conditions ? '' : (string) wp_json_encode( $r->conditions ), ], $rules ); return Csv::write( $rows ); } /** * @param list $rules */ private function json( array $rules ): string { $items = array_map( static function ( Rule $r ): array { $row = get_object_vars( $r ); unset( $row['id'], $row['target_type'], $row['target_id'], $row['post_id'], $row['last_hit'], $row['created_at'], $row['updated_at'], $row['origin'] ); return $row; }, $rules ); return (string) wp_json_encode( [ 'generator' => 'CodeBold Redirects', 'version' => \CodeBold\Redirect\VERSION, 'site' => home_url( '/' ), 'exported' => gmdate( 'c' ), 'redirects' => $items, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); } }