HEX
Server: LiteSpeed
System: Linux my-kul-web2054.main-hosting.eu 5.14.0-611.13.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 11 04:57:59 EST 2025 x86_64
User: u665686179 (665686179)
PHP: 8.2.30
Disabled: system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
Upload Files
File: /home/u665686179/domains/dealkr.com/public_html/app/Services/FileManagerService.php
<?php

namespace App\Services;

use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Madnest\Madzipper\Facades\Madzipper;
use ZipArchive;

class FileManagerService
{

    public function uploadFileAndImages(object $request): bool
    {
        $storage = $request['storage'];
        if ($request->hasfile('images')) {
            $images = $request->file('images');
            foreach ($images as $image) {
                $name = $image->getClientOriginalName();
                if ($storage == 's3') {
                    Storage::disk($storage)->putFileAs($request->path, $image, $name);
                } else {
                    $name = Str::slug(pathinfo($image->getClientOriginalName(), PATHINFO_FILENAME)) . '.' . $image->getClientOriginalExtension();
                    $path = $request['path'] == 'public' ? $name : ($request['path'] . '/' . $name);
                    Storage::disk('public')->put($path, file_get_contents($image));
                }
            }
        }

        if ($request->hasfile('file')) {
            $file = $request->file('file');
            if ($storage === 's3') {
                $zip = new ZipArchive;
                if ($zip->open($file->path()) === true) {
                    for ($i = 0; $i < $zip->numFiles; $i++) {
                        $stat = $zip->statIndex($i);

                        if (!$stat['name'] || $this->shouldSkip($stat['name'])) {
                            continue;
                        }
                        $filename = $stat['name'];
                        $fileContent = $zip->getFromIndex($i);
                        $format = pathinfo($filename, PATHINFO_EXTENSION);
                        $imageName = Carbon::now()->toDateString() . "-" . uniqid() . "." . $format;
                        $s3 = Storage::disk('s3');
                        $s3Path = $request->path . '/' . $imageName;
                        $s3->put($s3Path, $fileContent, 'public');
                    }
                    $zip->close();
                }
            } else {
                $zip = new ZipArchive();
                if ($zip->open($request->file('file')) === TRUE) {
                    $genFolderName = explode('/', $zip->getNameIndex(0))[0];
                    if ($genFolderName === "__MACOSX") {
                        for ($i = 0; $i < $zip->numFiles; $i++) {
                            if (strpos($zip->getNameIndex($i), "__MACOSX") === false) {
                                break;
                            }
                        }
                    }

                    $tempPath = storage_path('app/temp-zip-' . Str::random(10));
                    File::makeDirectory($tempPath);
                    $zip->extractTo($tempPath);
                    $zip->close();
                    if (File::exists($tempPath . '/__MACOSX')) {
                        File::deleteDirectory($tempPath . '/__MACOSX');
                    }

                    $destination = $request['path'] === 'public'
                        ? storage_path('app/public')
                        : storage_path('app/public/' . $request['path']);
                    $this->copyAndTouch($tempPath, $destination);

                    File::deleteDirectory($tempPath);
                    cacheRemoveByType(type: 'file_manager');
                } else {
                    return false;
                }
            }
        }
        return true;
    }

    private function copyAndTouch($src, $dst): void
    {
        $files = File::allFiles($src);
        foreach ($files as $file) {
            $relativePath = Str::after($file->getPathname(), $src);
            $destinationPath = $dst . $relativePath;
            File::ensureDirectoryExists(dirname($destinationPath));
            File::copy($file->getPathname(), $destinationPath);
            touch($destinationPath);
        }
    }


    private function getFileName($path): bool|string
    {
        $temp = explode('/', $path);
        return end($temp);
    }

    private function getFileExtension($name): bool|string
    {
        $temp = explode('.', $name);
        return end($temp);
    }

    private function getPathForDatabase($fullPath): bool|string
    {
        $temp = explode('/', $fullPath, 3);
        return end($temp);
    }

