paradox
3 سال پیش توسط paradox مطرح شد
22 پاسخ

دانلود فایل در لاراول

سلام به همگی
من یه فروشگاه با لاراول درست کردم برای محصولات فیزیکی
الان میخام تو همین پروژه یه بخش اضافه کنم برای دانلود فایل که کاربر بعد از پرداخت بتونه فایل دانلود کنه
میخواستم بدونم دوتا سبد خرید باید درست کرد؟ ممنون میشم راهنمایی کنید

من کدهای زیر رو نوشتم برای اینکه اطلاعات فایل تو دیتابیس ذخیره بشه ولی یک ارور دارم

ارور

Call to undefined method App\User::file()

دیتابیس

        Schema::create('files', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

            $table->string('title');
            $table->text('description');
            $table->integer('price');
            $table->string('image');
            $table->string('file');
            $table->string('slug')->unique();
            $table->integer('hit');
            $table->tinyInteger('status');

            $table->integer('inventory')->default(0);
            $table->timestamps();

      });

        Schema::create('category_file' , function(Blueprint $table) {
            $table->unsignedBigInteger('category_id');
            $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
            $table->unsignedBigInteger('file_id');
            $table->foreign('file_id')->references('id')->on('files')->onDelete('cascade');
            $table->primary(['category_id' , 'file_id']);
        });

مدل یوزر

    public function files()
    {
        return $this->hasMany(File::class);
    }

مدل فایل

    public function users()
    {
        return $this->belongsToMany(User::class);
    }

کنترلر

    public function store(Request $request , File $files)
    {
       $validData = $request->validate([
            'title' => 'required',
            'description' => 'required',
            'image' => 'required',
            'file' => 'required',
            'categories' => 'required',
            'slug' => 'unique:files',
            'status' => ''

        ]);

        if (empty($request->slug)) {
            $slug = SlugService::createSlug(File::class, 'slug', $request->title);
        } else {
            $slug = SlugService::createSlug(File::class, 'slug', $request->slug);
        }
        $request->merge(['slug' => $slug]);

        $files = auth()->user()->file()->create($request->all());
        $files->categories()->sync($validData['categories']);

        alert()->success('مطلب مورد نظر با موفقیت ثبت شد' , 'با تشکر');

        return redirect(route('admin.files.index'));
    }

ثبت پرسش جدید
Muhammad
تخصص : Back-End Developer
@muhammad 3 سال پیش مطرح شد
0

سلام.

  1. شما اسم رابطه رو files گذاشتین ولی توی کدتون از file استفاده کردین.
  2. توجه کنین که وقتی ()files رو صدا بزنین، یه Relation برمی‌گرده نه یه مدل.
  3. رابطه یوزر و فایل، یک به چنده. به این دقت کردین؟

paradox
@wxyz4367 3 سال پیش مطرح شد
0

@muhammad
متاسفانه موفق نشدم و چون تازه کارم گیج شدم
اگه با کد بهم بگید چیکار کنم ممنون میشم ازتون


Muhammad
تخصص : Back-End Developer
@muhammad 3 سال پیش مطرح شد
0

اسم متد رو گذاشتین files، پس هر جا استفاده کردین باید بذارین files نه file. هرچند من حدس می‌زنم یه جای کار جدول‌هاتون می‌لنگه چون گفتین هر فایل می‌تونه متعلق به چند یوزر باشه.


paradox
@wxyz4367 3 سال پیش آپدیت شد
0

@muhammad

الان به این شکل نوشتم غلطه؟
ارور زیر برمیگردونه

Call to a member function getClientOriginalName() on null
    public function store(Request $request , File $files)
    {
       $validData = $request->validate([
            'title' => 'required',
            'description' => 'required',
            'image' => 'required',
            'file' => 'required',
            'categories' => 'required',
            'slug' => 'unique:files',
            'status' => ''

        ]);

        if (empty($request->slug)) {
            $slug = SlugService::createSlug(File::class, 'slug', $request->title);
        } else {
            $slug = SlugService::createSlug(File::class, 'slug', $request->slug);
        }
        $request->merge(['slug' => $slug]);

        $files = Storage::disk('public')->putFileAs('files' , $request->file('file') , $request->file('file')->getClientOriginalName($files))->create($request->all());
        $files->categories()->sync($validData['categories']);

        alert()->success('مطلب مورد نظر با موفقیت ثبت شد' , 'با تشکر');

        return redirect(route('admin.files.index'));
    }

