argument('path'); if (!file_exists($path) || !mime_content_type($path) == 'application/x-tar') { $this->error('Path does not exist or is not a tarfile'); return Command::FAILURE; } $imported = 0; $skipped = 0; $failed = 0; $tar = new \PharData($path); $tar->decompress(); foreach (new \RecursiveIteratorIterator($tar) as $entry) { $this->line("Processing {$entry->getFilename()}"); if (!$entry->isFile() || !$this->isImage($entry) || !$this->isEmoji($entry->getPathname())) { $failed++; continue; } $filename = pathinfo($entry->getFilename(), PATHINFO_FILENAME); $extension = pathinfo($entry->getFilename(), PATHINFO_EXTENSION); // Skip macOS shadow files if (str_starts_with($filename, '._')) { continue; } $shortcode = implode('', [ $this->option('prefix'), $filename, $this->option('suffix'), ]); $customEmoji = CustomEmoji::whereShortcode($shortcode)->first(); if ($customEmoji && !$this->option('overwrite')) { $skipped++; continue; } $emoji = $customEmoji ?? new CustomEmoji(); $emoji->shortcode = $shortcode; $emoji->domain = config('pixelfed.domain.app'); $emoji->disabled = $this->option('disabled'); $emoji->save(); $fileName = $emoji->id . '.' . $extension; Storage::putFileAs('public/emoji', $entry->getPathname(), $fileName); $emoji->media_path = 'emoji/' . $fileName; $emoji->save(); $imported++; Cache::forget('pf:custom_emoji'); } $this->line("Imported: {$imported}"); $this->line("Skipped: {$skipped}"); $this->line("Failed: {$failed}"); //delete file unlink(str_replace('.tar.gz', '.tar', $path)); return Command::SUCCESS; } private function isImage($file) { $image = getimagesize($file->getPathname()); return $image !== false; } private function isEmoji($filename) { $allowedMimeTypes = ['image/png', 'image/jpeg', 'image/webp']; $mimeType = mime_content_type($filename); return in_array($mimeType, $allowedMimeTypes); } }