feat: add PartnersPageSeeder for populating partner data and enhance partners view with improved layout and styling for better user experience
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Page;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PartnersPageSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* @var array<int, array{name: string, url: string, slug: string, simple_icon?: string}>
|
||||
*/
|
||||
protected array $partners = [
|
||||
// Türkiye — domain, hosting ve dijital altyapı
|
||||
['name' => 'Turhost', 'url' => 'https://www.turhost.com', 'slug' => 'turhost'],
|
||||
['name' => 'Natro', 'url' => 'https://www.natro.com', 'slug' => 'natro'],
|
||||
['name' => 'İsimtescil', 'url' => 'https://www.isimtescil.net', 'slug' => 'isimtescil'],
|
||||
['name' => 'Radore', 'url' => 'https://www.radore.com', 'slug' => 'radore'],
|
||||
['name' => 'Nic.tr', 'url' => 'https://www.nic.tr', 'slug' => 'nic-tr'],
|
||||
['name' => 'Türk Telekom', 'url' => 'https://www.turktelekom.com.tr', 'slug' => 'turk-telekom'],
|
||||
['name' => 'Bulutistan', 'url' => 'https://www.bulutistan.com', 'slug' => 'bulutistan'],
|
||||
['name' => 'Güzel Hosting', 'url' => 'https://www.guzel.net.tr', 'slug' => 'guzel-hosting'],
|
||||
['name' => 'DorukNet', 'url' => 'https://www.doruk.net', 'slug' => 'doruknet'],
|
||||
|
||||
// Global teknoloji ortakları
|
||||
['name' => 'Google', 'url' => 'https://www.google.com', 'slug' => 'google', 'simple_icon' => 'google'],
|
||||
['name' => 'Google Gemini', 'url' => 'https://gemini.google.com', 'slug' => 'google-gemini', 'simple_icon' => 'googlegemini'],
|
||||
['name' => 'Apple', 'url' => 'https://www.apple.com', 'slug' => 'apple', 'simple_icon' => 'apple'],
|
||||
['name' => 'Meta', 'url' => 'https://www.meta.com', 'slug' => 'meta', 'simple_icon' => 'meta'],
|
||||
['name' => 'Cursor', 'url' => 'https://www.cursor.com', 'slug' => 'cursor'],
|
||||
['name' => 'Microsoft Azure', 'url' => 'https://azure.microsoft.com', 'slug' => 'microsoft-azure', 'simple_icon' => 'microsoftazure'],
|
||||
['name' => 'Cloudflare', 'url' => 'https://www.cloudflare.com', 'slug' => 'cloudflare', 'simple_icon' => 'cloudflare'],
|
||||
];
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$author = User::query()->first();
|
||||
if (!$author) {
|
||||
$this->command?->warn('Kullanıcı bulunamadı, seeder atlandı.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$corporate = Page::query()->where('slug', '=', 'kurumsal')->first();
|
||||
|
||||
Storage::disk('public')->makeDirectory('partners', 0755, true);
|
||||
|
||||
$partnerRecords = [];
|
||||
|
||||
foreach ($this->partners as $partner) {
|
||||
$logoPath = $this->downloadLogo($partner);
|
||||
|
||||
if (!$logoPath) {
|
||||
$this->command?->warn("Logo indirilemedi: {$partner['name']}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$partnerRecords[] = [
|
||||
'name' => $partner['name'],
|
||||
'url' => $partner['url'],
|
||||
'logo' => $logoPath,
|
||||
];
|
||||
|
||||
$this->command?->info("✓ {$partner['name']}");
|
||||
}
|
||||
|
||||
Page::updateOrCreate(
|
||||
['slug' => 'cozum-ortaklari'],
|
||||
[
|
||||
'author_id' => $author->id,
|
||||
'parent_id' => $corporate?->id,
|
||||
'title' => 'Çözüm Ortakları',
|
||||
'excerpt' => 'Türkiye\'nin önde gelen domain, hosting ve dijital altyapı sağlayıcıları ile Google, Apple, Meta, Cursor ve Gemini gibi global teknoloji liderleriyle güçlü bir ekosistem.',
|
||||
'content' => '<p>Güçlü çözüm ortaklıklarımız sayesinde müşterilerimize daha hızlı, daha yenilikçi ve daha sürdürülebilir çözümler sunuyoruz. Alan adı ve hosting hizmetlerinden bulut altyapısına, yapay zeka platformlarından kurumsal yazılım ekosistemlerine kadar geniş bir partner ağıyla projelerinizi güvenle hayata geçiriyoruz.</p>',
|
||||
'template' => 'corporate.partners',
|
||||
'status' => 'published',
|
||||
'is_homepage' => false,
|
||||
'show_in_menu' => true,
|
||||
'sort_order' => 7,
|
||||
'published_at' => now(),
|
||||
'meta_title' => 'Çözüm Ortaklarımız | Trunçgil',
|
||||
'meta_description' => 'Domain, hosting, veri merkezi ve bulut altyapısı ortaklarımız ile Google, Apple, Meta, Cursor ve Gemini gibi global teknoloji iş birliklerimiz.',
|
||||
'data' => [
|
||||
'partners' => $partnerRecords,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->command?->info('✅ ' . count($partnerRecords) . ' çözüm ortağı veritabanına kaydedildi.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{name: string, url: string, slug: string, simple_icon?: string} $partner
|
||||
*/
|
||||
protected function downloadLogo(array $partner): ?string
|
||||
{
|
||||
$filename = 'partners/' . $partner['slug'] . '.png';
|
||||
$fullPath = Storage::disk('public')->path($filename);
|
||||
|
||||
$domain = parse_url($partner['url'], PHP_URL_HOST);
|
||||
$domain = $domain ? preg_replace('/^www\./', '', $domain) : null;
|
||||
|
||||
$sources = [];
|
||||
|
||||
if (!empty($partner['simple_icon'])) {
|
||||
$sources[] = 'https://cdn.simpleicons.org/' . $partner['simple_icon'];
|
||||
}
|
||||
|
||||
if ($domain) {
|
||||
$sources[] = 'https://logo.clearbit.com/' . $domain;
|
||||
$sources[] = 'https://www.google.com/s2/favicons?domain=' . $domain . '&sz=128';
|
||||
}
|
||||
|
||||
foreach ($sources as $source) {
|
||||
try {
|
||||
$response = Http::timeout(15)
|
||||
->withHeaders(['User-Agent' => 'Mozilla/5.0 (compatible; TruncgilSeeder/1.0)'])
|
||||
->get($source);
|
||||
|
||||
if (!$response->successful() || strlen($response->body()) < 200) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$body = $response->body();
|
||||
$image = @imagecreatefromstring($body);
|
||||
|
||||
if ($image === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$width = imagesx($image);
|
||||
$height = imagesy($image);
|
||||
|
||||
$canvas = imagecreatetruecolor(256, 100);
|
||||
imagealphablending($canvas, false);
|
||||
imagesavealpha($canvas, true);
|
||||
$transparent = imagecolorallocatealpha($canvas, 255, 255, 255, 127);
|
||||
imagefill($canvas, 0, 0, $transparent);
|
||||
imagealphablending($canvas, true);
|
||||
|
||||
$scale = min(220 / max($width, 1), 72 / max($height, 1));
|
||||
$newWidth = (int) max(1, round($width * $scale));
|
||||
$newHeight = (int) max(1, round($height * $scale));
|
||||
$offsetX = (int) ((256 - $newWidth) / 2);
|
||||
$offsetY = (int) ((100 - $newHeight) / 2);
|
||||
|
||||
imagecopyresampled($canvas, $image, $offsetX, $offsetY, 0, 0, $newWidth, $newHeight, $width, $height);
|
||||
imagepng($canvas, $fullPath, 8);
|
||||
|
||||
imagedestroy($image);
|
||||
imagedestroy($canvas);
|
||||
|
||||
return $filename;
|
||||
} catch (\Throwable) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->generatePlaceholder($partner, $fullPath) ? $filename : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{name: string, url: string, slug: string} $partner
|
||||
*/
|
||||
protected function generatePlaceholder(array $partner, string $fullPath): bool
|
||||
{
|
||||
$canvas = imagecreatetruecolor(256, 100);
|
||||
imagealphablending($canvas, false);
|
||||
imagesavealpha($canvas, true);
|
||||
|
||||
$bg = imagecolorallocatealpha($canvas, 248, 250, 252, 0);
|
||||
imagefill($canvas, 0, 0, $bg);
|
||||
|
||||
$textColor = imagecolorallocate($canvas, 30, 41, 59);
|
||||
$initials = Str::upper(Str::substr(Str::before($partner['name'], ' '), 0, 2));
|
||||
|
||||
$font = 5;
|
||||
$textWidth = imagefontwidth($font) * strlen($initials);
|
||||
$textHeight = imagefontheight($font);
|
||||
imagestring($canvas, $font, (int) ((256 - $textWidth) / 2), (int) ((100 - $textHeight) / 2), $initials, $textColor);
|
||||
|
||||
$result = imagepng($canvas, $fullPath, 8);
|
||||
imagedestroy($canvas);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user