    public function formatFileAndFolders($files, $type): array
    {
        $data = [];
        foreach ($files as $file) {
            $name = $this->getFileName($file);
            $ext = $this->getFileExtension($name);
            if ($type == 'file' && in_array($ext, ['jpg', 'png', 'jpeg', 'gif', 'bmp', 'tif', 'tiff', 'webp', 'svg'])) {
                $data[] = [
                    'name' => $name,
                    'path' => $file,
                    'db_path' => $this->getPathForDatabase($file),
                    'type' => $type,
                ];
            } else if ($type == 'folder') {
                $data[] = [
                    'name' => $name,
                    'path' => $file,
                    'db_path' => $this->getPathForDatabase($file),
                    'type' => $type,
                    'totalFiles' => count(Storage::disk($request['storage'] ?? 'public')->files($this->getPathForDatabase($file))),
                ];
            }
        }
        return $data;
    }

    public static function shouldSkip($filename): bool
    {
        $skipFiles = [
            '__MACOSX/', // Skip macOS metadata files
            '.DS_Store', // Skip .DS_Store files
            'Thumbs.db', // Skip Thumbs.db files (Windows)
            // Add more conditions as needed
        ];

        foreach ($skipFiles as $skipFile) {
            if (strpos($filename, $skipFile) === 0) {
                return true;
            }
        }

        return false;
    }


    public static function getFoldersWithInfo(string|null $targetFolder, string|null $storage = 'public'): array
    {
        $currentFolder = Storage::disk($storage)->Directories($targetFolder);

        $folders = [];
        foreach ($currentFolder as $folder) {
            $name = explode('/', $folder);
            $readableName = str_ireplace(['\'', '"', ',', ';', '<', '>', '?', '“', '”', '_', '-'], ' ', preg_replace('/\s\s+/', ' ', end($name)));

            $currentFolderFiles = Storage::disk($storage)->files($folder);
            $currentFolderFiles = array_filter($currentFolderFiles, function ($file) {
                return basename($file) !== '.DS_Store' && basename($file) !== 'Thumbs.db';
            });

            $totalFileSize = 0;
            foreach ($currentFolderFiles as $file) {
                $totalFileSize += Storage::disk($storage)->size($file);
            }

            $folders[] = [
                'name' => $readableName,
                'path' => $folder,
                'encodePath' => base64_encode($folder),
                'lastPath' => str_replace(end($name), '', $folder),
                'type' => 'Folder',
                'totalFiles' => count($currentFolderFiles) ?? 0,
                'size' => self::getAdvancedFileFormatSize($totalFileSize),
                'allFolders' => self::getFoldersWithInfo($folder),
                'totalFolders' => count(Storage::disk($storage)->Directories($folder)),
            ];
        }

        usort($folders, function ($a, $b) {
            return strcmp($a['name'], $b['name']);
        });

        return $folders;
    }

    public static function getAllFilesWithInfo($targetFolder = null, string|null $storage = 'public'): array
    {
        $targetFolder = $targetFolder == 'public' ? '/' : $targetFolder;
        $currentFolderFiles = Storage::disk($storage)->files($targetFolder);

        $currentFolderFiles = array_filter($currentFolderFiles, function ($file) {
            return basename($file) !== '.DS_Store' && basename($file) !== 'Thumbs.db';
        });

        $AllDirectories = Storage::disk($storage)->directories($targetFolder);
        $filesWithInfo = self::getCurrentFolderFilesWithInfo(targetFolder: $targetFolder);
        $foldersWithInfo = self::getFoldersWithInfo(targetFolder: $targetFolder);

        $totalFileSize = 0;
        foreach ($currentFolderFiles as $file) {
            $totalFileSize += Storage::disk($storage)->size($file);
        }

        return [
            'size' => self::getAdvancedFileFormatSize($totalFileSize),
            'files' => $filesWithInfo,
            'folders' => $foldersWithInfo,
            'totalFiles' => count($currentFolderFiles),
            'totalDirectories' => count($AllDirectories),
        ];
    }

