true, 'uri' => '', ); } if ( preg_match( '~^at://([^/]+)/app\.bsky\.feed\.post/([^/?#]*)\z~', $value, $m ) || preg_match( '~^https://[A-Za-z0-9.-]+(?::[0-9]+)?/profile/([^/?#]+)/post/([^/?#]+)/?(?:[?#].*)?\z~s', $value, $m ) ) { list( , $authority, $rkey ) = $m; if ( preg_match( '/^' . self::RKEY . '\z/', $rkey ) ) { if ( preg_match( '/^(?:' . self::DID . ')\z/', $authority ) ) { return array( 'ok' => true, 'uri' => 'at://' . $authority . '/' . self::COLLECTION . '/' . $rkey, ); } if ( 0 !== strpos( $authority, 'did:' ) && preg_match( '/^' . self::HANDLE . '\z/', $authority ) ) { return array( 'ok' => false, 'error' => 'handle', 'handle' => strtolower( $authority ), 'rkey' => $rkey, ); } } } return array( 'ok' => false, 'error' => 'format', ); } /** * Whether a stored value is a canonical, non-empty thread URI. * * @param mixed $value Stored value. * @return bool */ public static function is_canonical( $value ) { if ( ! is_string( $value ) || '' === $value ) { return false; } $result = self::normalize( $value ); return $result['ok'] && $result['uri'] === $value; } }