Mein Setup für dieses Tutorial
- Windows 7
- Xampp mit Php7 & Mysql 5.7
- Composer mit gesetzter Pathvariable
1.) Laravel Installer mit Composer downloaden
$ composer global require "laravel/installer=~1.1"
2.) In das Server Webverzeichnis navigieren und Projekt anlegen
$ cd C:\xampp\htdocs $ composer create-project laravel/laravel framework_laravel 5.3.*
3.) Wir stellen das Projekt auf debug-modus ein
[code filename="config/app.php"] return [ 'debug' => env('APP_DEBUG', true), [/code]
4.) Wir konfigurieren unsere Datenbank(Mysql)-Einstellungen
[code filename=".env"] DB_HOST=localhost DB_PORT=3306 DB_DATABASE=framework_test DB_USERNAME=rootXXXX [/code]
4.) Http-Controller CatalogController erstellen und routen
[code filename="app/Http/Controllers/CatalogController.php"] <?php namespace App\Http\Controllers; use Illuminate\Http\Request; class CatalogController extends Controller { public function catalog($param = null, Request $request = null) { echo __CLASS__.'::'.__FUNCTION__; } } [/code]
5.) am Ende der Datei einfügen
[code filename="routes/web.php"] Route::get('katalog', 'CatalogController@catalog'); Route::get('katalog/', 'CatalogController@catalog'); Route::get('katalog/{param}', 'CatalogController@catalog'); [/code]
6.) Es wird Zeit die datenbankstruktur aufzuseten
Vom rootverszeichnis verwenden wir nun Artisan(Laravel’s Kommandozeilenschnittstelle) um Migrations zu erzeugen
$ php artisan make:migration create_shop_articles_table $ php artisan make:migration create_shop_article_countries_table $ php artisan make:migration create_shop_article_languages_table $ php artisan make:migration create_shop_categories_table $ php artisan make:migration create_shop_article_categories_table
Die Migrations-Dateien werden von artisan als folgende Dateien abgelegt
Die Datums-Nomenklatur variiert natürlich in eurem Projekt
database/migrations/2016_11_24_120908_create_shop_articles_table.php
database/migrations/2016_11_24_121033_create_shop_article_countries_table.php
database/migrations/2016_11_24_121100_create_shop_article_languages_table.php
database/migrations/2016_11_24_121127_create_shop_categories_table.php
database/migrations/2016_11_24_121154_create_shop_article_categories_table.php
7. Die erzeugten Dateien werden geöffnet. Funktionern werden ergänzt:
[code filename="database/migrations/2016_11_24_120908_create_shop_articles_table.php"] public function up() { Schema::dropIfExists('shop_articles'); Schema::create('shop_articles', function($table) { $table->increments('id'); $table->integer('active')->default(1); $table->string('artnum'); $table->string('picture_1')->nullable(); $table->string('picture_2')->nullable(); $table->string('picture_3')->nullable(); $table->timestamps(); }); } public function down() { Schema::drop('shop_articles'); } [/code]
[code filename="database/migrations/2016_11_24_121033_create_shop_article_countries_table.php"] public function up() { Schema::dropIfExists('shop_article_countries'); Schema::create('shop_article_countries', function($table) { $table->increments('id'); $table->integer('shop_articles_id')->unsigned(); $table->foreign('shop_articles_id')->references('id')->on('shop_articles')->onDelete('cascade'); $table->integer('country_id'); $table->double('brutto', 8, 4); $table->double('vat', 2, 2); $table->string('currency', 16); $table->integer('available')->default(1); $table->timestamps(); }); } public function down() { Schema::drop('shop_article_countries'); } [/code]
[code filename="database/migrations/2016_11_24_121100_create_shop_article_languages_table.php"] public function up() { Schema::dropIfExists('shop_article_languages'); Schema::create('shop_article_languages', function($table) { $table->increments('id'); $table->integer('shop_articles_id')->unsigned(); $table->foreign('shop_articles_id')->references('id')->on('shop_articles')->onDelete('cascade'); $table->integer('language_id'); $table->string('name', 255); $table->string('title', 255); $table->text('short_desc'); $table->text('description'); $table->timestamps(); }); } public function down() { Schema::drop('shop_article_languages'); } [/code]
[code filename="database/migrations/2016_11_24_121127_create_shop_categories_table.php"] public function up() { Schema::dropIfExists('shop_categories'); Schema::create('shop_categories', function($table) { $table->increments('id'); $table->integer('parent_id')->nullable(); $table->string('name', 255); $table->timestamps(); }); } public function down() { Schema::drop('shop_categories'); } [/code]
[code filename="database/migrations/2016_11_24_121154_create_shop_article_categories_table.php"] public function up() { Schema::dropIfExists('shop_article_categories'); Schema::create('shop_article_categories', function($table) { $table->increments('id'); $table->integer('shop_articles_id')->unsigned(); $table->foreign('shop_articles_id')->references('id')->on('shop_articles'); $table->integer('shop_categories_id')->unsigned(); $table->foreign('shop_categories_id')->references('id')->on('shop_categories'); $table->timestamps(); }); } public function down() { Schema::drop('shop_article_categories'); } [/code]
8.) Mit Artisan erzeugen wir aus den Migrationsfiles die Datenbanktabellen
$ php artisan migrate $ Y
Jetzt erzeugen wir noch die Eloquent-Modelle.
Jede Tabelle s.o. korrespondiert mit einem Model
Wir erstellen das Verzeichnis app/Models/Catalog
und legen dort folgende Dateien an
[code filename="app/Models/Catalog/ShopArticles.php"] <?php namespace App\Models\Catalog; use Illuminate\Database\Eloquent\Model; class ShopArticles extends Model{ public function country() { return $this->hasOne('App\Models\Catalog\ShopArticleCountries'); } public function language() { return $this->hasOne('App\Models\Catalog\ShopArticleLanguages'); } protected $table = 'shop_articles'; } [/code]
[code filename="app/Models/Catalog/ShopArticleLanguages.php"] <?php namespace App\Models\Catalog; use Illuminate\Database\Eloquent\Model; class ShopArticleLanguages extends Model{ protected $table = 'shop_article_languages'; } [/code]
[code filename="app/Models/Catalog/ShopArticleCountries.php"] <?php namespace App\Models\Catalog; use Illuminate\Database\Eloquent\Model; class ShopArticleCountries extends Model{ protected $table = 'shop_article_countries'; } [/code]
[code filename="app/Models/Catalog/ShopCategories.php"] <?php namespace App\Models\Catalog; use Illuminate\Database\Eloquent\Model; class ShopCategories extends Model{ protected $table = 'shop_categories'; } [/code]
[code filename="app/Models/Catalog/ShopArticleCategories.php"] <?php namespace App\Models\Catalog; use Illuminate\Database\Eloquent\Model; class ShopArticleCategories extends Model{ protected $table = 'shop_article_categories'; } [/code]
9.) Testdaten sind hier zu haben:
https://www.databau.de/download/tutorial-framework/framework_test-data.sql
Bitte downloaden und einspielen
10.) Wir kommen wieder zum CatalogController zurück
In der function catalog testen wir des erste mal eines unserer Elquent Modelle .
[code filename="app/Http/Controllers/CatalogController.php"] <?php namespace App\Http\Controllers; use App\Models\Catalog\ShopArticles; use Illuminate\Http\Request; class CatalogController extends Controller { public function catalog($param = null, Request $request = null) { $articles = ShopArticles::get(); print_r($articles); } } [/code]
11.) Sprach und Länder-spezifische Felder in das Artikel-Model joinen
Das Modell funktioniert also. Dann testen wir eine erweitere Abfrage und ergänzen die function catalog
[code filename="app/Http/Controllers/CatalogController.php"] public function catalog($param = null, Request $request = null) { $request['language_id'] = 1; $request['country_id'] = 3; $request['offset'] = 0; $request['limit'] = 12; $articles = ShopArticles::with([ 'language' => function($query) use ($request){ if( !empty($request['language_id']) ) { $query->whereRaw(' language_id = ? ', array($request['language_id'])); } }, 'country' => function($query) use ($request){ if( !empty($request['country_id']) ) { $query->whereRaw(' country_id = ? ', array($request['country_id'])); } }]) ->offset($request['offset']) ->limit($request['limit']) ->get(); print_r($articles); } [/code]
12.) Zum übergeben an das Frontend wollen wir unsere Resourcen mit Fractal transfomieren.
Bisher bekommen wir nur das ganze ORM-Eloquent-objekt, wollen aber eine weniger komplexe Struktur an das View liefern
Wir wollen ein eindimensionales Array mit angepassten keys, values pairs erzeugen.
Dafür integrieren wir Fractal-Transformers in unser Projekt.
In der Konsole installieren wir mit composer
$ composer require league/fractal
Und bauen einen Fractal-Transformer
[code filename="app/Transformers/Catalog/ShopArticlesTransformer.php"] <?php namespace App\Transformers\Catalog; use App\Models\Catalog\ShopArticles; use League\Fractal\TransformerAbstract; class ShopArticlesTransformer extends TransformerAbstract { public function transform(ShopArticles $ShopArticles) { $article = $ShopArticles->getAttributes(); $ShopLanguage = $ShopArticles->getRelation('language'); $language = empty($ShopLanguage) ? array('name' => null, 'title' => null, 'short_desc' => null, 'description' => null) : $ShopLanguage->getAttributes(); $ShopCountries = $ShopArticles->getRelation('country'); $country = empty($ShopCountries) ? array('brutto' => null, 'currency' => null) : $ShopCountries->getAttributes(); return [ 'id' => (int) $ShopArticles->id, 'name' => $language['name'], 'title' => $language['title'], 'desc1' => $language['short_desc'], 'desc2' => $language['description'], 'price' => number_format($country['brutto'], 2, ',', '.') . ' ' . $country['currency'], 'thumpnail' => empty($article['picture_1']) ? '' : 'thumpnail__' . $article['picture_1'], 'img1' => $article['picture_1'], 'img2' => $article['picture_2'], 'img3' => $article['picture_3'], ]; } } [/code]
Wir gehen wieder zum Http-Controller
Neue imports:
[code filename="app/Http/Controllers/CatalogController.php"] use App\Transformers\Catalog\ShopArticlesTransformer; use League\Fractal\Manager; use League\Fractal\Resource\Collection; [/code]
Dann Suchen:
[code filename="app/Http/Controllers/CatalogController.php"] print_r($articles); [/code]
Und Ersetzen:
[code filename="app/Http/Controllers/CatalogController.php"] $manager = new Manager(); $resource = new Collection($articles, new ShopArticlesTransformer()); $ArticleList = $manager->createData($resource)->toArray(); print_r($ArticleList); [/code]
Die Transfomation und Ausgabe der $ArticleList eignet sich jetzt zu Übergabe an das View.
Jetzt aber erstmal print_r und nachsehen was wir haben. Die wirklich Übergabe erfolgt später
13.) Views erstellen
Blade heißt die Template-Engine für Laravel.
Wir erstellen zwei Blade-Dateien.
[code filename="resources/views/layout.blade.php"] <!doctype html> <html ng-app="framance.shop"> <head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="device" content=""/> <title>Laravel Test</title> <link href="https://fonts.googleapis.com/css?family=Bad+Script" rel="stylesheet" type="text/css"> <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/> <link href="https://www.databau.de/download/turorial-framework/assets/css/main.css" rel="stylesheet"/> </head> <body> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="#">Laravel Tutorial</a> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="">Home</a></li> <li class="active"><a href="katalog">Katalog</a></li> </ul> </div> </div> </nav> <div class="content container"> @yield('content') </div> </body> </html> [/code]
[code filename="resources/views/catalog.blade.php"] @extends('layout') @section('content') <div class="wrapped-content"> <div> <br/><br/><br/><br/><br/> <div class="page-container"> @foreach ($ArticleList as $key=>$ArticleItem) <div class="col-sm-12 item-container list"> <div class="col-sm-3 item"> <a href="katalog/Schuhe#article/"> <img srcset="https://www.databau.de/download/tutorial-framework/images/{{$ArticleItem['img1']}} 750w, https://www.databau.de/download/tutorial-framework/images/{{$ArticleItem['thumpnail']}} 974w, https://www.databau.de/download/tutorial-framework/images/{{$ArticleItem['img1']}} 3000w" style="width:100%;height:auto;"/> </a> <span style="color:blue;">{{$ArticleItem['title']}}</span> <span style="color:red;">{{$ArticleItem['price']}}</span> </div> </div> @endforeach </div> </div> </div> @stop [/code]
14.) Zuletzt bearbeiten wir noch einmal den Http-Controller
Suchen:
[code filename="app/Http/Controllers/CatalogController.php"] print_r($ArticleList); [/code]
Und Ersetzen:
[code filename="app/Http/Controllers/CatalogController.php"] return view('catalog', [ 'ArticleList' => $ArticleList['data'], ] ); [/code]
15.) Im nächsten Teil werden Pager und Artikel-Detail fertig gestellt