    public static function getCurrentFolderFilesWithInfo($targetFolder = null, $storage = 'public'): array
    {
        $filePaths = Storage::disk($storage)->files($targetFolder);
        $FilesWithInfo = [];
        foreach ($filePaths as $file) {
            $type = explode('/', Storage::disk($storage)->mimeType($file))[0];
            $name = explode('/', $file);
            $dbPath = explode('/', $file, 2);

            if (!(empty(end($name)) || self::shouldSkip(end($name)))) {
                $FilesWithInfo[] = [
                    'name' => end($name),
                    'short_name' => self::getFileMinifyString(end($name)),
                    'driver' => $storage,
                    'path' => $file,
                    'db_path' => end($dbPath),
                    'encodePath' => Crypt::encryptString($file),
                    'type' => $type,
                    'size' => self::getAdvancedFileFormatSize(Storage::disk($storage)->size($file)),
                    'sizeInInteger' => Storage::disk($storage)->size($file),
                    'extension' => pathinfo($file, PATHINFO_EXTENSION),
                ];
            }
        }
        usort($FilesWithInfo, function ($a, $b) {
            return strcmp($a['name'], $b['name']);
        });
        return $FilesWithInfo;
    }

    public static function getFileMinifyString($inputString, $prefixLength = 15, $suffixLength = 8, $ellipsis = '.....')
    {
        if (strlen($inputString) <= $prefixLength + $suffixLength) {
            return $inputString;
        }
        $prefix = substr($inputString, 0, $prefixLength);
        $suffix = substr($inputString, -$suffixLength);
        return $prefix . $ellipsis . $suffix;
    }

    public static function getAdvancedFileFormatSize($size = 0): string
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];

        $unitIndex = 0;
        while ($size >= 1024 && $unitIndex < count($units) - 1) {
            $size /= 1024;
            $unitIndex++;
        }

        return round($size, 2) . ' ' . $units[$unitIndex];
    }

    public static function getFileManagerBreadcrumb($path): array
    {
        $decodedPath = trim($path, '/');
        $breadcrumb = [];

        $segments = explode('/', $decodedPath);
        $segments = in_array('public', $segments) ? $segments : array_merge(['public'], $segments);

        $relativePath = '';
        foreach ($segments as $index => $segment) {
            if ($segment === 'public') {
                $decodePath = '/';
                $relativePath = ''; // reset relative for others
            } else {
                $relativePath .= ($relativePath === '' ? '' : '/') . $segment;
                $decodePath = $relativePath;
            }
            if (!empty($decodePath)) {
                $breadcrumb[] = [
                    'name' => $segment === 'public'
                        ? (getDefaultLanguage() == 'en' ? 'Public' : translate('Main'))
                        : ucwords(str_replace(['-', '_'], ' ', $segment)),
                    'path' => base64_encode($decodePath),
                    'decode_path' => $decodePath,
                ];
            }
        }

        return $breadcrumb;
    }

    public function getRecentFiles(string $storage = 'public'): array
    {
        $cacheKey = $storage == 's3' ? 'cache_for_recent_file_list_s3' : 'cache_for_recent_file_list_public';
        return Cache::remember($cacheKey, CACHE_FOR_3_HOURS, function () use ($storage) {
            $recentFilesPath = Storage::disk($storage)->allFiles('/');
            usort($recentFilesPath, function ($a, $b) use ($storage) {
                $timeA = Storage::disk($storage)->lastModified($a);
                $timeB = Storage::disk($storage)->lastModified($b);
                return $timeB - $timeA;
            });
            $recentFilesPath = array_slice($recentFilesPath, 0, 10);

            $FilesWithInfo = [];
            foreach ($recentFilesPath as $file) {
                $type = explode('/', Storage::disk($storage)->mimeType($file))[0];
                $name = explode('/', $file);
                $dbPath = explode('/', $file, 2);

                if (!(empty(end($name)) || self::shouldSkip(end($name)))) {
                    $FilesWithInfo[] = [
                        'name' => end($name),
                        'short_name' => self::getFileMinifyString(end($name)),
                        'driver' => $storage,
                        'path' => $file,
                        'db_path' => end($dbPath),
                        'encodePath' => Crypt::encryptString($file),
                        'type' => $type,
                        'size' => self::getAdvancedFileFormatSize(Storage::disk($storage)->size($file)),
                        'sizeInInteger' => Storage::disk($storage)->size($file),
                        'extension' => pathinfo($file, PATHINFO_EXTENSION),
                        'last_modified' => Carbon::parse(date('Y-m-d H:i:s', Storage::disk($storage)->lastModified($file)))
                    ];
                }
            }
            return $FilesWithInfo;
        });
    }
}