لارافيل: نقوم بتحليل المفاهيم الأساسية. الجزء الثالث: النهائي

تبقى بضعة أيام حتى بدء دورة جديدة من OTUS - "Framework Laravel" . تحسبا لبدء الدورة ، نشارك الجزء الأخير من منشور المؤلف حول المفاهيم الأساسية في Laravel. هام: لا تتعلق هذه السلسلة من المنشورات بالبرنامج التعليمي للدورة وهي مادة مفيدة قليلاً للمبتدئين . يمكن العثور على برنامج الدورة هنا .




في المقالة الأخيرة ، بدأنا في كتابة معرض حيث يمكن للمستخدم تسجيل الدخول والتسجيل وإنشاء ألبومات مع الوصف والغطاء والعنوان. في التطبيق الذي تم إنشاؤه هناك القيمة الأساسية لرأينا والآن من الضروري توسيعه قليلاً.
أيضا ، الكود الموجود يستحق بعض التحسن:

لدينا بالفعل اثنين من وحدات التحكم - AlbumController و ImageController . إضافة استيراد فئة إضافية مسؤولة عن العمل مع سلاسل:

  use Illuminate\Support\Str; 

وقم بتغيير الخط المسؤول عن إنشاء اسم صورة عشوائي في قاعدة البيانات الخاصة بنا:

  $random_name = Str::random(8); 

بالإضافة إلى ذلك ، من المهم الآن تغيير رمز الترحيل قليلاً لزيادة موثوقية تطبيقنا ، لأن المستخدم يجب أن يكون له الحق في ترك حقل description بنا فارغًا (وإلا فإن Laravel with dynamite ستعلمنا بخطأ). دعنا نذهب إلى الترحيل المرتبط بجدول الصور ، وقم بتصحيح السطر المرتبط بوصف الصورة في هذا:

  $table->string('description')->nullable(); 

حسنا ، مع الانتهاء من "إعادة بناء" للتطبيق. بعد ذلك ، تحتاج إلى إنهاء مظهر طلبنا. قم بإنشاء نموذج يستطيع المستخدم من خلاله إنشاء ألبوماته:

ملف addimage.blade.php

  @include('includes.header') <body> @include('includes.nav') <div class="container" style="text-align: center;"> <div class="span4" style="display: inline-block; margin-top:100px;"> @if (isset($errors) && $errors->has('')) <div class="alert alert-block alert-error fade in"id="error-block"> <?php $messages = $errors->all('<li>:message</li>'); ?> <button type="button" class="close"data-dismiss="alert">×</button> <h4>Warning!</h4> <ul> @foreach($messages as $message) {{$message}} @endforeach </ul> </div> @endif <form name="createnewalbum" method="POST"action="{{route('create_album')}}" enctype="multipart/form-data"> {{ csrf_field() }} <fieldset> <legend> </legend> <div class="form-group"> <label for="name"> </label> <input name="name" type="text" class="form-control"placeholder=" " value="{{old('name')}}"> </div> <div class="form-group"> <label for="description"> </label> <textarea name="description" type="text"class="form-control" placeholder=" ">{{old('descrption')}}</textarea> </div> <div class="form-group"> <label for="cover_image">   </label> {{Form::file('cover_image')}} </div> <button type="submit" class=«btn btn-default">!</button> </fieldset> </form> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script> </body> </html> 

واسمحوا لي أن أذكركم بأننا includes في الجزء العلوي من الصفحة التصفح والمكتبات المستخدمة ، والتي تم وصفها في الجزء الأخير.

بالإضافة إلى ذلك ، نحتاج إلى إضافة مظهر album.blade.php

  @include('includes.header') <body> @include('includes.nav') <div class="container"> <div class="starter-template"> <div class="media"> <img class="media-object pull-left"alt="{{$album->name}}" src="/albums/{{$album->cover_image}}" width="350px"> <div class="media-body"> <h2 class="media-heading" style="font-size: 26px;"> :</h2> <p>{{$album->name}}</p> <div class="media"> <h2 class="media-heading" style="font-size: 26px;">  :</h2> <p>{{$album->description}}<p> <a href="{{route('add_image',array('id'=>$album->id))}}"><button type="button"class="btn btn-primary btn-large">    </button></a> <a href="{{route('delete_album',array('id'=>$album->id))}}" onclick="return confirm(' ?')"><button type="button"class="btn btn-danger btn-large"> </button></a> </div> </div> </div> </div> <div class="row"> @foreach($album->Photos as $photo) <div class="col-lg-3"> <div class="thumbnail" style="max-height: 350px;min-height: 350px;"> <img alt="{{$album->name}}" src="/albums/{{$photo->image}}"> <div class="caption"> <p>{{$photo->description}}</p> <p> : {{ date("d FY",strtotime($photo->created_at)) }}at {{ date("g:ha",strtotime($photo->created_at)) }}</p> <a href="{{route('delete_image',array('id'=>$photo->id))}}" onclick="returnconfirm(' ?')"><button type="button"class="btn btn-danger btn-small"> </button></a> <p>     :</p> <form name="movephoto" method="POST"action="{{route('move_image')}}"> {{ csrf_field() }} <select name="new_album"> @foreach($albums as $others) <option value="{{$others->id}}">{{$others->name}}</option> @endforeach </select> <input type="hidden" name="photo"value="{{$photo->id}}" /> <button type="submit" class="btn btn-smallbtn-info" onclick="return confirm(' ?')"> </button> </form> </div> </div> </div> @endforeach </div> </div> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> </body> </html> 

