PHP code example of entoknakal / file-picker

1. Go to this page and download the library: Download entoknakal/file-picker library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

entoknakal / file-picker example snippets




namespace App\NativeComponents;

use entoknakal\FilePicker\Events\FilePickerCopy;
use entoknakal\FilePicker\Facades\FilePicker;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;
use Native\Mobile\Edge\NativeComponent;

class PickFile extends NativeComponent
{
    public array $allowedTypes = ['application/pdf', 'photos'];
    
    // Set to true for multiple selection. Default value is false.
    public bool $multiple = false; 

    public array $selectedFiles = [];

    // First file metadata shortcuts (for single file compatibility)
    public ?string $filePath = null;
    public ?string $fileName = null;
    public ?string $mimeType = null;
    public ?string $fileSize = null;
    public ?string $extension = null;
    public ?string $imagesFilePath = null;

    public ?string $allowedTypesString = null;

    public ?bool $status = null; // Default state is null
    public ?string $errorMessage = null;

    public function selectFile(): void
    {
        $this->errorMessage = null;
        $this->status = null;
        $this->selectedFiles = [];

        try {
            $fileData = FilePicker::open([
                'types' => $this->allowedTypes,
                'multiple' => $this->multiple,
            ]);

            if (empty($fileData)) {
                return;
            }

            if (isset($fileData['error'])) {
                $this->status = false;
                $this->errorMessage = $fileData['error'];
                return;
            }

            // Normalize payload structure
            if (isset($fileData['files']) && is_array($fileData['files'])) {
                $items = $fileData['files'];
            } elseif (isset($fileData) && is_array($fileData)) {
                $items = $fileData;
            } else {
                $items = [$fileData];
            }

            $disk = Storage::disk('mobile_public');
            $this->allowedTypesString = implode(', ', $this->allowedTypes);

            foreach ($items as $index => $item) {
                if (empty($item['path']) || !file_exists($item['path'])) {
                    continue;
                }

                $originalName = $item['name'] ?? ('file_' . time());
                $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
                $baseName = pathinfo($originalName, PATHINFO_FILENAME);
                $fileName = $baseName . ($ext ? '.' . $ext : '');

                // Stream copy from temporary cache
                FilePickerCopy::dispatch(
                    $item['path'],
                    $fileName,
                    'ztssUpload',
                    'mobile_public'
                );

                $relativePath = 'ztssUpload/' . $fileName;
                $finalPath = $disk->path($relativePath);

                if (!file_exists($finalPath)) {
                    if (!$disk->exists('ztssUpload')) {
                        $disk->makeDirectory('ztssUpload');
                    }
                    copy($item['path'], $finalPath);
                    @unlink($item['path']);
                }

                if (!file_exists($finalPath)) {
                    continue;
                }

                $mimeType = $item['mime_type'] ?? null;
                $isImage = in_array($ext, ['jpg', 'jpeg', 'png', 'webp', 'gif'])
                    || ($mimeType && str_starts_with($mimeType, 'image/'));

                $fileSrc = str_starts_with($finalPath, 'file://') ? $finalPath : 'file://' . $finalPath;

                $this->selectedFiles[] = [
                    'name' => $fileName,
                    'path' => $finalPath,
                    'file_src' => $fileSrc,
                    'extension' => $ext,
                    'mime_type' => $mimeType,
                    'size' => $item['size'] ?? (file_exists($finalPath) ? filesize($finalPath) : 0),
                    'is_image' => $isImage,
                ];
            }

            if (!empty($this->selectedFiles)) {
                $this->status = true;
                $first = $this->selectedFiles[0];
                $this->fileName = $first['name'];
                $this->filePath = $first['path'];
                $this->extension = $first['extension'];
                $this->mimeType = $first['mime_type'];
                $this->fileSize = (string) $first['size'];
                $this->imagesFilePath = $first['file_src'];
            } else {
                $this->status = false;
                $this->errorMessage = 'Failed to save files into the ztssUpload directory.';
            }
        } catch (\Throwable $e) {
            $this->status = false;
            $this->filePath = null;
            $this->selectedFiles = [];
            $this->errorMessage = $e->getMessage();
        }
    }

    public function render(): View
    {
        return view('native.pick-file');
    }
}

use entoknakal\FilePicker\Events\FilePickerCopy;

FilePickerCopy::dispatch(
    sourcePath: $item['path'],       // Absolute Android system cache temporary path
    originalName: $fileName,         // Desired target filename (e.g., "document.pdf")
    targetFolder: 'ztssUpload',      // Subfolder directory name
    disk: 'mobile_public'            // Configured Laravel Storage Disk name
);

  public array $allowedTypes = ['photos']; // Resolves to image/*
  

  public array $allowedTypes = ['image/png', 'application/pdf', 'application/octet-stream']; 
  
bash
   php artisan vendor:publish --tag=nativephp-plugins-provider
   
bash
   php artisan native:plugin:register entoknakal/file-picker
   
bash
   php artisan native:plugin:list
   
html
<native:scroll-view fill class="bg-theme-background">
    <column class="gap-2 mt-6 w-full">
        <text class="text-md font-semibold text-theme-on-background">Penguji Plugin FilePicker</text>

        <text class="text-xs text-zinc-500 dark:text-zinc-400">
            Multiple Mode: {{ $multiple ? 'Enabled (Select Multiple Files)' : 'Disabled (Select Single File)' }}
        </text>

        <native:button label="Open File Manager" variant="secondary" @press="selectFile" />

        @if($status !== null)
            <text class="text-md font-semibold {{ $status ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400' }}">
                Status: {{ $status ? 'Succeed' : 'Failed' }}
            </text>
        @endif

        @if($status === true && !empty($selectedFiles))
            <vstack class="gap-3 mt-2 w-full">
                <text class="font-bold text-zinc-900 dark:text-white">
                    Total Files Selected: {{ count($selectedFiles) }}
                </text>

                @foreach($selectedFiles as $index => $file)
                    <vstack class="p-4 bg-zinc-100 dark:bg-zinc-800 rounded-lg gap-1 w-full border border-zinc-200 dark:border-zinc-700">
                        <text class="font-bold text-zinc-900 dark:text-white">
                            File #{{ $index + 1 }}: {{ $file['name'] }}
                        </text>
                        <text class="text-sm text-zinc-700 dark:text-zinc-300">Allowed Formats: {{ $allowedTypesString }}</text>
                        <text class="text-sm text-zinc-700 dark:text-zinc-300">Extension: .{{ $file['extension'] }}</text>
                        <text class="text-xs text-zinc-500 dark:text-zinc-400">Path: {{ $file['path'] }}</text>
                        <text class="text-xs text-zinc-500 dark:text-zinc-400">Mime Type: {{ $file['mime_type'] }}</text>
                        <text class="text-xs text-zinc-500 dark:text-zinc-400">
                            Size: {{ number_format($file['size'] / 1024, 2) }} KB
                        </text>

                        @if($file['is_image'])
                            <column class="gap-1 py-2">
                                <native:image :src="$file['file_src']" :fit="1" class="rounded-xl w-full h-48" />
                            </column>
                        @endif
                    </vstack>
                @endforeach
            </vstack>
        @endif

        @if($status === false && $errorMessage)
            <vstack class="p-4 bg-red-50 dark:bg-red-950/30 rounded-lg mt-2 gap-2 w-full border border-red-200 dark:border-red-900">
                <hstack class="gap-2 items-center">
                    <text class="text-md font-bold text-red-600 dark:text-red-400">⚠️ Akses Ditolak / Gagal</text>
                </hstack>