المنتج — FluxFiles

الميزات

كل ما يحتاجه مدير ملفات حديث

مصمم للمطورين الذين يحتاجون المرونة.

تخزين متعدد

محلي، AWS S3، Cloudflare R2, SFTP عبر Flysystem v3 — التبديل بالإعداد دون تغيير الكود.

تضمين في أي مكان

iframe + SDK postMessage. الواجهة المستقلة Alpine.js (بدون بناء). يعمل مع أي إطار.

مصادقة JWT + نطاقات

بادئة مسار لكل مستخدم، صلاحيات، قائمة أقراص، وضع المالك فقط — أو ابدأ من إعداد دور جاهز viewer/editor/admin.

إعدادات دور ACL الجاهزة

أصدر التوكنات من إعدادات جاهزة viewer/editor/admin/superadmin — معامل واحد يُفعّل صلاحيات وقرص ونطاق الوصول الصحيحة بدل تجميعها يدويًا.

وسم AI تلقائي

Claude / OpenAI vision — نص بديل وعنوان ووسوم تلقائية.

اقتصاص الصور

أداة اقتصاص مع نسب أبعاد مسبقة.

تحسين الصور

متغيرات WebP تلقائية — مصغّرة ومتوسطة وكبيرة.

رفع بتوقيع مسبق

المتصفح يرفع مباشرة إلى S3/R2 — صفر استهلاك على خادمك.

رفع مجزّأ

S3 multipart للملفات > 10 ميجابايت.

بحث نصي كامل

بحث مفهرس في الأسماء والعناوين والوسوم — قائم على الملفات افتراضيًا، أو قاعدة بيانات SQL خاصة بك كخيار.

تخزين البيانات الوصفية في قاعدة بيانات

وضع اختياري FLUXFILES_STORAGE_BACKEND=db — البيانات الوصفية وفهرس البحث/المجلدات وسجل التدقيق تُخزَّن في قاعدة MySQL/PostgreSQL/SQLite الخاصة بك بدل ملفات JSON. تبقى بيانات الملفات نفسها في مساحة التخزين في الحالتين.

عمليات جماعية

تحديد متعدد للنقل والنسخ والحذف والتحميل.

نقل عبر الأقراص

نسخ/نقل بين محلي ↔ S3 ↔ R2.

سلة المحذوفات

حذف قابل للاسترداد مع تنظيف تلقائي.

بيانات SEO الوصفية

عنوان، alt، تعليق، وسوم — بيانات وصفية S3 (سحابة) أو JSON جانبي (محلي). بحث نصي كامل.

الوضع الداكن

فاتح / داكن / تلقائي في الواجهة وSDK.

16 لغة

الإنجليزية افتراضياً. عيّن اللغة عبر SDK أو URL (?locale=) أو FLUXFILES_LOCALE. RTL للعربية.

سجل التدقيق

جميع إجراءات الكتابة مسجّلة.

تحديد المعدل

Token bucket لكل مستخدم لحماية API.

حصة التخزين

حدود لكل مستخدم عبر JWT claims.

دلاء BYOB

المستخدمون يضيفون S3/R2 الخاص — بيانات الاعتماد مشفّرة في JWT (AES-256-GCM).

كشف التكرار

تطابق SHA-256 يتخطى الرفع الزائد ما لم يُفرض الاستبدال.

تجديد رمز SDK

onTokenRefresh عند 401 — تجديد مجمّع، إعادة محاولة، updateToken().

Bucket Doctor

شخّص أي قرص S3/R2 — بيانات الاعتماد، القراءة/الكتابة/الحذف، presign، CORS، multipart — مع إصلاحات IAM وCORS جاهزة للّصق. أضِف حاويات BYOB في دقائق.

قرص SFTP

محرّك ثالث بعد S3/R2 — حوّل أي VPS أو استضافة إلى مدير ملفات.

محرّر الكود / الإعدادات

حرّر الملفات النصية والإعدادات (wp-config.php، .env) من المتصفح بأسلوب cPanel.

ضغط وفك ضغط

نزّل تحديدًا كملف zip أو استخرج أرشيفًا — محمي ضد zip-slip والقنابل.

