v1.1.0
This commit is contained in:
parent
443dceb8ca
commit
92d56fe84d
4445 changed files with 992 additions and 529601 deletions
|
|
@ -16,9 +16,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
* @since 1.0.0
|
||||
*
|
||||
* @param string $url GitHub repository URL.
|
||||
* @return array|WP_Error Array with 'owner' and 'repo' or error.
|
||||
* @return array{owner: string, repo: string}|WP_Error Array with 'owner' and 'repo' or error.
|
||||
*/
|
||||
function robotstxt_docmd_parse_github_url( $url ) {
|
||||
function robotstxt_docmd_parse_github_url( string $url ): array|WP_Error {
|
||||
if ( ! str_starts_with( $url, 'https://' ) ) {
|
||||
return new WP_Error( 'invalid_url', __( 'GitHub URL must use HTTPS', 'robotstxt-documentation-markdown' ) );
|
||||
}
|
||||
|
|
@ -33,6 +33,43 @@ function robotstxt_docmd_parse_github_url( $url ) {
|
|||
return new WP_Error( 'invalid_format', __( 'Could not parse GitHub URL', 'robotstxt-documentation-markdown' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and normalize a list of file data from cache or API response
|
||||
*
|
||||
* Converts untyped cache data back into the expected typed structure.
|
||||
* Required for PHPStan level 9 compliance with transient cache usage.
|
||||
*
|
||||
* @since 1.0.1
|
||||
*
|
||||
* @param mixed $data Raw data to validate (typically from get_transient()).
|
||||
* @return list<array{path: string, name: string, size: int, sha: string}>
|
||||
*/
|
||||
function robotstxt_docmd_validate_file_list( mixed $data ): array {
|
||||
if ( ! is_array( $data ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ( $data as $item ) {
|
||||
if ( is_array( $item )
|
||||
&& isset( $item['path'], $item['name'], $item['size'], $item['sha'] )
|
||||
&& is_string( $item['path'] )
|
||||
&& is_string( $item['name'] )
|
||||
&& is_int( $item['size'] )
|
||||
&& is_string( $item['sha'] )
|
||||
) {
|
||||
$result[] = array(
|
||||
'path' => $item['path'],
|
||||
'name' => $item['name'],
|
||||
'size' => $item['size'],
|
||||
'sha' => $item['sha'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all markdown files from repository
|
||||
*
|
||||
|
|
@ -42,15 +79,15 @@ function robotstxt_docmd_parse_github_url( $url ) {
|
|||
* @param string $repo Repository name.
|
||||
* @param string $branch Branch name.
|
||||
* @param string $token GitHub token (encrypted).
|
||||
* @return array|WP_Error Array of files or error.
|
||||
* @return list<array{path: string, name: string, size: int, sha: string}>|WP_Error Array of files or error.
|
||||
*/
|
||||
function robotstxt_docmd_get_all_markdown_files( $owner, $repo, $branch, $token ) {
|
||||
function robotstxt_docmd_get_all_markdown_files( string $owner, string $repo, string $branch, string $token ): array|WP_Error {
|
||||
// Check cache first.
|
||||
$cache_key = sprintf( 'robotstxt_docmd_files_%s_%s_%s', $owner, $repo, $branch );
|
||||
$cached = get_transient( $cache_key );
|
||||
|
||||
if ( false !== $cached ) {
|
||||
return $cached;
|
||||
return robotstxt_docmd_validate_file_list( $cached );
|
||||
}
|
||||
|
||||
// Decrypt token.
|
||||
|
|
@ -63,16 +100,13 @@ function robotstxt_docmd_get_all_markdown_files( $owner, $repo, $branch, $token
|
|||
return $files;
|
||||
}
|
||||
|
||||
// Filter only markdown files.
|
||||
$markdown_files = array_filter(
|
||||
$files,
|
||||
function ( $file ) {
|
||||
return preg_match( '/\.(md|markdown)$/i', $file['path'] );
|
||||
// Filter only markdown files and re-index.
|
||||
$markdown_files = array();
|
||||
foreach ( $files as $file ) {
|
||||
if ( preg_match( '/\.(md|markdown)$/i', $file['path'] ) ) {
|
||||
$markdown_files[] = $file;
|
||||
}
|
||||
);
|
||||
|
||||
// Re-index array.
|
||||
$markdown_files = array_values( $markdown_files );
|
||||
}
|
||||
|
||||
// Cache for 24 hours.
|
||||
set_transient( $cache_key, $markdown_files, DAY_IN_SECONDS );
|
||||
|
|
@ -91,9 +125,9 @@ function robotstxt_docmd_get_all_markdown_files( $owner, $repo, $branch, $token
|
|||
* @param string $branch Branch name.
|
||||
* @param string $token GitHub token (plain).
|
||||
* @param int $depth Current depth (for recursion limit).
|
||||
* @return array|WP_Error Array of files or error.
|
||||
* @return list<array{path: string, name: string, size: int, sha: string}>|WP_Error Array of files or error.
|
||||
*/
|
||||
function robotstxt_docmd_get_repository_contents_recursive( $owner, $repo, $path, $branch, $token, $depth = 0 ) {
|
||||
function robotstxt_docmd_get_repository_contents_recursive( string $owner, string $repo, string $path, string $branch, string $token, int $depth = 0 ): array|WP_Error {
|
||||
// Prevent infinite recursion.
|
||||
if ( $depth > 10 ) {
|
||||
return array();
|
||||
|
|
@ -145,6 +179,17 @@ function robotstxt_docmd_get_repository_contents_recursive( $owner, $repo, $path
|
|||
$files = array();
|
||||
|
||||
foreach ( $contents as $item ) {
|
||||
if ( ! is_array( $item )
|
||||
|| ! isset( $item['type'], $item['path'], $item['name'], $item['size'], $item['sha'] )
|
||||
|| ! is_string( $item['type'] )
|
||||
|| ! is_string( $item['path'] )
|
||||
|| ! is_string( $item['name'] )
|
||||
|| ! is_string( $item['sha'] )
|
||||
|| ! is_int( $item['size'] )
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'file' === $item['type'] ) {
|
||||
// Skip files larger than 10MB.
|
||||
if ( $item['size'] > 10 * 1024 * 1024 ) {
|
||||
|
|
@ -189,7 +234,7 @@ function robotstxt_docmd_get_repository_contents_recursive( $owner, $repo, $path
|
|||
* @param string $token GitHub token (encrypted).
|
||||
* @return string|WP_Error File content or error.
|
||||
*/
|
||||
function robotstxt_docmd_get_file_content( $owner, $repo, $file_path, $branch, $token ) {
|
||||
function robotstxt_docmd_get_file_content( string $owner, string $repo, string $file_path, string $branch, string $token ): string|WP_Error {
|
||||
$decrypted_token = robotstxt_docmd_decrypt_token( $token );
|
||||
|
||||
$url = sprintf(
|
||||
|
|
@ -231,7 +276,11 @@ function robotstxt_docmd_get_file_content( $owner, $repo, $file_path, $branch, $
|
|||
$body = wp_remote_retrieve_body( $response );
|
||||
$data = json_decode( $body, true );
|
||||
|
||||
if ( ! isset( $data['content'] ) || ! isset( $data['encoding'] ) ) {
|
||||
if ( ! is_array( $data )
|
||||
|| ! isset( $data['content'], $data['encoding'] )
|
||||
|| ! is_string( $data['content'] )
|
||||
|| ! is_string( $data['encoding'] )
|
||||
) {
|
||||
return new WP_Error( 'invalid_response', __( 'Invalid file response from GitHub', 'robotstxt-documentation-markdown' ) );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue