Created
August 5, 2025 02:01
-
-
Save mrunknown0001/a53b36dd4a7637f615a1a608c342d2a6 to your computer and use it in GitHub Desktop.
Laravel reusable customer helper functions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // Don't forget to autoload this in composer.json or create a service provider | |
| if (!function_exists('generate_username')) { | |
| /** | |
| * Generate a unique username from email or name | |
| */ | |
| function generate_username($input, $model = 'App\Models\User', $column = 'username') | |
| { | |
| // Extract base from email or clean the name | |
| if (filter_var($input, FILTER_VALIDATE_EMAIL)) { | |
| $base = explode('@', $input)[0]; | |
| } else { | |
| $base = $input; | |
| } | |
| // Clean and format | |
| $username = Str::slug(strtolower($base), ''); | |
| $original = $username; | |
| $counter = 1; | |
| // Check uniqueness | |
| while ($model::where($column, $username)->exists()) { | |
| $username = $original . $counter; | |
| $counter++; | |
| } | |
| return $username; | |
| } | |
| } | |
| if (!function_exists('mask_email')) { | |
| /** | |
| * Mask email address for privacy | |
| */ | |
| function mask_email($email, $mask_char = '*') | |
| { | |
| if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { | |
| return $email; | |
| } | |
| [$name, $domain] = explode('@', $email); | |
| if (strlen($name) <= 2) { | |
| $masked_name = $mask_char . substr($name, -1); | |
| } else { | |
| $masked_name = substr($name, 0, 2) . str_repeat($mask_char, strlen($name) - 2); | |
| } | |
| return $masked_name . '@' . $domain; | |
| } | |
| } | |
| if (!function_exists('mask_phone')) { | |
| /** | |
| * Mask phone number for privacy | |
| */ | |
| function mask_phone($phone, $visible_digits = 4) | |
| { | |
| $cleaned = preg_replace('/[^0-9]/', '', $phone); | |
| $length = strlen($cleaned); | |
| if ($length <= $visible_digits) { | |
| return $phone; | |
| } | |
| $masked = str_repeat('*', $length - $visible_digits) . substr($cleaned, -$visible_digits); | |
| // Try to maintain original formatting | |
| $formatted = $phone; | |
| $pos = 0; | |
| for ($i = 0; $i < strlen($phone); $i++) { | |
| if (is_numeric($phone[$i])) { | |
| $formatted[$i] = $masked[$pos] ?? $phone[$i]; | |
| $pos++; | |
| } | |
| } | |
| return $formatted; | |
| } | |
| } | |
| if (!function_exists('bytes_to_human')) { | |
| /** | |
| * Convert bytes to human readable format | |
| */ | |
| function bytes_to_human($bytes, $precision = 2) | |
| { | |
| $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; | |
| for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) { | |
| $bytes /= 1024; | |
| } | |
| return round($bytes, $precision) . ' ' . $units[$i]; | |
| } | |
| } | |
| if (!function_exists('percentage_of')) { | |
| /** | |
| * Calculate percentage of a value | |
| */ | |
| function percentage_of($value, $total, $precision = 2) | |
| { | |
| if ($total == 0) { | |
| return 0; | |
| } | |
| return round(($value / $total) * 100, $precision); | |
| } | |
| } | |
| if (!function_exists('is_image_url')) { | |
| /** | |
| * Check if URL points to an image | |
| */ | |
| function is_image_url($url) | |
| { | |
| $image_extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp']; | |
| $extension = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION)); | |
| return in_array($extension, $image_extensions); | |
| } | |
| } | |
| if (!function_exists('extract_urls')) { | |
| /** | |
| * Extract all URLs from text | |
| */ | |
| function extract_urls($text) | |
| { | |
| $pattern = '/https?:\/\/[^\s<>"]{2,}/i'; | |
| preg_match_all($pattern, $text, $matches); | |
| return array_unique($matches[0]); | |
| } | |
| } | |
| if (!function_exists('random_color')) { | |
| /** | |
| * Generate random hex color | |
| */ | |
| function random_color($dark = false) | |
| { | |
| if ($dark) { | |
| // Generate darker colors | |
| $r = rand(0, 128); | |
| $g = rand(0, 128); | |
| $b = rand(0, 128); | |
| } else { | |
| $r = rand(0, 255); | |
| $g = rand(0, 255); | |
| $b = rand(0, 255); | |
| } | |
| return sprintf("#%02x%02x%02x", $r, $g, $b); | |
| } | |
| } | |
| if (!function_exists('initials')) { | |
| /** | |
| * Get initials from full name | |
| */ | |
| function initials($name, $limit = 2) | |
| { | |
| $words = explode(' ', trim($name)); | |
| $initials = ''; | |
| foreach (array_slice($words, 0, $limit) as $word) { | |
| if (!empty($word)) { | |
| $initials .= strtoupper($word[0]); | |
| } | |
| } | |
| return $initials; | |
| } | |
| } | |
| if (!function_exists('is_json')) { | |
| /** | |
| * Check if string is valid JSON | |
| */ | |
| function is_json($string) | |
| { | |
| if (!is_string($string)) { | |
| return false; | |
| } | |
| json_decode($string); | |
| return json_last_error() === JSON_ERROR_NONE; | |
| } | |
| } | |
| if (!function_exists('array_filter_keys')) { | |
| /** | |
| * Filter array by keys | |
| */ | |
| function array_filter_keys($array, $keys) | |
| { | |
| return array_intersect_key($array, array_flip($keys)); | |
| } | |
| } | |
| if (!function_exists('array_except_keys')) { | |
| /** | |
| * Remove specified keys from array | |
| */ | |
| function array_except_keys($array, $keys) | |
| { | |
| return array_diff_key($array, array_flip($keys)); | |
| } | |
| } | |
| if (!function_exists('truncate_words')) { | |
| /** | |
| * Truncate text by word count instead of character count | |
| */ | |
| function truncate_words($text, $limit = 50, $end = '...') | |
| { | |
| $words = explode(' ', $text); | |
| if (count($words) <= $limit) { | |
| return $text; | |
| } | |
| return implode(' ', array_slice($words, 0, $limit)) . $end; | |
| } | |
| } | |
| if (!function_exists('currency_format')) { | |
| /** | |
| * Format currency with proper symbol and decimals | |
| */ | |
| function currency_format($amount, $currency = 'USD', $locale = 'en_US') | |
| { | |
| $formatter = new NumberFormatter($locale, NumberFormatter::CURRENCY); | |
| return $formatter->formatCurrency($amount, $currency); | |
| } | |
| } | |
| if (!function_exists('is_mobile_device')) { | |
| /** | |
| * Detect if request is from mobile device | |
| */ | |
| function is_mobile_device() | |
| { | |
| $userAgent = request()->userAgent(); | |
| return preg_match('/Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile/', $userAgent); | |
| } | |
| } | |
| if (!function_exists('generate_uuid_short')) { | |
| /** | |
| * Generate a shorter UUID-like string | |
| */ | |
| function generate_uuid_short($length = 8) | |
| { | |
| $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; | |
| $randomString = ''; | |
| for ($i = 0; $i < $length; $i++) { | |
| $randomString .= $characters[rand(0, strlen($characters) - 1)]; | |
| } | |
| return $randomString; | |
| } | |
| } | |
| if (!function_exists('sanitize_filename')) { | |
| /** | |
| * Sanitize filename for safe storage | |
| */ | |
| function sanitize_filename($filename) | |
| { | |
| // Get file extension | |
| $extension = pathinfo($filename, PATHINFO_EXTENSION); | |
| $name = pathinfo($filename, PATHINFO_FILENAME); | |
| // Remove special characters and spaces | |
| $clean_name = preg_replace('/[^a-zA-Z0-9._-]/', '_', $name); | |
| $clean_name = preg_replace('/_+/', '_', $clean_name); | |
| $clean_name = trim($clean_name, '_'); | |
| return $clean_name . ($extension ? '.' . $extension : ''); | |
| } | |
| } | |
| if (!function_exists('days_until')) { | |
| /** | |
| * Calculate days until a future date | |
| */ | |
| function days_until($date) | |
| { | |
| $target = Carbon::parse($date); | |
| $now = Carbon::now(); | |
| if ($target->isPast()) { | |
| return 0; | |
| } | |
| return $now->diffInDays($target); | |
| } | |
| } | |
| if (!function_exists('is_weekend')) { | |
| /** | |
| * Check if given date is weekend | |
| */ | |
| function is_weekend($date = null) | |
| { | |
| $carbon = $date ? Carbon::parse($date) : Carbon::now(); | |
| return $carbon->isWeekend(); | |
| } | |
| } | |
| if (!function_exists('get_client_ip')) { | |
| /** | |
| * Get real client IP address | |
| */ | |
| function get_client_ip() | |
| { | |
| $ip_keys = [ | |
| 'HTTP_CF_CONNECTING_IP', // Cloudflare | |
| 'HTTP_CLIENT_IP', | |
| 'HTTP_X_FORWARDED_FOR', | |
| 'HTTP_X_FORWARDED', | |
| 'HTTP_X_CLUSTER_CLIENT_IP', | |
| 'HTTP_FORWARDED_FOR', | |
| 'HTTP_FORWARDED', | |
| 'REMOTE_ADDR' | |
| ]; | |
| foreach ($ip_keys as $key) { | |
| if (array_key_exists($key, $_SERVER) && !empty($_SERVER[$key])) { | |
| $ips = explode(',', $_SERVER[$key]); | |
| $ip = trim($ips[0]); | |
| if (filter_var($ip, FILTER_VALIDATE_IP, | |
| FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { | |
| return $ip; | |
| } | |
| } | |
| } | |
| return request()->ip(); | |
| } | |
| } | |
| if (!function_exists('convert_timezone')) { | |
| /** | |
| * Convert datetime to different timezone | |
| */ | |
| function convert_timezone($datetime, $to_timezone, $from_timezone = 'UTC') | |
| { | |
| return Carbon::parse($datetime, $from_timezone)->setTimezone($to_timezone); | |
| } | |
| } | |
| if (!function_exists('words_count')) { | |
| /** | |
| * Count words in text (more accurate than str_word_count) | |
| */ | |
| function words_count($text) | |
| { | |
| return count(array_filter(explode(' ', strip_tags($text)))); | |
| } | |
| } | |
| if (!function_exists('reading_time')) { | |
| /** | |
| * Estimate reading time for text | |
| */ | |
| function reading_time($text, $wpm = 200) | |
| { | |
| $word_count = words_count($text); | |
| $minutes = ceil($word_count / $wpm); | |
| return $minutes . ' min read'; | |
| } | |
| } | |
| if (!function_exists('gravatar_url')) { | |
| /** | |
| * Generate Gravatar URL from email | |
| */ | |
| function gravatar_url($email, $size = 80, $default = 'mp') | |
| { | |
| $hash = md5(strtolower(trim($email))); | |
| return "https://www.gravatar.com/avatar/{$hash}?s={$size}&d={$default}"; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment