Armin Rahmati
4 سال پیش توسط Armin Rahmati مطرح شد
11 پاسخ

اضافه کردن تصویر در ویرایش اطلاعات

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

public function store(Request $request)
    {
        Log::debug('Some message.');
        $year = Carbon::now()->year;
        $destinationPath = "uploads/estates/{$year}/";
        $images = array();
        if ($files = $request->file('image1')) {
            foreach ($files as $file) {
                $filename = $file->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $file->move($destinationPath, $rnd . $filename);
                $images[] = $rnd . $filename;
            }
        }
        if ($files = $request->file('image2')) {
            foreach ($files as $file) {
                $filename = $file->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $file->move($destinationPath, $rnd . $filename);
                $images[] = $rnd . $filename;
            }
        }
        if ($files = $request->file('image3')) {
            foreach ($files as $file) {
                $filename = $file->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $file->move($destinationPath, $rnd . $filename);
                $images[] = $rnd . $filename;
            }
        }
        $allImages = implode("|", $images);
        // Apartment && Office - Sell
        if ($request->input('estateType') == 'apartment' && $request->input('type') == 'sell' ||
            $request->input('estateType') == 'office' && $request->input('type') == 'sell') {

            if ($request->input('rent') == null && $request->input('deposit') == null) {
                if (! $request->image1 && ! $request->image2 && ! $request->image3) {

                    auth()->user()->estate()->create(array_merge($request->all() , $images));
                }else
                    auth()->user()->estate()->create(array_merge($request->all() , ['images' => $allImages]));
            }
            return redirect('/UserPanel');
        }
}

همچنین هر کاربر میتواند برای ملک خود 3 عکس وارد کند.

حالا مشکلی که وجود داره اینه که شما فرض کنید زمانی که کاربر ملک رو ثبت کرده 1 عکس فقط وارد کرده و حالا میخواد هنگام ویرایش 2 عکس دیگه اضافه کنه، زمانی که وارد فرم ویرایش میشم اون عکسی که زمان ثبت ملک وارد کرده نمایش داده میشه ولی وقتی 2 عکس دیگه اضافه میکنم اون عکسی که زمان ثبت ملک وارد کرده رو از دیتابیس حذف میکنه و 2 عکس جدید رو قرار میده ولی من میخوام این 2 عکس به اون 1 عکس اضافه بشه.

اینم فانکشن update

public function update(Request $request, int $index)
    {
        $estate = Estate::where('id', $index)->first();
        $year = Carbon::now()->year;
        $destinationPath = "uploads/estates/{$year}/";
        $images = array();
        if ($files = $request->file('image1')) {
            foreach ($files as $file) {
                $filename = $file->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $file->move($destinationPath, $rnd . $filename);
                $images[] = $rnd . $filename;
            }
        }
        if ($files = $request->file('image2')) {
            foreach ($files as $file) {
                $filename = $file->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $file->move($destinationPath, $rnd . $filename);
                $images[] = $rnd . $filename;
            }
        }
        if ($files = $request->file('image3')) {
            foreach ($files as $file) {
                $filename = $file->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $file->move($destinationPath, $rnd . $filename);
                $images[] = $rnd . $filename;
            }
        }
        $allImages = implode("|", $images);
        // Apartment && Office - Sell
        if ($request->input('estateType') == 'apartment' && $request->input('type') == 'sell' ||
            $request->input('estateType') == 'office' && $request->input('type') == 'sell') {

            if ($request->input('rent') == null && $request->input('deposit') == null) {
                if (! $request->image1 && ! $request->image2 && ! $request->image3) {

                    $estate->update(array_merge($request->all() , $images));
                }else if (! $request->image1 || ! $request->image2 || ! $request->image3)
                    $estate->update(array_merge($request->all() , ['images' => $allImages]));
            }
            return redirect('/UserPanel');
        }
}

ممنون میشم راهنمایی کنید.


ثبت پرسش جدید
حسین شیری نژاد
تخصص : programmer
@hosseinshirinegad98 4 سال پیش مطرح شد
0

سلام یه چند نکته بگم کد شما کوتاتر بشه متغیرهای image1 , image2 , image3 اگه آرایه نیستن که فکر نکنم آرایه باشن پس بهتره حلقه foreach رو از سه قسمت بردارین.