الان مدل هام یعنی مشکل داره؟
تو مدل فایل اینو نباید بزارم؟


    public function users()
    {
        return $this->belongsToMany(User::class);
    }

و تو مدل یوزر اینو نباید میزاشتم؟

    public function files()
    {
        return $this->hasMany(File::class);
    }

paradox
@wxyz4367 3 سال پیش مطرح شد
0

الان یعنی جدول دیتابیس مشکل داره؟
چیکار باید کرد؟


رضا جهانگیر
تخصص : Full-Stack Developer
@rezajahangir 3 سال پیش آپدیت شد
0

سلام.
اولین نکته ای که باید در نظر داشته باشین اینه که این رابطه باید یک به چند باشه، در واقع هر کاربر میتونه تعداد زیادی فایل دانلود کنه و هر فایل مربوط به یک کاربر میشه، درسته؟ اگه جوابتون مثبت هست پس روابط در مدل هاتون باید به صورت زیر نوشته بشه.
مدل User:

public function files() {
    return $this->hasMany(File::class);
}

مدل File:

public function user() {
        return $this->belongsTo(User::class);
}

کد قسمت متد store واضح نیست و اصلا معلوم نیست میخواین چیکار کنید، روی کدتون یه توضیحی بدین تا بشه راهنمایی کرد.


paradox
@wxyz4367 3 سال پیش مطرح شد
0

@rezajahangir
بله کاملا درسته

برای فانکشن من میخام فایل با اسمی که رو خود فایل هست تو دیتابیس ذخیره بشه ولی اون ارور دارم
درکل هیچ جوره نتونستم فایل رو تو دیتابیس ذخیره کنم


رضا جهانگیر
تخصص : Full-Stack Developer
@rezajahangir 3 سال پیش مطرح شد
0

کدای مربوط به بلید این قسمت هم قرار بدین.


paradox
@wxyz4367 3 سال پیش آپدیت شد
0

@rezajahangir

    <div class="row">
        <div class="col-lg-12">
            @include('admin.layouts.errors')
            <div class="card">
                <div class="card-header">
                    <h3 class="card-title">فرم ایجاد فایل</h3>
                </div>
                <!-- /.card-header -->
                <!-- form start -->

                <form class="form-horizontal" action="{{ route('admin.files.store') }}" method="POST" enctype="multipart/form-data">
                    @csrf

                    <div class="card-body">
                        <div class="form-group">
                            <label for="inputEmail3" class="col-sm-2 control-label">نام فایل</label>
                            <input type="text" name="title" class="form-control @error('title') is-invalid @enderror" id="inputEmail3" placeholder="نام فایل را وارد کنید" value="{{ old('title') }}">
                            @error('title')
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $message }}</strong>
                            </span>
                            @enderror
                        </div>
                        <div class="form-group">
                            <label for="title" >نام مستعار :</label>
                            <div class="input-group">
                                <input type="text" class="form-control @error('slug') is-invalid @enderror" name="slug" value="{{old('slug')}}">
                            </div>
                            @error('slug')
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $message }}</strong>
                            </span>
                            @enderror
                        </div>

                        <div class="form-group">
                            <label for="description" class="col-sm-2 control-label">توضیحات</label>
                            <textarea class="form-control" name="description" id="description" cols="30" rows="10" style="min-height: 300px">{{ old('description') }}</textarea>
                        </div>

                        <div class="form-group">
                            <label for="title" > وضعیت : </label>
                            <div class="input-group">
                                <select class="form-control" name="status" >
                                    <option value="0">منتشر نشده</option>
                                    <option value="1">منتشر شده</option>
                                </select>
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="inputPassword3" class="col-sm-2 control-label">قیمت</label>
                            <input type="number" name="price" class="form-control @error('price') is-invalid @enderror" id="inputPassword3" placeholder="قیمت را وارد کنید" value="{{ old('price') }}">
                            @error('price')
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $message }}</strong>
                            </span>
                            @enderror
                        </div>
                        <div class="form-group">
                            <label for="inputPassword3" class="col-sm-2 control-label">موجودی</label>
                            <input type="number" name="inventory" class="form-control @error('inventory') is-invalid @enderror" id="inputPassword3" placeholder="موجودی را وارد کنید" value="{{ old('inventory') }}">
                            @error('inventory')
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $message }}</strong>
                            </span>
                            @enderror
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">آپلود تصویر شاخص</label>
                            <div class="input-group">
                                <input type="text" id="image_label" class="form-control" name="image">
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary" type="button" id="button-image">انتخاب</button>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">آپلود فایل</label>
                            <div class="input-group">
                                <input type="text" id="file_label" class="form-control" name="file">
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary" type="button" id="button-file">انتخاب</button>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputEmail3" class="col-sm-2 control-label">دسته بندی ها</label>
                            <select class="form-control" name="categories[]" id="categories" multiple>
                                @foreach(\Modules\Category\Entities\Category::all() as $category)
                                    <option value="{{ $category->id }}">{{ $category->name }}</option>
                                @endforeach
                            </select>
                        </div>

                    </div>
                    <!-- /.card-body -->
                    <div class="card-footer">
                        <button type="submit" class="btn btn-info">ثبت فایل</button>
                        <a href="{{ route('admin.files.index') }}" class="btn btn-default float-left">لغو</a>
                    </div>
                    <!-- /.card-footer -->
                </form>
            </div>
        </div>
    </div>

