', 'RewriteEngine On', 'RewriteCond %{HTTP_HOST} ^' . $apex . '$ [NC]', 'RewriteRule ^ https://www.' . $website . '%{REQUEST_URI} [R=301,L]', 'RewriteCond %{HTTP:X-Rabbitproof-Origin} !^' . $key . '$', 'RewriteRule ^ - [F]', '', '# END ' . self::MARKER, ); } private static function without( $text ) { return (string) preg_replace( '/^# BEGIN ' . preg_quote( self::MARKER, '/' ) . '.*?^# END ' . preg_quote( self::MARKER, '/' ) . "\r?\n(\r?\n)?/ms", '', $text ); } public static function write( array $lines ) { $f = self::file(); $text = file_exists( $f ) ? (string) file_get_contents( $f ) : ''; return false !== file_put_contents( $f, implode( "\n", $lines ) . "\n\n" . self::without( $text ), LOCK_EX ); } public static function remove() { $f = self::file(); if ( ! self::on() ) { return true; } return false !== file_put_contents( $f, self::without( (string) file_get_contents( $f ) ), LOCK_EX ); } private static function key_in_file() { $f = self::file(); return is_readable( $f ) && preg_match( '/X-Rabbitproof-Origin\} !\^([0-9a-f]{24})\$/', (string) file_get_contents( $f ), $m ) ? $m[1] : ''; } private static function fresh() { $o = Rabbitproof_Options::all(); if ( empty( $o['site']['id'] ) ) { return null; } $id = rawurlencode( $o['site']['id'] ); $s = Rabbitproof_Api::call( 'GET', '/v1/sites/' . $id, null, 10 ); if ( is_wp_error( $s ) || 200 !== $s['_status'] || empty( $s['site'] ) ) { return null; } $c = Rabbitproof_Api::call( 'GET', '/v1/sites/' . $id . '/connection', null, 20 ); return array( 'site' => $s['site'], 'conn' => ! is_wp_error( $c ) && 200 === $c['_status'] && isset( $c['connection'] ) && is_array( $c['connection'] ) ? $c['connection'] : array() ); } public static function staying( array $site ) { $pending = isset( $site['pending'] ) && is_array( $site['pending'] ) && isset( $site['pending']['tier'] ) && 'advanced' !== $site['pending']['tier']; return isset( $site['tier'] ) && 'advanced' === $site['tier'] && empty( $site['leaving'] ) && ! $pending; } public static function lock() { if ( ! self::can() ) { return 'nofile'; } $f = self::fresh(); if ( null === $f ) { return 'down'; } if ( ! self::staying( $f['site'] ) ) { return 'leaving'; } $c = $f['conn']; $key = isset( $c['key'] ) && is_string( $c['key'] ) && preg_match( '/^[0-9a-f]{24}$/', $c['key'] ) ? $c['key'] : ''; if ( '' === $key || empty( $c['ready'] ) || ! isset( $c['through'] ) || 'ok' !== $c['through'] || empty( $f['site']['website'] ) ) { return 'notlive'; } if ( ! self::write( self::lines( (string) $f['site']['website'], $key ) ) ) { return 'nofile'; } $after = self::fresh(); $ac = null === $after ? array() : $after['conn']; if ( ! isset( $ac['through'] ) || 'ok' !== $ac['through'] ) { self::remove(); self::tell( true ); return 'broke'; } if ( empty( $ac['locked'] ) ) { self::remove(); self::tell( true ); return 'nolock'; } if ( ! wp_next_scheduled( self::HOOK ) ) { wp_schedule_event( time() + HOUR_IN_SECONDS, 'hourly', self::HOOK ); } self::tell( true ); return 'locked'; } public static function unlock() { $done = self::remove(); wp_clear_scheduled_hook( self::HOOK ); self::tell( true ); return $done; } public static function check() { if ( ! self::on() ) { wp_clear_scheduled_hook( self::HOOK ); return; } $f = self::fresh(); if ( null === $f ) { if ( get_option( 'rabbitproof_gone' ) ) { self::unlock(); } return; } if ( ! self::staying( $f['site'] ) ) { self::unlock(); return; } $key = isset( $f['conn']['key'] ) && is_string( $f['conn']['key'] ) && preg_match( '/^[0-9a-f]{24}$/', $f['conn']['key'] ) ? $f['conn']['key'] : ''; if ( '' !== $key && $key !== self::key_in_file() && ! empty( $f['site']['website'] ) ) { self::write( self::lines( (string) $f['site']['website'], $key ) ); } self::tell( true ); } public static function tell( $now = false ) { $o = Rabbitproof_Options::all(); if ( empty( $o['site']['id'] ) || ! isset( $o['site']['tier'] ) || 'advanced' !== $o['site']['tier'] || ! Rabbitproof_Options::connected() ) { return; } if ( true !== $now && get_transient( self::SAID ) ) { return; } set_transient( self::SAID, 1, HOUR_IN_SECONDS ); Rabbitproof_Api::call( 'POST', '/v1/sites/' . rawurlencode( $o['site']['id'] ) . '/plugin-lock', array( 'can' => self::can(), 'on' => self::on() ), 5 ); } public static function stop() { self::remove(); wp_clear_scheduled_hook( self::HOOK ); delete_transient( self::SAID ); } }