سبحان دادخواه
تخصص : دانشجوی برنامه نویسی :)
@SobhanDadkhah 4 سال پیش مطرح شد
0

@arminrahmati999 سلام . شما میخواید آدرس عکسهارو به بصورت آرایه در دیتابیس ذخیره کنید درسته ؟ پس زمانی که ملک جدید ایجاد میکنید باید image آرایه خالی باشه ولی وقتی میخواین آپدیت کنید باید متغیر image شما از دیتابیس خونده بشه . شما دارید دوباره داخل متد آپدیت آرایه جدید تعریف میکنید و بعد همونو ذخیره میکنید . اینجا :

public function update(Request $request, int $index)
    {
        $estate = Estate::where('id', $index)->first();
        $year = Carbon::now()->year;
        $destinationPath = "uploads/estates/{$year}/";
        $images = array(); // اینجا باید تغییر کنه

و بجای موردی که عرض کردم همچین کدی بذارید :

$images = $estate->images;

که شامل آرایه ای که از قبل داخل دیتابیستون ذخیره شده هست و حالا میتونید اصطلاحا عنصر جدید push کنید داخل آرایه .
امیدوارم من درست متوجه منظورتون شده باشم و شما هم منظور من رو !
موفق باشید


حسین شیری نژاد
تخصص : programmer
@hosseinshirinegad98 4 سال پیش مطرح شد
0

برای ذخیره عکس اگر بتونی از یه جدول دیگه با ساختار زیر استفاده کنی خیلی بهتره. چون اگر کسی از سه تا عکس یکی رو وارد کرد دیگه دو فیلد دیگه در سطر جدول خالی نمیمونه و حافظه تلکی هدر نمیره.

table name = apartment_images
id
apartment_id
image_path

و اینکه احتمال خیلی زیاد مشکلی که ایجاد میشه در این دو خط
ایجاد میشه چون تصاویر جدید در جدول روی مسیرهای قبلت ذخیره میشن و تصاویر قبلی از بین میرن. شما باید طوری مسیرهای جدیدو سیو کنی که مسیرهای قبلی تصویر حذف نشن

$estate->update(array_merge($request->all() , $images));
 $estate->update(array_merge($request->all() , ['images' => $allImages]));

Armin Rahmati
@arminrahmati999 4 سال پیش مطرح شد
0

@hosseinshirinegad98
مرسی از نکته ای که گفتین.
@SobhanDadkhah
تشکر از شما الان عکس جدید به عکسای قبلی اضافه میشه ولی الان وقتی عکسی رو حذف میکنم و روی باتن ویرایش کلیک میکنم، اون عکس رو حذف نمیکنه، واسه این قسمت باید چیکار کنم؟


سبحان دادخواه
تخصص : دانشجوی برنامه نویسی :)
@SobhanDadkhah 4 سال پیش آپدیت شد
0

@arminrahmati999 بسته به فرآیند حذف عکستون داره . کلیت کار اینه که شما باید هم عکس رو از جدول دیتابیس حذف کنید و هم سرور . البته این هم بستگی داره ممکنه نخواید عکس رو از سرور حذف کنید . شما برای حذف عکس باید آدرس عکس رو دریافت کنید و اون عنصری از آرایه که آدرس مورد نظر هست رو اصطلاحا unset و از آرایه حذف کنید . بی نهایت راه براش هستش ولی خوب همه چیز به تحلیل خودتون و دیتابیس و ساز و کار اپلیکیشنتون برمیگرده .


Armin Rahmati
@arminrahmati999 4 سال پیش آپدیت شد
0

@SobhanDadkhah
ببینید فکر کنم منظور منو درست متوجه نشدید.
فرض کنید اطلاعات ملک ثبت شده و برای ملک 2 عکس انتخاب شده حالا وقتی وارد فرم ویرایش میشیم تصویر زیر نمایش داده میشه.
توضیح تصویر رو وارد کنید

حالا من یکی از عکس ها را پاک میکنم که نتیجه تصویر زیر است
توضیح تصویر رو وارد کنید

اما وقتی رو باتن ویرایش کلیک میکنم اون عکسی که حذف کردم، حذف نمیشه و همچنان باقی میمونه.