رضا جهانگیر
تخصص : Full-Stack Developer
@rezajahangir 3 سال پیش مطرح شد
0

قسمت بلید 3 تا مشکل داره.
مشکل اول اینه که input آپلود فایل رو به صورت زیر بنویسید.

<input type="file" id="file_label" class="form-control" name="file">

و اگر میخواین در این input، فقط pdf آپلود کنید باید به صورت زیر بنویسید که کاربر دیگه نتونه عکس یا فایل دیگه ای آپلود کنه:

<input type="file" id="file_label" class="form-control" name="file" accept="application/pdf>

مشکل دوم اینه که input آپلود عکس هم به صورت زیر بنویسید.

<input type="file" id="image_label" class="form-control" name="image">

و اگر فقط میخواین در این input، عکس آپلود کنید باید به صورت زیر بنویسید که کاربر دیگه نتونه نوع فایل دیگه ای آپلود کنه:

<input type="file" id="image_label" class="form-control" name="image" accept="image/*">

مشکل سوم اینه که حلقه foreach رو چرا به این صورت نوشتین؟ در صورتی که باید به صورت زیر باشه.

@foreach(\App\Models\Category::all() as $category)
    <option value="{{ $category->id }}">{{ $category->name }}</option>
@endforeach

paradox
@wxyz4367 3 سال پیش آپدیت شد
0

@rezajahangir
برای تصاویر چون از فایل منیجر و تصاویر شاخص استفاده میکنم type از نوع text گذاشتم این قسمت به درستی کار میکنه مشکلی نداره

برای foreach چون ماژول بندی کردم از اون مسیر داره میخونه category

تنها مشکلی که دارم فایل تو دیتابیس ذخیره نمیشه و اون اروری که فرستادم نمایش میده
مشکلم فقط قسمت کوئری store هست

اگه فایل پاک کنم اطلاعات تو دیتابیس ذخیره میشه ولی فایل اضافه میکنم اطلاعات ذخیره نمیشه

این خط تو فایل کنترلر ارور میگیره

        $files = Storage::disk('public')->putFileAs('files' , $request->file('file') , $request->file('file')->getClientOriginalName($files))->create($request->all());

متن ارور

Call to a member function getClientOriginalName() on null

رضا جهانگیر
تخصص : Full-Stack Developer
@rezajahangir 3 سال پیش مطرح شد
0

از ckeditor استفاده می کنید؟


paradox
@wxyz4367 3 سال پیش مطرح شد
رضا جهانگیر
تخصص : Full-Stack Developer
@rezajahangir 3 سال پیش مطرح شد
0

داخل بلیدی که فرستادین ckeditor نبود که؟
قصدتون اینه که فایلی که داخل ckeditor آپلود میشه داخل فیلد file ذخیره بشه؟


paradox
@wxyz4367 3 سال پیش مطرح شد
0

@rezajahangir
بله میخام هم یک تصویر داخل فایل منیجر ckeditor باشه
هم یک فایل حالا از نوع zip یا pdf تو قسمت دوم که نوشتم تو فایل منیجر ckeditor اپلود بشه و تو دیتابیس ذخیره شه

بلید به طور کامل میفرستم