بالإضافة إلى ذلك ، يمكننا تحديث التوجيه لدينا قليلاً ، على سبيل المثال ، في nav.blade.php :

  <li><a href="{{URL::route('create_album_form')}}">  </a></li> 

إلى خيار أحدث وأكثر عصرية:

  <li><a href="{{route('create_album_form')}}">  </a></li> 

من ناحية أخرى ، عملت النسخة السابقة على 6 Laravel. لذلك ، لدينا بالفعل نموذج يمكن للمستخدم من خلاله إضافة الصور إلى الألبوم ، وهناك view الرئيسية لألبومنا. بعد ذلك ، نحتاج إلى إضافة وحدة تحكم تكون مسؤولة عن معالجة صورة واحدة.

لذلك ، نقوم بإنشاء وحدة تحكم مسؤولة عن العمل مع الصور الفردية:

  php artisan make:controller ImageController 

لذا ، ماذا يجب أن يكون بداخلنا:

  <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\MessageBag; use Validator; //       use App\Album; use App\Image; use Illuminate\Support\Str; class ImageController extends Controller { public function getForm($id) { $album = Album::find($id); return view('addimage') ->with('album',$album); //  ,          } public function postAdd(Request $request) { //    ,       $rules = [ 'album_id' => 'required|numeric|exists:albums,id', 'image'=>'required|image' ]; $input = ['album_id' => null]; $validator = Validator::make($request->all(), $rules); if($validator->fails()){ return redirect()->route('add_image', ['id' => $request->get('album_id')])->withErrors($validator)->withInput(); } $file = $request->file('image'); //   $random_name = Str::random(8); //  $destinationPath = 'albums/'; $extension = $file->getClientOriginalExtension(); $filename=$random_name.'_album_image.'.$extension; $uploadSuccess = $request->file('image')->move($destinationPath, $filename); Image::create(array( 'description' => $request->get('description'), //   'image' => $filename, //   'album_id'=> $request->get('album_id') //         )); return redirect()->route('show_album',['id'=>$request->get('album_id')]); } public function getDelete($id) //       { $image = Image::find($id); $image->delete(); return redirect()->route('show_album',['id'=>$image->album_id]); } //       public function postMove(Request $request) { $rules = array( 'new_album' => 'required|numeric|exists:albums,id', 'photo'=>'required|numeric|exists:images,id' ); //    $validator = Validator::make($request->all(), $rules); if($validator->fails()){ return redirect()->route('index'); } $image = Image::find($request->get('photo')); $image->album_id = $request->get('new_album'); $image->save(); return redirect()->route('show_album', ['id'=>$request->get('new_album')]); } } 



التسجيل والترخيص


في الوقت الحالي ، طلبنا جاهز تقريبًا. ومع ذلك ، ما زلنا بحاجة إلى تشديد القدرة على التسجيل في طلبنا وتسجيل الخروج وتسجيل الدخول إلى حساب موجود.

في الجزء الأخير ، لقد أظهرنا بالفعل كيف يبدو لنا includes/nav.blade.php . لأن نريد أن يظهر زر تسجيل الدخول والتسجيل عندما يكون المستخدم غير مسجل حتى الآن ، وزر تسجيل الخروج عندما يكون مسجلاً معنا.

لذلك ، هكذا ننظر الآن إلى القائمة في includes/nav.blade.php :

  <ul class="nav navbar-nav"> @if (Auth::check()) <li> <button type="button" class="btn btn-primary"> <!--   ,  ->   --> {{{ Auth::user()->name}}} </button> </li> <li><a href="{{route('create_album_form')}}">  </a></li> @else <!--    --> <li><a href="{{route('register')}}"></a></li> <li><a href="{{route('login')}}"></a></li> @endif @if (Auth::check()) <!--  ,       --> <!--      --> <li> <a href="{{url('/logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">  </a> <form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;"> {{ csrf_field() }} </form> </li> @endif </ul> 

باستخدام Auth::check للبناء والعنصر الابتدائي if else ، يمكننا بناء تغييرات في رأينا ، اعتمادًا على ما إذا كان مستخدمنا مسجلاً أم لا.

ومع ذلك ، مع إجراء تغييرات على view قبل إنشاء النموذج ووحدة التحكم ، فإننا نتقدم قليلاً قبل المحرك. من أجل جعل المصادقة الخاصة بنا ، سوف نستخدم جميع الحلول الجاهزة والسريعة الموجودة في Laravel 6.