اینو باید چیکار کنم؟


سبحان دادخواه
تخصص : دانشجوی برنامه نویسی :)
@SobhanDadkhah 4 سال پیش آپدیت شد
0

@arminrahmati999 کمی توضیحش سخته چون خیلی راه های فراوون و مختلفی هست فقط باید ایده بیاد به ذهنتون ، تحلیل کنید و بعد پیادش کنید و بنده فقط دارم فی البداهه با بررسی سطحی کد هاتون راه پیشنهاد میکنم پس ممکنه بهترین راه نباشه و صرفا سعی دارم ایده های مختلف داخل ذهنتون جرقه بخوره . پیاده سازی و تحلیل نهایی رو شما با توجه به ساختار مورد انتظار از برنامتون باید انجام بدید .

میتونید در کنترلر و موقع آپدیت چک کنید که اگر عکس ها تغییری داشته تغییراتو اعمال کنید . مثلا چطوری ؟ یکی از روش هاش این هست که با هربار کلیک روی دکمه حذف عکس ها وقتی عکس بصورت ظاهری از فرانت اندتون حذف میشه به کمک جاوااسکریپت بیاین و آدرس عکس رو داخل یک hidden input بصورت آرایه ذخیره و push کنید :

<input type="hidden" name="deleted_images[]" value="آدرس عکس" />

حالا داخل کنترلر داخل ریکوئستی که فرستاده میشه میتونید چک کنید اگر این اینپوت مخفی شما مقدار داشت ، یعنی مقادیری که داخلش ذخیره شده آدرس یا آدرس های عکس های حذف شده هست پس با یک حلقه میتونید دونه دونه عکس های مربوط به ملک مورد نظر رو حذف کنید.


میتونید با ajax درخواست فرستاده بشه با هربار کلیک روی دکمه حذف هر عکس مشخصات اون عکس + آیدی ملک درحال ویرایش رو بفرستید به Endpoint مورد نظر مثلا داخل کنترلر متدی به نام destroyImage و اول ملک رو پیدا کنید و داخل آرایه ستون images ، اون عنصر با آدرس عکس مورد نظر رو پیدا کنید و حذف کنید .

چون شاید کمی گنگ توضیح داده باشم از دوستان با تجربه تر هم میتونید کمک بگیرید و حتی خود بنده هم مورد جدیدی رو یاد میگیرم . بنده تگ میکنم انشالا زمان داشته باشن و راهنمایی های بهتری دریافت کنید .
@ali.bayat @mohsenbostan @mohammadeng3731


محسن بستان
تخصص : Senior Backend Developer
@mohsenbostan 4 سال پیش مطرح شد
1

@arminrahmati999
سلام.
باید یک تابع برای عملیات sync بنویسید. یعنی اینکه بیاد تفاوت ها رو ایجاد کنه و بعد آپدیت. پیشنهاد میکنم کلا یک جدول جدا برای تصاویر داشته باشید. با این طوری خیلی ساده تر می تونید کار کنید.


Armin Rahmati
@arminrahmati999 4 سال پیش مطرح شد
0

@SobhanDadkhah
خیلی گیج کننده بود.
@mohsenbostan
اگه بخوام با همین یه جدول این کارو کنم، باید چیکار کنم؟
@hesammousavi
@mohammadeng3731
@ali.bayat
از دوستان باتجربه ممنون میشم راهنمایی کنن.


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

سلام.
شما اصلا منطق طراحی دیتابیستون درست نیست که همین مورد باعث پیچشده شدن کداتون و گیج شدن خودتون شده.شما باید یک جدول جدا برای ثبت آدرس یا اسم عکساتون استفاده کنید.یه خورده منعطف تر باشید و روی پیاده سازی یه روش غیر بهینه انقدر اسرار نکنید و در مورد نرمالایز کردن جداول دیتا بیس مطالعه کنید تا در آینده با این چالش ها کمتر مواجه بشید.در مورد حذف یا اضافه کردن یک عکس اصلا نیاز نیست شما بیاید از حلقه ها استفاده کنین و این کار کاملا اشتباه است.بهترین و بهینه ترین روش استفاده از کلاس formData از javascript هستش که هر بار یک درخواست برای آپلود عکس مورد نظرتون بدید و اون رو داخل پایگاه داده ذخیره کنید و آپلود کنید(دونه دونه آپلود کنید نه همه رو یک جا. با رخداد onchange برای input مورد نظرتون مثلا میتونید این کار رو انجام بدید).برای هر عکس هم یک سطر جدا باید در نظر گرفت تا مجبور نشید unserialize یا عملیات casting رو برای پیدا کردن عکس مورد نظر انجام بدید که کداتون بهم ریخته و غیر قابل فهم بشه در آینده برای توسعه دهنده های دیگه یا حتی خودتون.