@component('admin.layouts.content' , ['title' => 'ایجاد فایل'])
    @slot('breadcrumb')
        <li class="breadcrumb-item"><a href="/admin">پنل مدیریت</a></li>
        <li class="breadcrumb-item"><a href="{{ route('admin.files.index') }}">لیست فایل</a></li>
        <li class="breadcrumb-item active">ایجاد فایل</li>
    @endslot

    @slot('script')

        <script src="/js/ckeditor/ckeditor.js"></script>
        <script>

            CKEDITOR.replace('description', { filebrowserImageBrowseUrl: '/file-manager/ckeditor' });

            document.addEventListener("DOMContentLoaded", function() {

                document.getElementById('button-image').addEventListener('click', (event) => {
                    event.preventDefault();

                    inputId = 'image_label';
                    window.open('/file-manager/fm-button', 'fm', 'width=1400,height=800');
                });

                document.getElementById('button-file').addEventListener('click', (event) => {
                    event.preventDefault();

                    inputId = 'file_label';
                    window.open('/file-manager/fm-button', 'fm2', 'width=1400,height=800');
                });
            });

            // set file link
            let inputId = '';

            function fmSetLink($url) {
                document.getElementById(inputId).value = $url;
            }

            $('#categories').select2({
                'placeholder' : 'دسترسی مورد نظر را انتخاب کنید'
            })

        </script>
    @endslot

    <div class="row">
        <div class="col-lg-12">
            @include('admin.layouts.errors')
            <div class="card">
                <div class="card-header">
                    <h3 class="card-title">فرم ایجاد فایل</h3>
                </div>
                <!-- /.card-header -->
                <!-- form start -->

                <form class="form-horizontal" action="{{ route('admin.files.store') }}" method="POST" enctype="multipart/form-data">
                    @csrf

                    <div class="card-body">
                        <div class="form-group">
                            <label for="inputEmail3" class="col-sm-2 control-label">نام فایل</label>
                            <input type="text" name="title" class="form-control @error('title') is-invalid @enderror" id="inputEmail3" placeholder="نام فایل را وارد کنید" value="{{ old('title') }}">
                            @error('title')
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $message }}</strong>
                            </span>
                            @enderror
                        </div>
                        <div class="form-group">
                            <label for="title" >نام مستعار :</label>
                            <div class="input-group">
                                <input type="text" class="form-control @error('slug') is-invalid @enderror" name="slug" value="{{old('slug')}}">
                            </div>
                            @error('slug')
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $message }}</strong>
                            </span>
                            @enderror
                        </div>

                        <div class="form-group">
                            <label for="description" class="col-sm-2 control-label">توضیحات</label>
                            <textarea class="form-control" name="description" id="description" cols="30" rows="10" style="min-height: 300px">{{ old('description') }}</textarea>
                        </div>

                        <div class="form-group">
                            <label for="title" > وضعیت : </label>
                            <div class="input-group">
                                <select class="form-control" name="status" >
                                    <option value="0">منتشر نشده</option>
                                    <option value="1">منتشر شده</option>
                                </select>
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="inputPassword3" class="col-sm-2 control-label">قیمت</label>
                            <input type="number" name="price" class="form-control @error('price') is-invalid @enderror" id="inputPassword3" placeholder="قیمت را وارد کنید" value="{{ old('price') }}">
                            @error('price')
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $message }}</strong>
                            </span>
                            @enderror
                        </div>
                        <div class="form-group">
                            <label for="inputPassword3" class="col-sm-2 control-label">موجودی</label>
                            <input type="number" name="inventory" class="form-control @error('inventory') is-invalid @enderror" id="inputPassword3" placeholder="موجودی را وارد کنید" value="{{ old('inventory') }}">
                            @error('inventory')
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $message }}</strong>
                            </span>
                            @enderror
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">آپلود تصویر شاخص</label>
                            <div class="input-group">
                                <input type="text" id="image_label" class="form-control" name="image">
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary" type="button" id="button-image">انتخاب</button>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">آپلود فایل</label>
                            <div class="input-group">
                                <input type="text" id="file_label" class="form-control" name="file">
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary" type="button" id="button-file">انتخاب</button>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputEmail3" class="col-sm-2 control-label">دسته بندی ها</label>
                            <select class="form-control" name="categories[]" id="categories" multiple>
                                @foreach(\Modules\Category\Entities\Category::all() as $category)
                                    <option value="{{ $category->id }}">{{ $category->name }}</option>
                                @endforeach
                            </select>
                        </div>

                    </div>
                    <!-- /.card-body -->
                    <div class="card-footer">
                        <button type="submit" class="btn btn-info">ثبت فایل</button>
                        <a href="{{ route('admin.files.index') }}" class="btn btn-default float-left">لغو</a>
                    </div>
                    <!-- /.card-footer -->
                </form>
            </div>
        </div>
    </div>