علامة مائية

أضف علامة مائية نصية أو شعارًا فوريًا لحماية المعاينة — دون المساس بالأصل.

WebP + AVIF عند الطلب

قدّم أي حجم صورة كـ AVIF/WebP مخزّن مؤقتاً عبر رابط واحد (متفاوَض عبر Accept)، مع srcset متجاوب جاهز.

أذونات SFTP

غيّر أذونات يونكس (chmod) على أقراص SFTP عبر نافذة بأسلوب cPanel.

طرفية SSH

ضمّن ttyd أو gotty أو wetty الخاص بك كطرفية داخل التطبيق على أقراص SFTP عبر المطالبة المجانية terminal_pty_url — لا تأتي FluxFiles بصدفة (shell) خاصة بها.

نشر Git بنقرة واحدة

اسحب وأعد ضبط مستودع Git على خادم SFTP مباشرة من مدير الملفات — شكل ثابت، ليس صدفة عشوائية، والخطافات معطّلة افتراضيًا.

لوحة الاستخدام

اطّلع على التخزين بنظرة — الحصة مع تفصيل حسب النوع والمجلد.

معاينة الوسائط

معاينة مدمجة للصور والفيديو والصوت وPDF؛ بث آمن للوسائط المحلية الخاصة.

تثبيت سريع

جاهز خلال دقيقتين

composer require fluxfiles/fluxfiles
cp vendor/fluxfiles/fluxfiles/.env.example vendor/fluxfiles/fluxfiles/.env
# vendor/fluxfiles/fluxfiles/.env  (read only from inside the package)
# Real environment variables win over this file and are preferred in production
# (Composer may remove a vendor .env on update).
FLUXFILES_SECRET=<output of: openssl rand -hex 32>
FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com
<?php
require_once 'vendor/autoload.php';
// embed.php is not autoloaded — require it for fluxfiles_token()
require_once 'vendor/fluxfiles/fluxfiles/embed.php';

$token = fluxfiles_token([
    'user'   => 'user-123',
    'perms'  => ['read', 'write', 'delete'],
    'disks'  => ['local'],     // s3 / r2 need their own credentials in .env
    'prefix' => 'user-123/',
    'ttl'    => 3600,
]);
php vendor/bin/fluxfiles serve --port=8080
# then open http://127.0.0.1:8080/public/
composer require fluxfiles/laravel
php artisan vendor:publish --tag=fluxfiles-config
php artisan storage:link
# .env — proxy mode is the default: the API runs through your Laravel routes,
# no separate FluxFiles server is needed.
FLUXFILES_SECRET=<output of: openssl rand -hex 32>

# Only for FLUXFILES_MODE=standalone (FluxFiles on its own server):
# FLUXFILES_MODE=standalone
# FLUXFILES_ENDPOINT=https://fm.yourdomain.com
<?php
// app/FluxFiles/TenantClaims.php — REQUIRED: without a claims resolver
// <x-fluxfiles> renders "not available".
namespace App\FluxFiles;

use FluxFiles\Laravel\ClaimsResolver;
use Illuminate\Contracts\Auth\Authenticatable;

class TenantClaims implements ClaimsResolver
{
    public function resolve(Authenticatable $user): array
    {
        return [
            'prefix' => 'users/' . $user->getAuthIdentifier(),
        ];
    }
}
// config/fluxfiles.php
'claims_resolver' => \App\FluxFiles\TenantClaims::class,
// Laravel 11 / 12 — bootstrap/app.php: exclude the proxy routes from CSRF (else 419)
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: ['api/fm/*']);
})

// Laravel 10 — app/Http/Middleware/VerifyCsrfToken.php
// protected $except = ['api/fm/*'];
<x-fluxfiles disk="local" mode="picker" height="600px" />
# Not yet on WordPress.org — install the release zip:
# 1. Download fluxfiles-<version>.zip from https://github.com/thai-pc/fluxfiles/releases
# 2. Plugins -> Add New -> Upload Plugin -> Activate
# 3. Settings -> FluxFiles: set the JWT secret (>= 32 bytes) and storage
# 4. Add the shortcode (or the FluxFiles block) to any page or post:
[fluxfiles]
npm install @fluxfiles/node   # Node >= 16
// Express / Next.js route — mint a token from your JS backend (no PHP)
import { createToken } from '@fluxfiles/node';

