Files
Keith Solomon 0613e33411
Sync TODOs with Issues / sync_todos (push) Successful in 6s
Enhance project handling for websites in portfolio
- Added methods in Projects class to determine if a project is a website, retrieve its URL, platform, and screenshot.
- Updated single-project template to display website-specific information and actions.
- Modified project card component to show website details and adjust action buttons accordingly.
- Improved CSS for project cards and buttons to align with new website features.
2026-08-22 15:14:28 -05:00

196 lines
5.2 KiB
PHP

<?php
/**
* Project helper for the ks-portfolio theme.
*
* Thin wrapper around the projects-portfolio plugin's provider-aware
* helpers. Templates should call these methods instead of branching on
* provider, so the theme stays decoupled from GitHub/Gitea implementation
* details.
*
* Every accessor is safe to call whether the plugin is active or not: when
* the underlying function is missing or repo data is unavailable, defaults
* that match the documented data contract are returned.
*
* @package KsPortfolio
*/
namespace KsPortfolio;
/**
* Provider-agnostic helper wrapping the projects-portfolio plugin.
*/
class Projects {
/**
* Whether the projects-portfolio plugin is active.
*
* @return bool
*/
public static function is_plugin_active(): bool {
return function_exists( 'projects_portfolio_get_provider' );
}
/**
* Provider label for a project (e.g. 'GitHub', 'Gitea', or 'Unknown').
*
* @param int $post_id Project post ID.
* @return string
*/
public static function get_provider_label( int $post_id ): string {
if ( ! self::is_plugin_active() ) {
return 'Unknown';
}
$provider = projects_portfolio_get_provider( $post_id );
return method_exists( $provider, 'get_label' ) ? (string) $provider->get_label() : 'Unknown';
}
/**
* Release ZIP URL (or empty string).
*
* @param int $post_id Project post ID.
* @return string
*/
public static function get_release_url( int $post_id ): string {
if ( ! self::is_plugin_active() ) {
return '';
}
return (string) projects_portfolio_get_release_url( $post_id );
}
/**
* Public repository browse URL (or empty string).
*
* @param int $post_id Project post ID.
* @return string
*/
public static function get_repo_browse_url( int $post_id ): string {
if ( ! self::is_plugin_active() ) {
return '';
}
$provider = projects_portfolio_get_provider( $post_id );
return method_exists( $provider, 'get_repo_browse_url' ) ? (string) $provider->get_repo_browse_url() : '';
}
/**
* Normalized repository data array (or null).
*
* @param int $post_id Project post ID.
* @return array<string,mixed>|null
*/
public static function get_repo_data( int $post_id ) {
if ( ! self::is_plugin_active() ) {
return null;
}
$data = projects_portfolio_get_repo_data( $post_id );
return is_array( $data ) ? $data : null;
}
/**
* Owner data (avatar/login/html_url) or null.
*
* @param int $post_id Project post ID.
* @return array<string,mixed>|null
*/
public static function get_owner_data( int $post_id ) {
$data = self::get_repo_data( $post_id );
if ( ! $data || empty( $data['owner']['login'] ) ) {
return null;
}
return $data['owner'];
}
/**
* Latest release tag, or 'Unknown'.
*
* @param int $post_id Project post ID.
* @return string
*/
public static function get_latest_version( int $post_id ): string {
if ( ! self::is_plugin_active() ) {
return 'Unknown';
}
$provider = projects_portfolio_get_provider( $post_id );
return method_exists( $provider, 'get_latest_version' ) ? (string) $provider->get_latest_version() : 'Unknown';
}
/**
* Local download endpoint URL for the project.
*
* @param int $post_id Project post ID.
* @return string
*/
public static function get_download_url( int $post_id ): string {
return home_url( '/download/' . $post_id . '/' );
}
/**
* Render a stat-card-safe integer with optional formatting.
*
* @param mixed $value Raw repo stat value.
* @return string Display-safe string ('1.2k', '12,345', etc.) or '—' when empty.
*/
public static function format_stat( $value ): string {
if ( null === $value || '' === $value ) {
return '—';
}
$value = (int) $value;
if ( $value >= 10000 ) {
return number_format( $value / 1000, 1 ) . 'k';
}
return number_format( $value );
}
/**
* Whether the project is configured as a website rather than a git repo.
*
* @param int $post_id Project post ID.
* @return bool
*/
public static function is_website( int $post_id ): bool {
if ( ! self::is_plugin_active() ) {
return false;
}
return (bool) projects_portfolio_is_website( $post_id );
}
/**
* Public URL for the project's website (or empty string).
*
* @param int $post_id Project post ID.
* @return string
*/
public static function get_site_url( int $post_id ): string {
if ( ! self::is_plugin_active() ) {
return '';
}
return (string) projects_portfolio_get_site_url( $post_id );
}
/**
* Platform label for the project's website (or empty string).
*
* @param int $post_id Project post ID.
* @return string
*/
public static function get_site_platform( int $post_id ): string {
if ( ! self::is_plugin_active() ) {
return '';
}
return (string) projects_portfolio_get_site_platform( $post_id );
}
/**
* Screenshot attachment URL for the project's website (or empty string).
*
* @param int $post_id Project post ID.
* @param string $size Registered image size.
* @return string
*/
public static function get_site_screenshot_url( int $post_id, string $size = 'large' ): string {
if ( ! self::is_plugin_active() ) {
return '';
}
return (string) projects_portfolio_get_site_screenshot_url( $post_id, $size );
}
}