Skip to content

Commit 8408847

Browse files
authored
Enhance GitHub Portfolio Fetcher functionality
Updated plugin name and version. Improved error handling and caching for GitHub API requests.
1 parent 73218cc commit 8408847

1 file changed

Lines changed: 57 additions & 46 deletions

File tree

github-portfolio-fetcher.php

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,86 @@
11
<?php
22
/**
3-
* Plugin Name: GitHub Portfolio Fetcher
4-
* Description: Connects to the GitHub API, fetches your top repositories, and caches them for performance.
5-
* Version: 1.0.0
6-
* Author: Vamsi Bodapati
3+
* Plugin Name: GitHub Portfolio Fetcher (Enterprise Edition)
4+
* Description: Fetches and caches GitHub repositories with advanced error handling and rate-limit protection.
5+
* Version: 2.0.0
6+
* Author: Vamsi Bodapati
77
*/
88

9-
if ( ! defined( 'ABSPATH' ) ) { exit; }
9+
if ( ! defined( 'ABSPATH' ) ) {
10+
exit; // Exit if accessed directly
11+
}
12+
13+
class GitHub_Portfolio_Fetcher {
1014

11-
class WP_Github_Fetcher {
15+
private $username = 'Vamsi0702'; // Your verified username
16+
private $transient_key = 'vamsi_github_repos';
1217

1318
public function __construct() {
14-
add_shortcode( 'my_github_repos', array( $this, 'render_repos' ) );
19+
add_shortcode( 'my_github_repos', [ $this, 'render_github_repos' ] );
1520
}
1621

17-
/**
18-
* Fetch data from GitHub API with Caching (Transient API)
19-
*/
20-
private function get_repos() {
21-
// 1. Check if we have the data cached (saved in database) for 1 hour
22-
$cached_repos = get_transient( 'vamsi_github_repos' );
23-
if ( false !== $cached_repos ) {
24-
return $cached_repos;
22+
public function fetch_repositories() {
23+
$cached_data = get_transient( $this->transient_key );
24+
25+
if ( false !== $cached_data ) {
26+
return $cached_data;
2527
}
2628

27-
// 2. If not cached, connect to GitHub API
28-
$response = wp_remote_get( 'https://api.github.com/users/Vamsi0702/repos?sort=updated&per_page=5', array(
29-
'user-agent' => 'WordPress-Portfolio-Site'
30-
));
29+
$url = "https://api.github.com/users/{$this->username}/repos?sort=updated&per_page=5";
30+
31+
// Advanced HTTP Request with User-Agent (Required by GitHub API)
32+
$response = wp_remote_get( $url, [
33+
'timeout' => 15,
34+
'user-agent' => 'WordPress-Portfolio-Fetcher'
35+
]);
3136

32-
// 3. Error Handling (If GitHub is down)
33-
if ( is_wp_error( $response ) ) {
37+
// FIX: Missing HTTP header validation
38+
$response_code = wp_remote_retrieve_response_code( $response );
39+
if ( 200 !== $response_code ) {
40+
// Cache a "failure" for 10 minutes to prevent hitting rate limits repeatedly
41+
set_transient( $this->transient_key, [], 10 * MINUTE_IN_SECONDS );
3442
return [];
3543
}
3644

3745
$body = wp_remote_retrieve_body( $response );
3846
$data = json_decode( $body );
3947

40-
// 4. Save to Cache for 1 hour (3600 seconds) - Performance Boost!
41-
set_transient( 'vamsi_github_repos', $data, 3600 );
48+
// FIX: Silent failure on JSON decode
49+
if ( ! is_array( $data ) ) {
50+
set_transient( $this->transient_key, [], 10 * MINUTE_IN_SECONDS );
51+
return [];
52+
}
53+
54+
// Cache successful response for 1 hour as per ADR standards
55+
set_transient( $this->transient_key, $data, HOUR_IN_SECONDS );
4256

4357
return $data;
4458
}
4559

46-
/**
47-
* Render the HTML
48-
*/
49-
public function render_repos() {
50-
$repos = $this->get_repos();
60+
public function render_github_repos() {
61+
$repos = $this->fetch_repositories();
5162

5263
if ( empty( $repos ) ) {
53-
return '<p>Could not load GitHub repositories.</p>';
64+
return '<p>Could not load GitHub repositories at this time.</p>';
65+
}
66+
67+
$output = '<ul class="github-repos">';
68+
foreach ( $repos as $repo ) {
69+
// FIX: No language fallback
70+
$language = ! empty( $repo->language ) ? esc_html( $repo->language ) : 'Not specified';
71+
72+
$output .= sprintf(
73+
'<li><strong><a href="%s" target="_blank">%s</a></strong> - %s <em>(%s)</em></li>',
74+
esc_url( $repo->html_url ),
75+
esc_html( $repo->name ),
76+
esc_html( $repo->description ),
77+
$language
78+
);
5479
}
80+
$output .= '</ul>';
5581

56-
ob_start();
57-
?>
58-
<div class="github-showcase" style="display: grid; gap: 15px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));">
59-
<?php foreach ( $repos as $repo ) : ?>
60-
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 8px; background: #fff;">
61-
<h3 style="margin: 0 0 10px 0;"><a href="<?php echo esc_url( $repo->html_url ); ?>" target="_blank" style="text-decoration:none; color:#0073aa;"><?php echo esc_html( $repo->name ); ?></a></h3>
62-
<p style="color: #666; font-size: 14px;"><?php echo esc_html( $repo->description ? $repo->description : 'No description.' ); ?></p>
63-
<div style="font-size: 12px; font-weight: bold; color: #333;">
64-
Stars: <?php echo intval( $repo->stargazers_count ); ?> |
65-
Language: <?php echo esc_html( $repo->language ); ?>
66-
</div>
67-
</div>
68-
<?php endforeach; ?>
69-
</div>
70-
<?php
71-
return ob_get_clean();
82+
return $output;
7283
}
7384
}
7485

75-
new WP_Github_Fetcher();
86+
new GitHub_Portfolio_Fetcher();

0 commit comments

Comments
 (0)