app.get('/fluxfiles-token', (req, res) => {
    const token = createToken({
        secret: process.env.FLUXFILES_SECRET, // >= 32 bytes
        userId: req.user.id,
        perms: ['read', 'write', 'delete'],
        prefix: `users/${req.user.id}`,
        ttl: 3600,
    });
    res.json({ token });
});
pip install fluxfiles-token
# FastAPI / Django / Flask route — mint a token from your Python backend (no PHP)
import os

from fastapi import Depends
from fluxfiles_token import create_token

@app.get("/fluxfiles-token")
def fluxfiles_token(user=Depends(current_user)):
    token = create_token(
        secret=os.environ["FLUXFILES_SECRET"],  # >= 32 bytes
        user_id=user.id,
        perms=["read", "write", "delete"],
        prefix=f"users/{user.id}",
        ttl=3600,
    )
    return {"token": token}
{
  "mcpServers": {
    "fluxfiles": {
      "command": "npx",
      "args": ["-y", "@fluxfiles/mcp"],
      "env": {
        "FLUXFILES_URL": "<your FluxFiles URL>",
        "FLUXFILES_TOKEN": "<scoped JWT>"
      }
    }
  }
}
# Claude Code (Node >= 18)
claude mcp add fluxfiles -e FLUXFILES_URL=<your FluxFiles URL> -e FLUXFILES_TOKEN=<scoped JWT> -- npx -y @fluxfiles/mcp
# Read-only by default. Opt in to writes:
FLUXFILES_MCP_WRITE=1
# and to move_to_trash:
FLUXFILES_MCP_DELETE=1

لا يستطيع الوكيل الوصول إلا إلى ما يسمح به رمز JWT الخاص به — أقراصه وبادئة المسار وصلاحياته. امنحه رمزًا ضيق النطاق وللقراءة فقط.

npm install fluxfiles
<!-- or load a pinned CDN build (never @latest) -->
<script src="https://unpkg.com/fluxfiles@1.0.1/fluxfiles.js"></script>
<div id="file-picker" style="height:600px"></div>

<script>
FluxFiles.open({
    endpoint: 'https://your-fluxfiles-host',
    token: 'eyJhbGci...',   // JWT minted by your backend
    disk: 'local',
    mode: 'picker',
    container: '#file-picker',
    onSelect: function(file) {
        console.log('Selected:', file.url);
    },
    async onTokenRefresh() {
        const r = await fetch('/api/auth/refresh-fluxfiles-token');
        const { token } = await r.json();
        return token;
    }
});
</script>
npm install @fluxfiles/react
import { FluxFilesModal } from '@fluxfiles/react';

<FluxFilesModal
    open={open}
    endpoint="https://your-api.com"
    token={token}
    onSelect={(file) => console.log(file)}
    onClose={() => setOpen(false)}
/>
npm install @fluxfiles/vue
<script setup>
import { FluxFilesModal } from '@fluxfiles/vue';
</script>

<FluxFilesModal
    v-model:open="open"
    endpoint="https://your-api.com"
    :token="token"
    @select="onSelect"
    @close="open = false"
/>
docker run -p 8080:80 \
  -e FLUXFILES_SECRET="$(openssl rand -hex 32)" \
  -e FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com \
  -v fluxfiles-data:/app/packages/core/storage \
  ghcr.io/thai-pc/fluxfiles:1.1
# UI: http://localhost:8080/public/
git clone https://github.com/thai-pc/fluxfiles.git
cd fluxfiles/packages/core
composer install
cp .env.example .env
# packages/core/.env — the placeholder secret is rejected, set a real one
FLUXFILES_SECRET=<output of: openssl rand -hex 32>
FLUXFILES_ALLOWED_ORIGINS=http://localhost:8080
# print dev tokens (run from the repo root)
php packages/core/tests/generate-token.php
php -S localhost:8080 router.php

