Constants
19 hours ago
Accordion.php
19 hours ago
Alert.php
19 hours ago
AttachmentCard.php
19 hours ago
Avatar.php
19 hours ago
Badge.php
19 hours ago
BaseComponent.php
19 hours ago
Button.php
19 hours ago
ConfirmationModal.php
19 hours ago
CourseFilter.php
19 hours ago
DateFilter.php
19 hours ago
DropdownFilter.php
19 hours ago
EmptyState.php
19 hours ago
FileUploader.php
19 hours ago
InputField.php
19 hours ago
Modal.php
19 hours ago
Nav.php
19 hours ago
Pagination.php
19 hours ago
Popover.php
19 hours ago
PreviewTrigger.php
19 hours ago
Progress.php
19 hours ago
SearchFilter.php
19 hours ago
Sorting.php
19 hours ago
StarRating.php
19 hours ago
StarRatingInput.php
19 hours ago
StatusSelect.php
19 hours ago
SvgIcon.php
19 hours ago
Table.php
19 hours ago
Tabs.php
19 hours ago
Tooltip.php
19 hours ago
WPEditor.php
19 hours ago
Avatar.php
342 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Avatar Component Class. |
| 4 | * |
| 5 | * @package Tutor\Components |
| 6 | * @author Themeum |
| 7 | * @link https://themeum.com |
| 8 | * @since 4.0.0 |
| 9 | */ |
| 10 | |
| 11 | namespace Tutor\Components; |
| 12 | |
| 13 | use Tutor\Components\Constants\Size; |
| 14 | use Tutor\Cache\TutorCache; |
| 15 | |
| 16 | defined( 'ABSPATH' ) || exit; |
| 17 | |
| 18 | /** |
| 19 | * Class Avatar |
| 20 | * |
| 21 | * Responsible for rendering user avatars using either an image or initials. |
| 22 | * Supports various sizes, border styles, and radius options. |
| 23 | * |
| 24 | * Example usage: |
| 25 | * |
| 26 | * ```php |
| 27 | * Avatar with user object/ID |
| 28 | * Avatar::make() |
| 29 | * ->user($user_id) |
| 30 | * ->size(Size::SIZE_56) |
| 31 | * ->render(); |
| 32 | * |
| 33 | * Avatar with image source |
| 34 | * Avatar::make() |
| 35 | * ->src('https://example.com/avatar.jpg') |
| 36 | * ->size(Size::SIZE_20) |
| 37 | * ->bordered() |
| 38 | * ->render(); |
| 39 | * |
| 40 | * Avatar with initials |
| 41 | * Avatar::make() |
| 42 | * ->initials('SK') |
| 43 | * ->size(Size::SIZE_32) |
| 44 | * ->rounded(false) |
| 45 | * ->render(); |
| 46 | * ``` |
| 47 | * |
| 48 | * @since 4.0.0 |
| 49 | */ |
| 50 | class Avatar extends BaseComponent { |
| 51 | |
| 52 | /** |
| 53 | * Avatar size (20, 24, etc). |
| 54 | * |
| 55 | * @since 4.0.0 |
| 56 | * |
| 57 | * @see Size constants |
| 58 | * |
| 59 | * @var string |
| 60 | */ |
| 61 | protected $size = Size::SIZE_56; |
| 62 | |
| 63 | /** |
| 64 | * Avatar type (image or initials). |
| 65 | * |
| 66 | * @since 4.0.0 |
| 67 | * |
| 68 | * @var string |
| 69 | */ |
| 70 | protected $type = 'image'; |
| 71 | |
| 72 | /** |
| 73 | * Avatar image URL. |
| 74 | * |
| 75 | * @since 4.0.0 |
| 76 | * @var string|null |
| 77 | */ |
| 78 | protected $src = null; |
| 79 | |
| 80 | /** |
| 81 | * User initials. |
| 82 | * |
| 83 | * @since 4.0.0 |
| 84 | * |
| 85 | * @var string|null |
| 86 | */ |
| 87 | protected $initials = null; |
| 88 | |
| 89 | /** |
| 90 | * User object or ID. |
| 91 | * |
| 92 | * @since 4.0.0 |
| 93 | * |
| 94 | * @var int|object|null |
| 95 | */ |
| 96 | protected $user = null; |
| 97 | |
| 98 | /** |
| 99 | * Avatar alt text. |
| 100 | * |
| 101 | * @since 4.0.0 |
| 102 | * |
| 103 | * @var string|null |
| 104 | */ |
| 105 | protected $alt = null; |
| 106 | |
| 107 | /** |
| 108 | * Border enabled flag. |
| 109 | * |
| 110 | * @since 4.0.0 |
| 111 | * |
| 112 | * @var bool |
| 113 | */ |
| 114 | protected $bordered = false; |
| 115 | |
| 116 | /** |
| 117 | * Avatar Shape |
| 118 | * |
| 119 | * @since 4.0.0 |
| 120 | * |
| 121 | * @var string |
| 122 | */ |
| 123 | protected $shape = ''; |
| 124 | |
| 125 | /** |
| 126 | * Set the avatar size. |
| 127 | * |
| 128 | * @since 4.0.0 |
| 129 | * |
| 130 | * @param string $size Avatar size, see size constants. |
| 131 | * |
| 132 | * @return $this |
| 133 | */ |
| 134 | public function size( string $size ): self { |
| 135 | $this->size = sanitize_html_class( $size ); |
| 136 | return $this; |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Set the avatar type (image or initials). |
| 141 | * |
| 142 | * @since 4.0.0 |
| 143 | * |
| 144 | * @param string $type Avatar type. |
| 145 | * |
| 146 | * @return $this |
| 147 | */ |
| 148 | public function type( string $type ): self { |
| 149 | $this->type = in_array( $type, array( 'image', 'initials' ), true ) ? $type : 'image'; |
| 150 | return $this; |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * Set the avatar shape ('' or square). |
| 155 | * |
| 156 | * @since 4.0.0 |
| 157 | * |
| 158 | * @param string $shape Avatar shape. |
| 159 | * |
| 160 | * @return $this |
| 161 | */ |
| 162 | public function shape( string $shape = '' ): self { |
| 163 | $this->shape = $shape; |
| 164 | return $this; |
| 165 | } |
| 166 | |
| 167 | /** |
| 168 | * Set the image URL for avatar. |
| 169 | * |
| 170 | * @since 4.0.0 |
| 171 | * |
| 172 | * @param string $src Image URL. |
| 173 | * @return $this |
| 174 | */ |
| 175 | public function src( string $src ): self { |
| 176 | $this->src = esc_url_raw( $src ); |
| 177 | return $this; |
| 178 | } |
| 179 | |
| 180 | /** |
| 181 | * Set initials for the avatar. |
| 182 | * |
| 183 | * @since 4.0.0 |
| 184 | * |
| 185 | * @param string $initials User initials. |
| 186 | * @return $this |
| 187 | */ |
| 188 | public function initials( string $initials ): self { |
| 189 | $this->initials = strtoupper( sanitize_text_field( $initials ) ); |
| 190 | return $this; |
| 191 | } |
| 192 | |
| 193 | /** |
| 194 | * Set alt text for the avatar. |
| 195 | * |
| 196 | * @since 4.0.0 |
| 197 | * |
| 198 | * @param string $alt Alt text. |
| 199 | * @return $this |
| 200 | */ |
| 201 | public function alt( string $alt ): self { |
| 202 | $this->alt = $alt; |
| 203 | return $this; |
| 204 | } |
| 205 | |
| 206 | /** |
| 207 | * Set user for the avatar. |
| 208 | * |
| 209 | * @since 4.0.0 |
| 210 | * |
| 211 | * @param int|object $user User ID or object. |
| 212 | * @return $this |
| 213 | */ |
| 214 | public function user( $user ): self { |
| 215 | if ( ! $user ) { |
| 216 | return $this; |
| 217 | } |
| 218 | |
| 219 | $user_id = is_object( $user ) ? $user->ID : (int) $user; |
| 220 | $cache_key = 'avatar_component_user_data_' . $user_id; |
| 221 | $cache_data = TutorCache::get( $cache_key ); |
| 222 | |
| 223 | if ( false !== $cache_data ) { |
| 224 | if ( $cache_data['src'] ) { |
| 225 | $this->src( $cache_data['src'] ); |
| 226 | } |
| 227 | $this->type( $cache_data['type'] ); |
| 228 | $this->initials( $cache_data['initials'] ); |
| 229 | $this->alt( $cache_data['alt'] ); |
| 230 | return $this; |
| 231 | } |
| 232 | |
| 233 | if ( ! is_object( $user ) ) { |
| 234 | $user = get_userdata( $user_id ); |
| 235 | } |
| 236 | |
| 237 | if ( is_a( $user, 'WP_User' ) ) { |
| 238 | $profile_photo = get_user_meta( $user->ID, '_tutor_profile_photo', true ); |
| 239 | $avatar_src = ''; |
| 240 | |
| 241 | if ( $profile_photo ) { |
| 242 | $url = wp_get_attachment_image_url( $profile_photo, 'thumbnail' ); |
| 243 | if ( $url ) { |
| 244 | $avatar_src = $url; |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | // Generate initials. |
| 249 | $name = $user->display_name; |
| 250 | $arr = explode( ' ', trim( $name ) ); |
| 251 | $first_char = ! empty( $arr[0] ) ? mb_substr( $arr[0], 0, 1, 'UTF-8' ) : ''; |
| 252 | $second_char = ! empty( $arr[1] ) ? mb_substr( $arr[1], 0, 1, 'UTF-8' ) : ''; |
| 253 | $initials = $first_char . $second_char; |
| 254 | |
| 255 | $data = array( |
| 256 | 'src' => $avatar_src, |
| 257 | 'type' => $avatar_src ? 'image' : 'initials', |
| 258 | 'initials' => $initials, |
| 259 | 'alt' => $name, |
| 260 | ); |
| 261 | |
| 262 | // Store in cache. |
| 263 | TutorCache::set( $cache_key, $data ); |
| 264 | |
| 265 | // Apply to current instance. |
| 266 | $this->src( $data['src'] ); |
| 267 | $this->type( $data['type'] ); |
| 268 | $this->initials( $data['initials'] ); |
| 269 | $this->alt( $data['alt'] ); |
| 270 | } |
| 271 | |
| 272 | return $this; |
| 273 | } |
| 274 | |
| 275 | /** |
| 276 | * Enable or disable border. |
| 277 | * |
| 278 | * @since 4.0.0 |
| 279 | * |
| 280 | * @param bool $bordered Whether avatar has border. |
| 281 | * @return $this |
| 282 | */ |
| 283 | public function bordered( bool $bordered = true ): self { |
| 284 | $this->bordered = $bordered; |
| 285 | return $this; |
| 286 | } |
| 287 | |
| 288 | /** |
| 289 | * Get the avatar HTML. |
| 290 | * |
| 291 | * @since 4.0.0 |
| 292 | * |
| 293 | * @return string HTML output. |
| 294 | */ |
| 295 | public function get(): string { |
| 296 | $classes = array( |
| 297 | 'tutor-avatar', |
| 298 | 'tutor-avatar-' . esc_attr( $this->size ), |
| 299 | ); |
| 300 | |
| 301 | if ( $this->bordered ) { |
| 302 | $classes[] = 'tutor-avatar-border'; |
| 303 | } |
| 304 | |
| 305 | if ( ! empty( $this->shape ) ) { |
| 306 | $classes[] = 'tutor-avatar-' . esc_attr( $this->shape ); |
| 307 | } |
| 308 | |
| 309 | $this->attributes['class'] = trim( implode( ' ', $classes ) . ' ' . ( $this->attributes['class'] ?? '' ) ); |
| 310 | |
| 311 | $attributes = $this->get_attributes_string(); |
| 312 | |
| 313 | if ( 'image' === $this->type && $this->src ) { |
| 314 | $initials_html = sprintf( |
| 315 | '<span class="tutor-avatar-initials">%s</span>', |
| 316 | esc_html( $this->initials ?? '' ) |
| 317 | ); |
| 318 | |
| 319 | $image_html = sprintf( |
| 320 | '<img src="%1$s" alt="%2$s" class="tutor-avatar-image" loading="lazy" onerror="this.style.display=\'none\'" />', |
| 321 | esc_url( $this->src ), |
| 322 | esc_attr( $this->alt ?? $this->initials ?? _x( 'User Avatar', 'image alter text', 'tutor' ) ) |
| 323 | ); |
| 324 | |
| 325 | $content = $initials_html . $image_html; |
| 326 | } else { |
| 327 | $content = sprintf( |
| 328 | '<span class="tutor-avatar-initials">%s</span>', |
| 329 | esc_html( $this->initials ?? '' ) |
| 330 | ); |
| 331 | } |
| 332 | |
| 333 | $this->component_string = sprintf( |
| 334 | '<div %1$s>%2$s</div>', |
| 335 | $attributes, |
| 336 | $content |
| 337 | ); |
| 338 | |
| 339 | return $this->component_string; |
| 340 | } |
| 341 | } |
| 342 |