2026-04-18 20:50:31 +00:00
< ? php
if ( ! defined ( 'ABSPATH' )) {
exit ;
}
class Ansico_Plugins_Client {
private $settings ;
public function __construct ( $settings = array ()) {
$this -> settings = empty ( $settings ) ? Ansico_Plugins :: get_settings () : $settings ;
}
private function base_url () {
return trailingslashit (( string ) $this -> settings [ 'forgejo_base_url' ]);
}
private function owner_name () {
return trim (( string ) $this -> settings [ 'forgejo_owner' ]);
}
private function owner_type () {
$owner_type = isset ( $this -> settings [ 'owner_type' ]) ? strtolower (( string ) $this -> settings [ 'owner_type' ]) : 'user' ;
return in_array ( $owner_type , array ( 'org' , 'organisation' , 'organization' ), true ) ? 'org' : 'user' ;
}
private function cache_key ( $method , $url ) {
return 'ansico_plugins_' . md5 ( strtoupper (( string ) $method ) . '|' . $url . '|' . wp_json_encode ( array (
'token' => ! empty ( $this -> settings [ 'access_token' ]) ? 1 : 0 ,
'ssl' => ! empty ( $this -> settings [ 'verify_ssl' ]) ? 1 : 0 ,
)));
}
private function normalize_http_response ( $response ) {
return array (
'code' => ( int ) wp_remote_retrieve_response_code ( $response ),
'message' => ( string ) wp_remote_retrieve_response_message ( $response ),
'body' => ( string ) wp_remote_retrieve_body ( $response ),
'headers' => array (),
);
}
private function parse_json_response ( $response , $error_code , $error_message ) {
if ( is_wp_error ( $response )) {
return $response ;
}
$body = isset ( $response [ 'body' ]) ? ( string ) $response [ 'body' ] : '' ;
$data = json_decode ( $body , true );
if ( JSON_ERROR_NONE !== json_last_error ()) {
return new WP_Error ( $error_code , $error_message . ' JSON error: ' . json_last_error_msg ());
}
return $data ;
}
private function get_owner_endpoint () {
$base = $this -> base_url ();
$owner = rawurlencode ( $this -> owner_name ());
if ( 'org' === $this -> owner_type ()) {
return sprintf ( '%sapi/v1/orgs/%s/repos?limit=100' , $base , $owner );
}
return sprintf ( '%sapi/v1/users/%s/repos?limit=100' , $base , $owner );
}
public function test_connection () {
$base = $this -> base_url ();
if ( '' === $base ) {
return new WP_Error ( 'missing_base_url' , __ ( 'Forgejo base URL mangler.' , 'ansico-plugins' ));
}
$response = $this -> request ( 'GET' , $base . 'api/v1/version' , false );
if ( is_wp_error ( $response )) {
return $response ;
}
if ( $response [ 'code' ] < 200 || $response [ 'code' ] >= 300 ) {
return new WP_Error ( 'bad_response' , sprintf ( __ ( 'Forgejo svarede med HTTP %d.' , 'ansico-plugins' ), ( int ) $response [ 'code' ]));
}
$body = $this -> parse_json_response ( $response , 'invalid_version' , __ ( 'Kunne ikke læse version fra Forgejo.' , 'ansico-plugins' ));
if ( is_wp_error ( $body )) {
return $body ;
}
return array (
'version' => isset ( $body [ 'version' ]) ? ( string ) $body [ 'version' ] : __ ( 'Ukendt' , 'ansico-plugins' ),
);
}
public function get_repositories_without_filter () {
if ( '' === $this -> base_url () || '' === $this -> owner_name ()) {
return new WP_Error ( 'missing_settings' , __ ( 'Du skal udfylde Forgejo URL og owner/org først.' , 'ansico-plugins' ));
}
$response = $this -> request ( 'GET' , $this -> get_owner_endpoint ());
if ( is_wp_error ( $response )) {
return $response ;
}
if ( $response [ 'code' ] < 200 || $response [ 'code' ] >= 300 ) {
return new WP_Error ( 'repos_http_error' , sprintf ( __ ( 'Repository-endpoint svarede med HTTP %d.' , 'ansico-plugins' ), ( int ) $response [ 'code' ]));
}
$repos = $this -> parse_json_response ( $response , 'invalid_repos' , __ ( 'Kunne ikke læse repositories fra Forgejo.' , 'ansico-plugins' ));
if ( is_wp_error ( $repos )) {
return $repos ;
}
return is_array ( $repos ) ? $repos : array ();
}
public function get_repositories () {
$all_repos = $this -> get_repositories_without_filter ();
if ( is_wp_error ( $all_repos )) {
return $all_repos ;
}
$topic_filter = strtolower ( trim (( string ) $this -> settings [ 'topic_filter' ]));
$filtered = array ();
foreach ( $all_repos as $repo ) {
if ( empty ( $repo [ 'name' ]) || empty ( $repo [ 'owner' ][ 'login' ])) {
continue ;
}
$topics = $this -> get_repository_topics_safe ( $repo );
$repo [ 'topics' ] = $topics ;
$normalized_topics = array_map ( 'strtolower' , array_map ( 'strval' , ( array ) $topics ));
if ( '' === $topic_filter || in_array ( $topic_filter , $normalized_topics , true )) {
$filtered [] = $repo ;
}
}
return $filtered ;
}
public function get_repositories_debug () {
$all_repos = $this -> get_repositories_without_filter ();
if ( is_wp_error ( $all_repos )) {
return $all_repos ;
}
$topic_filter = strtolower ( trim (( string ) $this -> settings [ 'topic_filter' ]));
$rows = array ();
foreach ( $all_repos as $repo ) {
$owner = ! empty ( $repo [ 'owner' ][ 'login' ]) ? ( string ) $repo [ 'owner' ][ 'login' ] : '' ;
$name = ! empty ( $repo [ 'name' ]) ? ( string ) $repo [ 'name' ] : '' ;
$topics_result = ( $owner !== '' && $name !== '' ) ? $this -> get_repository_topics ( $owner , $name ) : new WP_Error ( 'missing_repo_data' , __ ( 'Repo mangler owner eller navn.' , 'ansico-plugins' ));
$topics = is_wp_error ( $topics_result ) ? array () : ( array ) $topics_result ;
$release = ( $owner !== '' && $name !== '' ) ? $this -> get_latest_release ( $owner , $name ) : new WP_Error ( 'missing_repo_data' , __ ( 'Repo mangler owner eller navn.' , 'ansico-plugins' ));
$rows [] = array (
'name' => $name ,
'full_name' => ! empty ( $repo [ 'full_name' ]) ? ( string ) $repo [ 'full_name' ] : $name ,
'topics' => $topics ,
'matches_filter' => ( '' === $topic_filter || in_array ( $topic_filter , array_map ( 'strtolower' , array_map ( 'strval' , $topics )), true )),
'release' => is_wp_error ( $release ) ? '' : ( ! empty ( $release [ 'tag_name' ]) ? ( string ) $release [ 'tag_name' ] : ( ! empty ( $release [ 'name' ]) ? ( string ) $release [ 'name' ] : '' )),
'topics_error' => is_wp_error ( $topics_result ) ? $topics_result -> get_error_message () : '' ,
'release_error' => is_wp_error ( $release ) ? $release -> get_error_message () : '' ,
);
}
return $rows ;
}
private function get_repository_topics_safe ( $repo ) {
if ( ! empty ( $repo [ 'topics' ]) && is_array ( $repo [ 'topics' ])) {
return $repo [ 'topics' ];
}
$owner = ! empty ( $repo [ 'owner' ][ 'login' ]) ? ( string ) $repo [ 'owner' ][ 'login' ] : '' ;
$name = ! empty ( $repo [ 'name' ]) ? ( string ) $repo [ 'name' ] : '' ;
if ( '' === $owner || '' === $name ) {
return array ();
}
$topics = $this -> get_repository_topics ( $owner , $name );
if ( ! is_wp_error ( $topics )) {
return ( array ) $topics ;
}
$repo_details = $this -> get_repository ( $owner , $name );
if ( ! is_wp_error ( $repo_details ) && ! empty ( $repo_details [ 'topics' ]) && is_array ( $repo_details [ 'topics' ])) {
return $repo_details [ 'topics' ];
}
return array ();
}
public function get_repository ( $owner , $repo_name ) {
$endpoint = sprintf ( '%sapi/v1/repos/%s/%s' , $this -> base_url (), rawurlencode ( $owner ), rawurlencode ( $repo_name ));
$response = $this -> request ( 'GET' , $endpoint );
if ( is_wp_error ( $response )) {
return $response ;
}
if ( $response [ 'code' ] < 200 || $response [ 'code' ] >= 300 ) {
return new WP_Error ( 'repo_http_error' , sprintf ( __ ( 'Repository-endpoint svarede med HTTP %d.' , 'ansico-plugins' ), ( int ) $response [ 'code' ]));
}
$repo = $this -> parse_json_response ( $response , 'invalid_repo' , __ ( 'Kunne ikke læse repository-data.' , 'ansico-plugins' ));
return is_wp_error ( $repo ) ? $repo : ( is_array ( $repo ) ? $repo : array ());
}
public function get_repository_topics ( $owner , $repo_name ) {
$endpoint = sprintf ( '%sapi/v1/repos/%s/%s/topics' , $this -> base_url (), rawurlencode ( $owner ), rawurlencode ( $repo_name ));
$response = $this -> request ( 'GET' , $endpoint );
if ( is_wp_error ( $response )) {
return $response ;
}
if ( $response [ 'code' ] < 200 || $response [ 'code' ] >= 300 ) {
return new WP_Error ( 'topics_http_error' , sprintf ( __ ( 'Topics-endpoint svarede med HTTP %d.' , 'ansico-plugins' ), ( int ) $response [ 'code' ]));
}
$body = $this -> parse_json_response ( $response , 'invalid_topics' , __ ( 'Kunne ikke læse repository-topics.' , 'ansico-plugins' ));
if ( is_wp_error ( $body )) {
return $body ;
}
if ( isset ( $body [ 'topics' ]) && is_array ( $body [ 'topics' ])) {
return $body [ 'topics' ];
}
return is_array ( $body ) ? $body : array ();
}
public function get_latest_release ( $owner , $repo_name ) {
$endpoint = sprintf ( '%sapi/v1/repos/%s/%s/releases/latest' , $this -> base_url (), rawurlencode ( $owner ), rawurlencode ( $repo_name ));
$response = $this -> request ( 'GET' , $endpoint );
if ( is_wp_error ( $response )) {
return $response ;
}
if ( 404 === ( int ) $response [ 'code' ]) {
return new WP_Error ( 'release_not_found' , __ ( 'Ingen release fundet.' , 'ansico-plugins' ));
}
if ( $response [ 'code' ] < 200 || $response [ 'code' ] >= 300 ) {
return new WP_Error ( 'release_http_error' , sprintf ( __ ( 'Release-endpoint svarede med HTTP %d.' , 'ansico-plugins' ), ( int ) $response [ 'code' ]));
}
$release = $this -> parse_json_response ( $response , 'invalid_release' , __ ( 'Kunne ikke læse release-data.' , 'ansico-plugins' ));
return is_wp_error ( $release ) ? $release : ( is_array ( $release ) ? $release : array ());
}
public function find_zip_asset ( $release ) {
if ( empty ( $release [ 'assets' ]) || ! is_array ( $release [ 'assets' ])) {
return null ;
}
foreach ( $release [ 'assets' ] as $asset ) {
$name = isset ( $asset [ 'name' ]) ? ( string ) $asset [ 'name' ] : '' ;
if ( preg_match ( '/\.zip$/i' , $name )) {
return $asset ;
}
}
if ( ! empty ( $release [ 'zipball_url' ])) {
return array (
'name' => basename (( string ) $release [ 'zipball_url' ]),
'browser_download_url' => ( string ) $release [ 'zipball_url' ],
);
}
return null ;
}
public function get_repository_contents ( $owner , $repo_name , $path = '' , $ref = '' ) {
$endpoint = sprintf ( '%sapi/v1/repos/%s/%s/contents' , $this -> base_url (), rawurlencode ( $owner ), rawurlencode ( $repo_name ));
$path = ltrim (( string ) $path , '/' );
if ( '' !== $path ) {
$endpoint .= '/' . str_replace ( '%2F' , '/' , rawurlencode ( $path ));
}
$query = array ();
if ( '' !== ( string ) $ref ) {
$query [ 'ref' ] = ( string ) $ref ;
}
if ( ! empty ( $query )) {
$endpoint .= '?' . http_build_query ( $query , '' , '&' );
}
$response = $this -> request ( 'GET' , $endpoint );
if ( is_wp_error ( $response )) {
return $response ;
}
if ( 404 === ( int ) $response [ 'code' ]) {
return new WP_Error ( 'contents_not_found' , __ ( 'Fil eller mappe blev ikke fundet i repository.' , 'ansico-plugins' ));
}
if ( $response [ 'code' ] < 200 || $response [ 'code' ] >= 300 ) {
return new WP_Error ( 'contents_http_error' , sprintf ( __ ( 'Contents-endpoint svarede med HTTP %d.' , 'ansico-plugins' ), ( int ) $response [ 'code' ]));
}
$contents = $this -> parse_json_response ( $response , 'invalid_contents' , __ ( 'Kunne ikke læse repository-indhold.' , 'ansico-plugins' ));
return is_wp_error ( $contents ) ? $contents : $contents ;
}
public function get_repository_readme_title ( $owner , $repo_name , $ref = '' ) {
2026-04-18 21:19:08 +00:00
$documentation = $this -> get_repository_documentation ( $owner , $repo_name , $ref );
if ( is_wp_error ( $documentation )) {
return '' ;
}
return ! empty ( $documentation [ 'title' ]) ? ( string ) $documentation [ 'title' ] : '' ;
}
public function get_repository_documentation ( $owner , $repo_name , $ref = '' ) {
$candidates = array ( 'readme.txt' , 'README.txt' , 'README.md' , 'readme.md' , 'Readme.md' );
2026-04-18 20:50:31 +00:00
foreach ( $candidates as $candidate ) {
2026-04-18 21:19:08 +00:00
$raw = $this -> get_repository_text_file ( $owner , $repo_name , $candidate , $ref );
if ( '' === $raw ) {
continue ;
}
if ( preg_match ( '/\.txt$/i' , $candidate )) {
$parsed = $this -> parse_wordpress_readme ( $raw );
} else {
$parsed = $this -> parse_markdown_readme ( $raw );
}
if ( ! empty ( $parsed [ 'title' ]) || ! empty ( $parsed [ 'short_description' ]) || ! empty ( $parsed [ 'sections' ])) {
$parsed [ 'source' ] = $candidate ;
return $parsed ;
}
}
return array (
'title' => '' ,
'short_description' => '' ,
'sections' => array (),
'source' => '' ,
);
}
private function get_repository_text_file ( $owner , $repo_name , $path , $ref = '' ) {
$file = $this -> get_repository_contents ( $owner , $repo_name , $path , $ref );
if ( is_wp_error ( $file ) || ! is_array ( $file ) || empty ( $file [ 'content' ]) || empty ( $file [ 'encoding' ]) || 'base64' !== $file [ 'encoding' ]) {
return '' ;
}
$raw = base64_decode (( string ) $file [ 'content' ], true );
if ( false === $raw ) {
return '' ;
}
return str_replace ( array ( "
" , "
" ), "
" , (string) $raw );
}
private function parse_wordpress_readme ( $raw ) {
$raw = trim (( string ) $raw );
$lines = preg_split ( ' /
/ ' , $raw );
$title = '' ;
$short_description = '' ;
$sections = array ();
$current = '' ;
$buffer = array ();
$header_done = false ;
foreach ( $lines as $line ) {
if ( '' === $title && preg_match ( '/^===\s*(.+?)\s*===\s*$/' , $line , $m )) {
$title = trim ( $m [ 1 ]);
continue ;
}
if ( ! $header_done && preg_match ( '/^==\s*(.+?)\s*==\s*$/' , $line , $m )) {
$header_done = true ;
$current = strtolower ( trim ( $m [ 1 ]));
$buffer = array ();
continue ;
}
if ( ! $header_done ) {
if ( '' === $short_description && '' !== trim ( $line ) && false === strpos ( $line , ':' )) {
$short_description = trim ( $line );
}
continue ;
}
if ( preg_match ( '/^==\s*(.+?)\s*==\s*$/' , $line , $m )) {
if ( '' !== $current ) {
$sections [ $current ] = trim ( implode ( "
" , $buffer ));
}
$current = strtolower ( trim ( $m [ 1 ]));
$buffer = array ();
continue ;
}
$buffer [] = $line ;
}
if ( '' !== $current ) {
$sections [ $current ] = trim ( implode ( "
" , $buffer ));
}
if ( '' === $short_description && ! empty ( $sections [ 'description' ])) {
$short_description = $this -> first_paragraph ( $sections [ 'description' ]);
}
return array (
'title' => $title ,
'short_description' => $short_description ,
'sections' => $sections ,
);
}
private function parse_markdown_readme ( $raw ) {
$title = '' ;
$short_description = '' ;
$sections = array ();
$current = '' ;
$buffer = array ();
$after_title = '' ;
foreach ( preg_split ( ' /
/ ' , ( string ) $raw ) as $line ) {
if ( '' === $title && preg_match ( '/^#\s+(.+)$/' , $line , $m )) {
$title = trim ( wp_strip_all_tags ( $m [ 1 ]));
2026-04-18 20:50:31 +00:00
continue ;
}
2026-04-18 21:19:08 +00:00
if ( preg_match ( '/^##\s+(.+)$/' , $line , $m )) {
if ( '' !== $current ) {
$sections [ $current ] = trim ( implode ( "
" , $buffer ));
}
$current = strtolower ( trim ( wp_strip_all_tags ( $m [ 1 ])));
$buffer = array ();
2026-04-18 20:50:31 +00:00
continue ;
}
2026-04-18 21:19:08 +00:00
if ( '' === $current ) {
$after_title .= $line . "
" ;
} else {
$buffer [] = $line ;
2026-04-18 20:50:31 +00:00
}
}
2026-04-18 21:19:08 +00:00
if ( '' !== $current ) {
$sections [ $current ] = trim ( implode ( "
" , $buffer ));
}
$short_description = $this -> first_paragraph ( $after_title );
if ( '' === $short_description && ! empty ( $sections [ 'description' ])) {
$short_description = $this -> first_paragraph ( $sections [ 'description' ]);
}
return array (
'title' => $title ,
'short_description' => $short_description ,
'sections' => $sections ,
);
}
private function first_paragraph ( $text ) {
$text = trim (( string ) $text );
if ( '' === $text ) {
return '' ;
}
$parts = preg_split ( " /
\s *
/ " , $text );
if ( empty ( $parts [ 0 ])) {
return '' ;
}
return trim ( wp_strip_all_tags ( $parts [ 0 ]));
}
private function find_repository_asset_url ( $owner , $repo_name , $default_branch , $candidates ) {
foreach (( array ) $candidates as $candidate ) {
$file = $this -> get_repository_contents ( $owner , $repo_name , $candidate , $default_branch );
if ( ! is_wp_error ( $file ) && is_array ( $file ) && ! empty ( $file [ 'download_url' ])) {
return ( string ) $file [ 'download_url' ];
}
}
2026-04-18 20:50:31 +00:00
return '' ;
}
public function get_repository_plugin_metadata ( $owner , $repo_name ) {
$repo = $this -> get_repository ( $owner , $repo_name );
if ( is_wp_error ( $repo )) {
return $repo ;
}
$default_branch = ! empty ( $repo [ 'default_branch' ]) ? ( string ) $repo [ 'default_branch' ] : '' ;
$root = $this -> get_repository_contents ( $owner , $repo_name , '' , $default_branch );
$plugin_headers = array ();
2026-04-18 21:19:08 +00:00
if ( ! is_wp_error ( $root ) && is_array ( $root )) {
foreach ( $root as $item ) {
if ( ! is_array ( $item ) || empty ( $item [ 'name' ])) {
continue ;
}
$name = ( string ) $item [ 'name' ];
if ( empty ( $plugin_headers ) && ! empty ( $item [ 'type' ]) && 'file' === $item [ 'type' ] && preg_match ( '/\.php$/i' , $name )) {
$file = $this -> get_repository_contents ( $owner , $repo_name , $name , $default_branch );
if ( ! is_wp_error ( $file ) && is_array ( $file ) && ! empty ( $file [ 'content' ]) && ! empty ( $file [ 'encoding' ]) && 'base64' === $file [ 'encoding' ]) {
$raw = base64_decode (( string ) $file [ 'content' ], true );
if ( false !== $raw ) {
$plugin_headers = $this -> parse_plugin_headers ( $raw );
}
2026-04-18 20:50:31 +00:00
}
}
}
}
2026-04-18 21:19:08 +00:00
$documentation = $this -> get_repository_documentation ( $owner , $repo_name , $default_branch );
if ( is_wp_error ( $documentation )) {
$documentation = array ( 'title' => '' , 'short_description' => '' , 'sections' => array (), 'source' => '' );
}
2026-04-18 20:50:31 +00:00
$author_name = ! empty ( $plugin_headers [ 'Author' ]) ? ( string ) $plugin_headers [ 'Author' ] : ( ! empty ( $repo [ 'owner' ][ 'full_name' ]) ? ( string ) $repo [ 'owner' ][ 'full_name' ] : ( ! empty ( $repo [ 'owner' ][ 'login' ]) ? ( string ) $repo [ 'owner' ][ 'login' ] : '' ));
$author_url = ! empty ( $plugin_headers [ 'AuthorURI' ]) ? ( string ) $plugin_headers [ 'AuthorURI' ] : ( ! empty ( $repo [ 'owner' ][ 'website' ]) ? ( string ) $repo [ 'owner' ][ 'website' ] : ( ! empty ( $repo [ 'owner' ][ 'html_url' ]) ? ( string ) $repo [ 'owner' ][ 'html_url' ] : '' ));
$support_url = ! empty ( $plugin_headers [ 'SupportURI' ]) ? ( string ) $plugin_headers [ 'SupportURI' ] : ( ! empty ( $repo [ 'html_url' ]) ? trailingslashit (( string ) $repo [ 'html_url' ]) . 'issues' : '' );
$license = ! empty ( $plugin_headers [ 'License' ]) ? ( string ) $plugin_headers [ 'License' ] : ( ! empty ( $repo [ 'license' ][ 'spdx_id' ]) ? ( string ) $repo [ 'license' ][ 'spdx_id' ] : '' );
2026-04-18 21:19:08 +00:00
$screenshot_url = $this -> find_repository_asset_url ( $owner , $repo_name , $default_branch , array ( 'screenshot.png' , 'assets/screenshot.png' ));
$icon_url = $this -> find_repository_asset_url ( $owner , $repo_name , $default_branch , array ( 'icon-256x256.png' , 'icon-128x128.png' , 'assets/icon-256x256.png' , 'assets/icon-128x128.png' ));
$banner_url = $this -> find_repository_asset_url ( $owner , $repo_name , $default_branch , array ( 'banner-1544x500.png' , 'banner-772x250.png' , 'assets/banner-1544x500.png' , 'assets/banner-772x250.png' ));
2026-04-18 20:50:31 +00:00
return array (
2026-04-18 21:19:08 +00:00
'readme_title' => ! empty ( $documentation [ 'title' ]) ? $documentation [ 'title' ] : '' ,
'description' => ! empty ( $documentation [ 'short_description' ]) ? $documentation [ 'short_description' ] : ( ! empty ( $repo [ 'description' ]) ? ( string ) $repo [ 'description' ] : '' ),
'readme_sections' => ! empty ( $documentation [ 'sections' ]) && is_array ( $documentation [ 'sections' ]) ? $documentation [ 'sections' ] : array (),
'readme_source' => ! empty ( $documentation [ 'source' ]) ? $documentation [ 'source' ] : '' ,
2026-04-18 20:50:31 +00:00
'author_name' => $author_name ,
'author_url' => $author_url ,
'plugin_headers' => $plugin_headers ,
'support_url' => $support_url ,
'license' => $license ,
'screenshot_url' => $screenshot_url ,
2026-04-18 21:19:08 +00:00
'icon_url' => $icon_url ,
'banner_url' => $banner_url ,
2026-04-18 20:50:31 +00:00
'default_branch' => $default_branch ,
);
}
private function parse_plugin_headers ( $content ) {
$headers = array (
'Plugin Name' => 'Name' ,
'Author' => 'Author' ,
'Author URI' => 'AuthorURI' ,
'Plugin URI' => 'PluginURI' ,
'Description' => 'Description' ,
'Version' => 'Version' ,
'Requires at least' => 'RequiresWP' ,
'Requires PHP' => 'RequiresPHP' ,
'License' => 'License' ,
'License URI' => 'LicenseURI' ,
'Text Domain' => 'TextDomain' ,
'Support URI' => 'SupportURI' ,
);
$parsed = array ();
foreach ( $headers as $label => $key ) {
if ( preg_match ( '/^[ \t\/*#@]*' . preg_quote ( $label , '/' ) . ':(.*)$/mi' , ( string ) $content , $matches )) {
$parsed [ $key ] = trim ( wp_strip_all_tags ( $matches [ 1 ]));
}
}
return $parsed ;
}
public function request ( $method , $url , $allow_retry_without_auth = true ) {
$method = strtoupper (( string ) $method );
$headers = array (
'Accept' => 'application/json' ,
'User-Agent' => 'Ansico-Plugins/' . ANSICO_PLUGINS_VERSION . '; ' . home_url ( '/' ),
);
if ( ! empty ( $this -> settings [ 'access_token' ])) {
$headers [ 'Authorization' ] = 'token ' . trim (( string ) $this -> settings [ 'access_token' ]);
}
$args = array (
'method' => $method ,
'headers' => $headers ,
'timeout' => max ( 5 , ( int ) $this -> settings [ 'request_timeout' ]),
'sslverify' => ! empty ( $this -> settings [ 'verify_ssl' ]),
);
$cache_key = $this -> cache_key ( $method , $url );
if ( 'GET' === $method ) {
$cached = get_transient ( $cache_key );
if ( is_array ( $cached ) && isset ( $cached [ 'body' ], $cached [ 'code' ])) {
return $cached ;
}
}
$response = wp_remote_request ( esc_url_raw ( $url ), $args );
if ( is_wp_error ( $response )) {
return $response ;
}
$normalized = $this -> normalize_http_response ( $response );
if (
$allow_retry_without_auth &&
! empty ( $this -> settings [ 'access_token' ]) &&
in_array (( int ) $normalized [ 'code' ], array ( 401 , 403 ), true )
) {
unset ( $args [ 'headers' ][ 'Authorization' ]);
$retry_response = wp_remote_request ( esc_url_raw ( $url ), $args );
if ( ! is_wp_error ( $retry_response )) {
$normalized = $this -> normalize_http_response ( $retry_response );
}
}
if ( 'GET' === $method ) {
set_transient ( $cache_key , $normalized , 5 * MINUTE_IN_SECONDS );
}
return $normalized ;
}
}