# UI: http://localhost:8080/public/index.html?token=<token>
# ?token= is dev-only — it is stripped from the URL on boot.
# Real apps pass the JWT via the SDK / postMessage, never in a URL.

عند الانتقال إلى الإنتاج: عيّن FLUXFILES_SECRET بطول 32 بايت على الأقل مع FLUXFILES_ALLOWED_ORIGINS (أو FLUXFILES_FRAME_ANCESTORS). اجعل جذر الحزمة هو document root ومنع الوصول إلى /_fluxfiles/ و.env في nginx. لا تضع رمز JWT الرئيسي في عنوان URL أبدًا — تمرّره المحوّلات عبر postMessage. DEPLOYMENT.md

يعمل مع

Laravel WordPress React / Next.js Vue / Nuxt CKEditor 4 CKEditor 5 TinyMCE Summernote Any framework

عمليات الدمج

محوّلات جاهزة للعمل مع منظومتك التقنية

تدمج المحوّلات الرسمية FluxFiles بشكل أصلي في أطر العمل والمحررات التي تستخدمها بالفعل.

استخدم CKEditor أو TinyMCE مع تخزينك الخاص، دون الحاجة إلى اشتراك في CKBox أو Tiny Drive. يضيف FluxFiles زر شريط أدوات لتصفح الملفات وإدراجها؛ وهو ليس بديلًا مكافئًا لتلك المنتجات ميزةً بميزة.

Laravel
PHP
WordPress
Plugin
React
Component
Vue / Nuxt
Component
CKEditor 4
Plugin
CKEditor 5
Plugin
TinyMCE
Plugin
Summernote
Plugin

التضمين

ضمّنه في بضعة أسطر

حمّل fluxfiles.js ومرّر رمز JWT صادرًا من الخادم، لتضع مدير ملفات كاملاً — أو نافذة اختيار ملفات — داخل أي صفحة.

<!-- npm install fluxfiles, or a pinned CDN build -->
<script src="https://unpkg.com/fluxfiles@1.0.1/fluxfiles.js"></script>

FluxFiles.open({
  endpoint: 'https://fm.example.com',
  token: 'eyJhbGci...',   // JWT from your backend
  disk: 'local',
  mode: 'picker',         // select & close
  theme: 'auto',
  onSelect(file) {
    // { url, key, name, size, disk, meta, variants }
    document.querySelector("#img").src = file.url;
  },
});
<div id="fm" style="height:600px"></div>

FluxFiles.open({
  endpoint: 'https://fm.example.com',
  token: 'eyJhbGci...',
  mode: 'browser',          // full manager, stays open
  container: '#fm',         // omit for a modal overlay
  disks: ['local', 's3', 'r2'],
});

FluxFiles.on('FM_EVENT', (e) => console.log(e.event));
FluxFiles.navigate('/photos/2024');
import { FluxFilesModal } from '@fluxfiles/react';

function Picker({ open, setOpen, token }) {
  return (
    <FluxFilesModal
      open={open}
      endpoint="https://fm.example.com"
      token={token}
      onSelect={(file) => console.log(file.url)}
      onClose={() => setOpen(false)}
    />
  );
}

تُصدَر الرموز من جهة الخادم — لا تُرسل المفتاح السري إلى المتصفح أبدًا.

لماذا FluxFiles

مصمم لما نسيه الآخرون