Armin Rahmati
@arminrahmati999 4 سال پیش مطرح شد
0

@mohammadeng3731
سلام.
کدهای فانکشن های store و update رو به صورت بهینه تر نوشتم و همچنین حلقه های foreach هم حذف کردم که اصلاح شده ی آنها به صورت زیر است:

store

public function store(Request $request)
    {
        $year = Carbon::now()->year;
        $destinationPath = "uploads/estates/{$year}/";
        $images = array();
        if ($files = $request->file('image1')) {
                $filename = $files->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $files->move(public_path($destinationPath), $rnd . $filename);
                $images[] = $destinationPath . $rnd . $filename;
        }
        if ($files = $request->file('image2')) {
                $filename = $files->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $files->move(public_path($destinationPath), $rnd . $filename);
                $images[] = $destinationPath . $rnd . $filename;
        }
        if ($files = $request->file('image3')) {
                $filename = $files->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $files->move(public_path($destinationPath), $rnd . $filename);
                $images[] = $destinationPath . $rnd . $filename;
        }
        $allImages = implode("|", $images);

        // Apartment && Office - Sell
        if ($request->input('estateType') == 'apartment' && $request->input('type') == 'sell' ||
            $request->input('estateType') == 'office' && $request->input('type') == 'sell') {

            if ($request->input('rent') == null && $request->input('deposit') == null) {
                if (! $request->image1 && ! $request->image2 && ! $request->image3) {

                    auth()->user()->estate()->create(array_merge($request->all() , $images));
                }else
                    auth()->user()->estate()->create(array_merge($request->all() , ['images' => $allImages]));
            }
            return redirect('/UserPanel');
        }
}

update

public function update(Request $request, int $index)
    {
        $estate = Estate::where('id', $index)->first();
        $year = Carbon::now()->year;
        $destinationPath = "uploads/estates/{$year}/";
        $images[] = $estate->images;
        if ($files = $request->file('image1')) {
                $filename = $files->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $files->move(public_path($destinationPath), $rnd . $filename);
                $images[] = $destinationPath . $rnd . $filename;
        }
        if ($files = $request->file('image2')) {
                $filename = $files->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $files->move(public_path($destinationPath), $rnd . $filename);
                $images[] = $destinationPath . $rnd . $filename;
        }
        if ($files = $request->file('image3')) {
                $filename = $files->getClientOriginalName();
                $rnd = random_int(1, 1000);
                $files->move(public_path($destinationPath), $rnd . $filename);
                $images[] = $destinationPath . $rnd . $filename;
        }
        $allImages = implode("|", $images);

        // Apartment && Office - Sell
        if ($request->input('estateType') == 'apartment' && $request->input('type') == 'sell' ||
            $request->input('estateType') == 'office' && $request->input('type') == 'sell') {

            if ($request->input('rent') == null && $request->input('deposit') == null) {
                if (! $request->image1 && ! $request->image2 && ! $request->image3) {

                    $estate->update(array_merge($request->all() , $images));
                }else if ($request->image1 || $request->image2 || $request->image3)
                    $estate->update(array_merge($request->all() , ['images' => $allImages]));
            }
            return redirect('/UserPanel');
        }
}

همچنین برای هر عکس یک input در نظر گرفتم ولی همه رو داخل یک آرایه ذخیره میکنم و داخل دیتابیس هم هر سه عکس داخل یک فیلد ذخیره میشن.

حالا برای اینکه اون عکس حذف بشه فقط قسمت جاوا اسکریپت باید تغییراتی رو انجام بدم؟ (توضیح دقیق تر: چهار تا پیام بالاتر از پیام شما)


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

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