settings = $settings;
$this->history = $history;
}
/**
* Registers hooks.
*
* @return void
*/
public function register(): void {
add_action( 'init', array( $this, 'add_rewrite_rule' ) );
add_filter( 'query_vars', array( $this, 'add_query_var' ) );
add_action( 'parse_request', array( $this, 'maybe_serve' ) );
add_action( 'wp_head', array( $this, 'print_meta' ), 1 );
add_filter( 'wp_headers', array( $this, 'add_headers' ) );
}
/**
* Whether the reservation is switched on.
*
* @return bool True when rights are reserved.
*/
public function is_enabled(): bool {
return ! aiblackout_is_disabled() && (bool) $this->settings->get_declaration( 'tdm_reservation', false );
}
/**
* Returns the configured TDM policy URL.
*
* @return string Policy URL, or an empty string when none is set.
*/
public function get_policy_url(): string {
$url = (string) $this->settings->get_declaration( 'tdm_policy_url', '' );
return '' !== $url ? esc_url_raw( $url ) : '';
}
/**
* Adds the rewrite rule for the well-known file.
*
* @return void
*/
public function add_rewrite_rule(): void {
add_rewrite_rule(
'^\.well-known/tdmrep\.json$',
'index.php?' . self::QUERY_VAR . '=1',
'top'
);
}
/**
* Registers the query variable.
*
* @param array $vars Registered query variables.
* @return array Filtered query variables.
*/
public function add_query_var( $vars ): array {
$vars = is_array( $vars ) ? $vars : array();
$vars[] = self::QUERY_VAR;
return $vars;
}
/**
* Serves the well-known file when it is requested.
*
* @param \WP $wp Current WordPress environment.
* @return void
*/
public function maybe_serve( $wp ): void {
$requested = isset( $wp->query_vars[ self::QUERY_VAR ] );
if ( ! $requested && ! $this->is_tdmrep_request() ) {
return;
}
if ( ! $this->is_enabled() ) {
status_header( 404 );
nocache_headers();
exit;
}
status_header( 200 );
header( 'Content-Type: application/json; charset=utf-8' );
header( 'X-Robots-Tag: noindex' );
echo wp_json_encode( $this->build_document(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );
exit;
}
/**
* Whether the current request is for the well-known file.
*
* @return bool True when the path matches.
*/
private function is_tdmrep_request(): bool {
if ( empty( $_SERVER['REQUEST_URI'] ) ) {
return false;
}
$uri = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) );
$path = (string) wp_parse_url( $uri, PHP_URL_PATH );
if ( '' === $path ) {
return false;
}
$expected = (string) wp_parse_url( $this->get_url(), PHP_URL_PATH );
return '' !== $expected && untrailingslashit( $path ) === untrailingslashit( $expected );
}
/**
* Returns the URL the well-known file is published at.
*
* @return string Absolute URL.
*/
public function get_url(): string {
return home_url( '/' . self::PATH );
}
/**
* Builds the tdmrep.json document.
*
* @return array The document, ready to encode.
*/
public function build_document(): array {
$entry = array(
'location' => '/',
'tdm-reservation' => 1,
);
$policy = $this->get_policy_url();
if ( '' !== $policy ) {
$entry['tdm-policy'] = $policy;
}
return array( $entry );
}
/**
* Returns the document as it would be served.
*
* @return string JSON, or an empty string when the reservation is off.
*/
public function preview(): string {
if ( ! $this->is_enabled() ) {
return '';
}
return (string) wp_json_encode( $this->build_document(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );
}
/**
* Prints the meta tags on front-end pages.
*
* @return void
*/
public function print_meta(): void {
if ( ! $this->is_enabled() || is_admin() ) {
return;
}
echo '' . "\n";
$policy = $this->get_policy_url();
if ( '' !== $policy ) {
printf( '' . "\n", esc_url( $policy ) );
}
}
/**
* Adds the HTTP headers to front-end responses.
*
* @param array $headers Response headers.
* @return array Filtered headers.
*/
public function add_headers( $headers ): array {
$headers = is_array( $headers ) ? $headers : array();
if ( ! $this->is_enabled() || is_admin() ) {
return $headers;
}
$headers['tdm-reservation'] = '1';
$policy = $this->get_policy_url();
if ( '' !== $policy ) {
$headers['tdm-policy'] = $policy;
}
return $headers;
}
/**
* Records the current declaration in the history log.
*
* @return void
*/
public function record(): void {
if ( ! $this->is_enabled() ) {
$this->history->record(
self::TYPE,
__( 'Text and data mining reservation withdrawn.', 'ai-blackout' ),
array( 'tdm-reservation' => 0 )
);
return;
}
$this->history->record(
self::TYPE,
__( 'Reserved text and data mining rights site-wide under EU Directive 2019/790 Article 4.', 'ai-blackout' ),
$this->build_document()
);
}
}