اسحب للمقارنة
الميزة FluxFiles elFinder Laravel-FM RichFilemanager Responsive FM
S3 + R2 + محلي + SFTP ✓ ⚠ ⚠ ⚠ ✗
تضمين في أي إطار عمل ✓ ⚠ ✗ ⚠ ✗
مصادقة JWT + نطاقات ✓ ✗ ✗ ✗ ✗
بيانات SEO الوصفية ✓ ✗ ✗ ✗ ✗
وسم AI تلقائي ✓ ✗ ✗ ✗ ✗
اقتصاص الصور ✓ ✓ ✗ ✗ ✗
رفع مجزّأ ✓ ✗ ✗ ✗ ✗
بحث نصي كامل ✓ ✗ ✗ ✗ ✗
الوضع الداكن ✓ ✗ ⚠ ✗ ✗
16 لغة ✓ ✓ ✗ ✗ ✗
PHP ≥ 8.1 ✓ ✓ ✗ ✓ ✓
صيانة نشطة ✓ ✓ ⚠ ✗ ✗
واجهة حديثة ✓ ✗ ⚠ ✗ ✗
القدرة FluxFiles Filestack Uploadcare Cloudinary Supabase Storage
مُستضاف ذاتيًا (يعمل في بنيتك) ✓ ✗ ✗ ✗ ⚠
BYOB — حاوية خاصة لكل عميل ✓ ⚠ ⚠ ✗ ✗
واجهة مدير ملفات قابلة للتضمين ✓ ✓ ✓ ⚠ ✗
مفتوح المصدر (MIT) ✓ ✗ ✗ ✗ ✓
بلا رسوم SaaS لكل تخزين / لكل رفع ✓ ✗ ✗ ✗ ⚠
تخزين متعدد (S3 / R2 / محلي) ✓ ⚠ ✗ ✗ ✗
تحديد نطاق الرمز لكل مستأجر مدمج ✓ ⚠ ⚠ ⚠ ⚠

تعكس المقارنة العروض الافتراضية المعتادة؛ كل منتج يتفوّق في مجاله. تخصّص FluxFiles هو الجمع بين القابلية للتضمين والاستضافة الذاتية وإحضار حاويتك الخاصة.

المقارنة محدّثة حتى November 2026، وهي غير رسمية — راجع مستودع GitHub للإبلاغ عن أي تصحيح.

الأسئلة الشائعة

الأسئلة المتكررة

كيف تعمل المصادقة؟
رمز JWT عديم الحالة (HS256): تُصدر الرمز من الخادم بمطالبات دقيقة (الصلاحيات، الأقراص، نطاق المسار، الحدود)، فلا يرى كل مستخدم إلا ما تسمح به.
هل يحتاج مستخدموي إلى حساب FluxFiles؟
لا. يثق FluxFiles برمز JWT الصادر من تطبيقك، فيتكامل مباشرة مع مصادقتك الحالية — دون نظام مستخدمين منفصل.
ماذا أحتاج لتشغيله؟
PHP 8.1+ (مُختبَر على 8.1–8.5) مع gd وcurl وjson وopenssl وmbstring وfileinfo (وzip لميزة الاستخراج) وComposer 2 — أو صورة Docker ‏ghcr.io/thai-pc/fluxfiles. وجّهه إلى قرص، وعيّن سرًّا والأصول المسموح بها، ثم شغّله — ويعمل على VPS صغير.
هل يمكن لمستخدمين مختلفين الحصول على صلاحيات مختلفة؟
نعم. اسكّ رمزاً بادّعاءات دقيقة (قراءة/كتابة/حذف، القرص، بادئة المسار، حدود الرفع، الامتدادات المسموحة، ownership فقط)، أو استخدم واحداً من أربعة أدوار جاهزة — viewer وeditor وadmin وsuperadmin — لتحديد نطاق الرمز بسطر واحد بدلاً من سرد كل ادّعاء يدوياً.
هل أحتاج إلى تشغيل قاعدة بيانات؟
لا. افتراضياً تعيش كل البيانات الوصفية (معلومات الملف، فهرس البحث، سجل التدقيق) بجانب ملفاتك كملفات JSON مرافقة — لا شيء إضافي لتوفيره أو نسخه احتياطياً. إن أردت الاحتفاظ بهذه السجلات في قاعدة MySQL أو PostgreSQL أو SQLite خاصة بك، يتيح لك وضع اختياري FLUXFILES_STORAGE_BACKEND=db نقلها إلى هناك؛ تبقى بايتات الملفات دائماً في مخزنك.
هل هناك أي حدود استخدام؟
النسخة الأساسية نفسها لا تفرض حدوداً صناعية — لا سقف للمستخدمين النشطين شهرياً، ولا حث إجباري على الترقية. أنت من يضبط الحدود عبر ادّعاءات JWT: حصص تخزين لكل مستخدم، وقيود حجم/امتداد الرفع، ومحدِّد معدل مدمج (60 قراءة / 10 كتابة في الدقيقة افتراضياً، قابل للتهيئة).