لذلك ، حول نموذج المستخدم - سوف نستخدم النموذج الذي يأتي في المربع. من ناحية ، من الواضح أنه لا يكفي لتطبيق كامل ، من ناحية أخرى - لا أريد أن أقصر نفسي على نطاق تطبيق معين. أي نوع من معرض تريد؟ أين يمكن للمستخدم إنشاء ألبوماته الخاصة التي لا يمكن لأي شخص الوصول إليها؟ أو أين يشارك الجميع صورهم؟ لن يكون لدينا قيود في تطبيقنا - أعتقد أن القارئ سيكون قادرًا على الانتهاء منها دون أي مشاكل لذوقه ولونه.

لذلك ، في Laravel 6 ، أصبح إنشاء المصادقة أسهل. نذهب إلى سطر الأوامر من تطبيقنا:

  composer require laravel/ui —dev 

الذي يعطينا الحزم اللازمة. الآن قم بإنشاء:

  php artisan ui:auth 

ماذا يعطينا هذا الفريق؟ أولاً ، لدينا مجلد auth جديد في resources/views ، حيث لدينا جميع views التي قد تكون ضرورية لتخويل المستخدم وتسجيله: login register verify . يوجد أيضًا مجلد فرعي passwords مخصص لإعادة تعيين كلمات المرور واستعادتها. في مجلد Http/Controllers ، لدينا HomeController ، وهو ضروري لإعادة التوجيه إلى الصفحة الرئيسية بعد تسجيل المستخدم. سيكون لدينا أيضًا layouts app.blade.php الفرعي ، والتي ستحتوي على app.blade.php ، والتي لن نقوم بتفكيكها اليوم ، لكن يمكن أن تكون أساسًا ممتازًا لتطبيق تم إنشاؤه من البداية.

تحتوي قوالب الشفرات المولدة بالفعل على تخطيط أولي مخصص لـ Bootstrap . لدينا بالفعل متصلا في header.blade.php .
بالإضافة إلى ذلك ، قمنا بتحديث بعض التوجيه في routes/web.php . تمت إضافة الأسطر التالية:

  Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); Route::post('/logout', 'Auth\LoginController@logout')->name('logout'); 

يتم إنشاء المسار إلى home تلقائيًا ، وقد قمت بإعادة التوجيه لتسجيل logout بنفسي.

لكي يعمل التصميم الخاص بك على القوالب التي تم إنشاؤها ، سنقوم بربط nav :

  @include('includes.header') <body> @include('includes.nav') @extends('layouts.app') 

عظيم ، الآن كل شيء جاهز. محاولة للتسجيل. تأكيد كلمة المرور يجب أن تعمل أيضا:





في المستقبل ، يمكن للمستخدم اختيار أي صفحة من الخدمة يريد أن يذهب إليها (أو يمكن للقارئ إجراء إعادة توجيه من تلقاء نفسه ، ليست معقدة بما فيه الكفاية). علينا فقط إصلاح التفاصيل الصغيرة: لجعلها حتى يتمكن المستخدمون المسجلون والمصرح لهم فقط من رؤية ألبوماتنا الثمينة.

للقيام بذلك ، نضيف شرطًا إلى التوجيه الخاص بنا حتى يتسنى للمستخدم تسجيل الدخول للوصول إلى الألبومات.

تحديث web.php لدينا:

  Route::get('/', array('as' => 'index','uses' => 'AlbumsController@getList')) ->middleware('auth');; //middleware     http    Route::get('/createalbum', array('as' => 'create_album_form','uses' => 'AlbumsController@getForm')) ->middleware('auth');; //    Route::post('/createalbum', array('as' => 'create_album','uses' => 'AlbumsController@postCreate')) ->middleware('auth');; //   Route::get('/deletealbum/{id}', array('as' => 'delete_album','uses' => 'AlbumsController@getDelete')) ->middleware('auth');; //   Route::get('/album/{id}', array('as' => 'show_album','uses' => 'AlbumsController@getAlbum')) ->middleware('auth');; //   

في الأساس ، في هذه المرحلة يمكننا بالفعل الانتهاء. سأترك الأمر للقارئ ما هو التطبيق الذي يريد تقديمه: مع ألبومات خاصة أو مع ألبومات عامة. من الناحية النظرية البحتة ، يمكن استخدام التطبيق بالفعل إذا تغيبت عن إمكانية التسجيل وإنشاء مستخدم بشكل منفصل مباشرة في قاعدة البيانات - على سبيل المثال ، إذا كنت أنت وزملاؤك ستنظمون ألبوماتك الخاصة ولا تريد استخدام خدمات أخرى لسبب ما.

شكرا لكم جميعا على اهتمامكم! كما هو الحال دائمًا ، روابط مفيدة:

Source: https://habr.com/ru/post/ar473114/


All Articles