@endcomponent

رضا جهانگیر
تخصص : Full-Stack Developer
@rezajahangir 3 سال پیش آپدیت شد
0

اگه از ckeditor استفاده میکنید به ترتیب مراحل زیر رو کپی کنید.
توضیحات مربوط به ورژن ۴ هست.
روت:

Route::post('/editor/upload', [EditorUploadController::class, 'upload'])->name('editor-upload');

کنترلر مربوطه:

class EditorUploadController extends Controller
{
    public function upload(Request $request) {
        $file = $request->file('upload');
        $base_name = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
        $ext = $file->getClientOriginalExtension();
        $file_name = $base_name . '_' . time() . '.' . $ext;
        $file->storeAs('images/Articles', $file_name, 'public_files');
        $function = $request->CKEditorFuncNum;
        $url = asset('images/Articles/' . $file_name);

        return response("<script>window.parent.CKEDITOR.tools.callFunction({$function}, '{$url}', 'فایل به درستی آپلود شد')</script>");
    }
}

در بلید مربوطه کد زیر رو اضافه کنید.

<script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script>
        <script>
            CKEDITOR.replace('file', {
                language: 'fa',
                filebrowserUploadUrl: '{{ route("editor-upload", ["_token" => csrf_token()]) }}',
                filebrowserUploadMethod: 'form'
            })
</script>

در آخر به مسیر زیر برید:

config\filesystems.php

و کد زیر رو اضافه کنید.

'public_files' => [
   'driver' => 'local',
   'root' => public_path(),
   'url' => env('APP_URL').'/storage',
   'visibility' => 'public',
],

متد store هم به صورت زیر بنویسید:

public function store(Request $request)
    {

        $file = $request->file('image');
        $file_name = $file->getClientOriginalName();
        $file->storeAs('images/image', $file_name, 'public_files');
        $validData = $request->validate([
            'title' => 'required',
            'description' => 'required',
            'image' => 'required',
            'file' => 'required',
            'categories' => 'required',
            'slug' => 'unique:files',
            'status' => ''

        ]);
        $validData['image'] = $file_name;
        $validData['user_id'] = auth()->user()->id;

        $article = Article::create(
            $validData
        );

        $article->categories()->attach($validData['categories']);

       alert()->success('مطلب مورد نظر با موفقیت ثبت شد' , 'با تشکر');

        return redirect(route('admin.files.index'));
    }

موفق باشید.


paradox
@wxyz4367 3 سال پیش مطرح شد
0

@rezajahangir
ممنون ازتون

store به این شکل نوشتم درسته ؟

    public function store(Request $request , File $files)
    {
       $validData = $request->validate([
            'title' => 'required',
            'description' => 'required',
            'image' => 'required',
            'file' => 'required',
            'categories' => 'required',
            'slug' => 'unique:files',
            'status' => ''

        ]);

        if (empty($request->slug)) {
            $slug = SlugService::createSlug(File::class, 'slug', $request->title);
        } else {
            $slug = SlugService::createSlug(File::class, 'slug', $request->slug);
        }
        $request->merge(['slug' => $slug]);

        $files = File::create($request->all());

        $files->categories()->sync($validData['categories']);

        alert()->success('مطلب مورد نظر با موفقیت ثبت شد' , 'با تشکر');

        return redirect(route('admin.files.index'));
    }

الان این ارور دارم

SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into `files` (`hit`, `title`, `slug`, `description`, `status`, `price`, `inventory`, `image`, `file`, `updated_at`, `created_at`) values (1, nbnb, nbnb, <p>jhjk</p>, 1, 6565, 8, http://localhost:8000/images/AI-Drug.jpg, http://localhost:8000/storage/files/file.rar, 2021-06-11 01:17:04, 2021-06-11 01:17:04))

رضا جهانگیر
تخصص : Full-Stack Developer
@rezajahangir 3 سال پیش مطرح شد
0

داخل $fillable مدل File باید 'user_id' هم اضافه کنی


paradox
@wxyz4367 3 سال پیش مطرح شد
0

@rezajahangir
اضافه کردم ولی باز همین ارور هست


محمد امیری
تخصص : backend coder
@mohammadeng3731 3 سال پیش مطرح شد
0

سلام.
نیازی به دوتا سبد ندارید و از polymorphic ها در لاراول به راحتی استفاده کنید و لذت ببرید.داکیومنت رو در بخش relation ها بخونید تمومه و دستتون میاد


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام