Merge pull request #9872 from bizley-code/guide-pl

Guide [PL] translation [skip ci]
This commit is contained in:
Alexander Makarov
2015-10-09 21:36:04 +03:00
4 changed files with 413 additions and 1 deletions

View File

@@ -92,7 +92,7 @@ Odbieranie danych od użytkowników
* [Walidacja danych wejściowych](input-validation.md)
* [Wysyłanie plików](input-file-upload.md)
* [Odczytywanie tablicowych danych wejściowych](input-tabular-input.md)
* [Odbieranie danych z wielu modeli](input-multiple-models.md)
* [Pobieranie danych dla wielu modeli](input-multiple-models.md)
Wyświetlanie danych

View File

@@ -0,0 +1,194 @@
Wysyłanie plików
===============
Przesyłanie plików w Yii jest zazwyczaj wykonywane przy użyciu klasy [[yii\web\UploadedFile]], która hermetyzuje każdy przesłany plik jako obiekt `UploadedFile`.
W połączeniu z [[yii\widgets\ActiveForm]] oraz [modelem](structure-models.md), możesz w łatwy sposób zaimplementować bezpieczny mechanizm przesyłania plików.
## Tworzenie modeli <span id="creating-models"></span>
Tak jak przy zwykłych polach tekstowych, aby przesłać pojedyńczy plik musisz utworzyć klasę modelu oraz użyć atrybutu tego modelu do przechowania instancji przesłanego pliku.
Powinieneś również zadeklarować zasadę walidacji do zwalidowania przesłanego pliku.
Dla przykładu:
```php
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model
{
/**
* @var UploadedFile
*/
public $imageFile;
public function rules()
{
return [
[['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
public function upload()
{
if ($this->validate()) {
$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
return true;
} else {
return false;
}
}
}
```
W powyższym kodzie, atrybut `imageFile` zostanie użyty do przechowania instancji przesłanego pliku. Jest połączony z zasadą walidacji `file`, która korzysta z
walidatora [[yii\validators\FileValidator]], aby upewnić się, że przesłany plik posiada rozszerzenie `png` lub `jpg`.
Metoda `upload()` wywoła walidację oraz zapis przesłanego pliku na serwerze.
Walidator `file` pozwala na sprawdzenie rozszerzenia, wielkości, typu MIME, itp.
Po więcej szczegółów zajrzyj do sekcji [Podstawowe walidatory](tutorial-core-validators.md#file)
> Tip: Jeśli przesyłasz obrazek, możesz rozważyć użycie walidatora `image`.
Walidator ten jest implementowany przez [[yii\validators\ImageValidator]], który weryfikuje czy atrybut otrzymał prawidłowy obrazek który może być zapisany i przetworzony przez [rozszerzenie Imagine](https://github.com/yiisoft/yii2-imagine).
## Renderowanie pola wyboru pliku <span id="rendering-file-input"></span>
Po zapisaniu modelu, utwórz pole wyboru pliku w widoku:
```php
<?php
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<button>Wyślij</button>
<?php ActiveForm::end() ?>
```
Należy pamiętać, aby dodać opcję `enctype` do formularza, przez co plik będzie mógł być prawidłowo przesłany.
Wywołanie `fileInput()` spowoduje wyrenderowanie tagu `<input type="file">`, który pozwala użytkownikowi na wybranie oraz przesłanie pliku.
## Implementacja kontrolera <span id="wiring-up"></span>
W akcji kontrolera musimy połączyć model oraz widok aby zaimplementować przesyłanie plików:
```php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->imageFile = UploadedFile::getInstance($model, 'imageFile');
if ($model->upload()) {
// plik został przesłany
return;
}
}
return $this->render('upload', ['model' => $model]);
}
}
```
W powyższym kodzie, kiedy formularz jest wysłany, metoda [[yii\web\UploadedFile::getInstance()]] wywoływana jest do reprezentowania pliku jako instancji `UploadedFile`.
Następnie przystępujemy do walidacji modelu, aby upewnić się, że przesłany plik jest prawidłowy, po czym zapisujemy go na serwerze.
## Przesyłanie wielu plików <span id="uploading-multiple-files"></span>
Możesz przesyłać wiele plików za jednym razem modyfikując odrobinę kod wylistowany w powyższych sekcjach.
Najpierw powinieneś dostosować klasę modelu dodając opcję `maxFiles` do zasady walidacji `file`, aby określić dozwoloną maksymalną liczbę przesyłanych plików.
Metoda `upload()` powinna również zostać zaktualizowana, aby zapisywać pliki jeden po drugim.
```php
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model
{
/**
* @var UploadedFile[]
*/
public $imageFiles;
public function rules()
{
return [
[['imageFiles'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg', 'maxFiles' => 4],
];
}
public function upload()
{
if ($this->validate()) {
foreach ($this->imageFiles as $file) {
$file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
}
return true;
} else {
return false;
}
}
}
```
W pliku widoku, powinieneś dodać opcję `multiple` do wywołania `fileInput()`, aby pole wyboru pliku pozwalało na wybór wielu plików na raz:
```php
<?php
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'imageFiles[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
<button>Submit</button>
<?php ActiveForm::end() ?>
```
Na koniec, w akcji kontrolera musimy zmienić wywołanie `UploadedFile::getInstance()` na `UploadedFile::getInstances()`, aby przypisać tablicę instancji `UploadedFile` do `UploadForm::imageFiles`.
```php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->imageFiles = UploadedFile::getInstances($model, 'imageFiles');
if ($model->upload()) {
// plik został przesłany
return;
}
}
return $this->render('upload', ['model' => $model]);
}
}
```

View File

@@ -0,0 +1,142 @@
Tworzenie formularzy
==============
Podstawowym sposobem korzystania z formularzy w Yii jest użycie [[yii\widgets\ActiveForm]]. Ten sposób powinien być używany, jeśli formularz jest bazowany na modelu.
Dodatkowo, [[yii\helpers\Html]] zawiera sporo użytecznych metod, które zazwyczaj używane są do dodawania przycisków i tekstów pomocniczych do każdego formularza.
Formularz, który jest wyświetlany po stronie klienta, w większości przypadków, posiada odpowiedni [model](structure-models.md), który jest używany do walidacji danych wejściowych po stronie serwera.
(Sprawdź sekcję [Walidacja danych wejściowych](input-validation.md) aby uzyskać więcej szczegółów).
Podczas tworzenia formularza na podstawie modelu, pierwszym krokiem jest zdefiniowanie samego modelu.
Model może być bazowany na klasie [Active Record](db-active-record.md), reprezentując dane z bazy danych, lub może być też bazowany na klasie generycznej Model ([[yii\base\Model]]) aby przechwytywać dowolne dane wejściowe, np. formularz logowania.
W poniższym przykładzie pokażemy, jak model generyczny może być użyty do formularza logowania:
```php
<?php
class LoginForm extends \yii\base\Model
{
public $username;
public $password;
public function rules()
{
return [
// zasady walidacji
];
}
}
```
W kontrolerze przekażemy instancję tego modelu do widoku, gdzie widżet [[yii\widgets\ActiveForm|ActiveForm]] zostanie użyty do wyświetlenia formularza:
```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$form = ActiveForm::begin([
'id' => 'login-form',
'options' => ['class' => 'form-horizontal'],
]) ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<div class="form-group">
<div class="col-lg-offset-1 col-lg-11">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end() ?>
```
W powyższym kodzie, [[yii\widgets\ActiveForm::begin()|ActiveForm::begin()]] nie tylko tworzy instancję formularza, ale zaznacza też jego początek.
Cała zawartość położona pomiędzy [[yii\widgets\ActiveForm::begin()|ActiveForm::begin()]] i [[yii\widgets\ActiveForm::end()|ActiveForm::end()]] zostanie otoczona tagiem HTML'owym `<form>`.
Jak w każdym widżecie, możesz sprecyzować kilka opcji jak widżet powinien być skonfigurowany przez przekazanie tablicy do metody `begin`.
W tym przypadku dodatkowa klasa CSS i identyfikator ID zostały przekazane do otwierającego tagu `<form>`.
Aby zobaczyć wszystkie dostępne opcje, zajrzyj do dokumentacji API [[yii\widgets\ActiveForm]].
Do utworzenia formularza, wraz z elementami etykiet oraz wszelkimi walidacjami JavaScript, wywoływana jest metoda [[yii\widgets\ActiveForm::field()|ActiveForm::field()]], która zwraca instancję obiektu [[yii\widgets\ActiveField]].
Kiedy rezultat tej metody jest bezpośrednio wyświetlany, będzie on regularnym polem tekstowym.
Aby dostosować pola, możesz używać dodatkowych metod łączonych [[yii\widgets\ActiveField|ActiveField]]:
```php
// pole hasła
<?= $form->field($model, 'password')->passwordInput() ?>
// dodanie podpowiedzi oraz zmiana etykiety
<?= $form->field($model, 'username')->textInput()->hint('Please enter your name')->label('Name') ?>
// utworzenie pola email w formacie HTML5
<?= $form->field($model, 'email')->input('email') ?>
```
Powyższy kod utworzy tagi `<label>`, `<input>`, oraz wszystkie inne, według pól formularza zdefiniowanych w [[yii\widgets\ActiveField::$template|template]].
Nazwa pola określana jest automatycznie z modelu [[yii\base\Model::formName()|form name]] i nazwy atrybutu.
Dla przykładu, nazwą pola dla atrybutu `username` w powyższym przykładzie będzie `LoginForm[username]`.
Ta zasada nazewnictwa spowoduje, że tablica wszystkich atrybutów z formularza logowania będzie dostępna w zmiennej `$_POST['LoginForm']` po stronie serwera.
Określanie atrybutów modelu może być wykonane w bardziej wyrafinowany sposób.
Dla przykładu, kiedy atrybut będzie potrzebował pobierać tablicę wartości, podczas przesyłania wielu plików lub wybrania wielu pozycji, możesz określić go jako tablicę dodając `[]` do nazwy atrybutu:
```php
// pozwól na przesłanie wielu plików
echo $form->field($model, 'uploadFile[]')->fileInput(['multiple'=>'multiple']);
// pozwól na zaznaczenie wielu pozycji
echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C']);
```
Bądź ostrożny podczas nazywania elementów formularza takich jak przyciski wysyłania.
Odnosząc się do [dokumentacji jQuery](https://api.jquery.com/submit/), istnieje kilka zarezerwowanych nazw, które mogą powodować konflikty.
> Formularz i jego elementy podrzędne powinny nie używać nazw pól lub nazw identyfikatorów które tworzą konflikt z właściwościami formularza,
> takich jak `submit`, `length` lub `method`. Konflikty nazw mogą powodować mylące błędy.
> Kompletna lista zasad oraz walidator znaczników dla tych problemów znajduje się na stronie [DOMLint](http://kangax.github.io/domlint/).
Dodatkowe tagi HTML mogą zostać dodane do formularza używając czystego HTML'a lub używając metody z klasy pomocniczej - [[yii\helpers\Html|Html]],
tak jak było to zrobione w przykładzie wyżej z [[yii\helpers\Html::submitButton()|Html::submitButton()]].
> Tip: Jeśli używasz Twitter Bootstrap CSS w Twojej aplikacji, możesz użyć
> [[yii\bootstrap\ActiveForm]] zamiast [[yii\widgets\ActiveForm]].
> Rozszerza on [[yii\widgets\ActiveForm]] i używa specyficzne dla Bootstrap style, podczas generowania pól formularza.
> Tip: Jeśli chcesz oznaczyć wymagane pola gwiazdką, możesz uzyć poniższego kodu CSS:
>
> ```css
> div.required label:after {
> content: " *";
> color: red;
> }
> ```
Tworzenie listy rozwijanej <span id="creating-activeform-dropdownlist"></span>
---------------------
Możemy użyć metody klasy ActiveForm [dropDownList()](http://www.yiiframework.com/doc-2.0/yii-widgets-activefield.html#dropDownList()-detail)
do utworzenia rozwijanej listy:
```php
use app\models\ProductCategory;
use yii\helpers\ArrayHelper;
/* @var $this yii\web\View */
/* @var $form yii\widgets\ActiveForm */
/* @var $model app\models\Product */
echo $form->field($model, 'product_category')->dropdownList(
ProductCategory::find()->select(['category_name', 'id'])->indexBy('id')->column(),
['prompt'=>'Select Category']
);
```
Wartość z Twojego modelu będzie automatycznie wybrana po wyświetleniu formularza.
Dalsza lektura <span id="further-reading"></span>
---------------
Następna sekcja [Walidacja danych wejściowych](input-validation.md) dotyczy walidacji przesłanych przed formularz danych po stronie serwera, przy użyciu ajax oraz walidacji po stronie kklienta.
Aby przeczytać o bardziej złożonych użyciach formularzy możesz zajrzeć do poniższych sekcji:
- [Odczytywanie tablicowych danych wejściowych](input-tabular-input.md - do pobierania danych dla wielu modeli tego samego rodzaju.
- [Pobieranie danych dla wielu modeli](input-multiple-models.md) - do obsługi wielu różnych modeli w tym samym formularzu.
- [Wysyłanie plików](input-file-upload.md) - jak używać formularzy do przesyłania plików.

View File

@@ -0,0 +1,76 @@
Pobieranie danych dla wielu modeli
================================
Kiedy mamy do czynienia z jakimiś skomplikowanymi danymi, jest możliwe, że będziesz musiał użyć wielu różnych modeli aby pobrać te dane od użytkownika.
Dla przykładu: Zakładając, że dane logowania użytkownika zapisane są w tabeli `user`, podczas gdy dane profilu użytkownika są przechowywane w tabeli `profile`,
będziesz chciał pobrać dane od użytkownika przez model `User` oraz `Profile`.
Z modelem Yii oraz wsparciem formularzy, możesz rozwiązać ten problem w sposób nie różniący się za bardzo od przetwarzania pojedyńczego modelu.
W poniższym przykładzie pokażemy jak utworzyć formularz, który pozwoli Ci na zbieranie danych dla obydwu modeli: `User` oraz `Profile`.
Na początek, akcja w kontrolerze do zbierania danych użytkownika oraz danych profilowych może zostać napisana następująco:
```php
namespace app\controllers;
use Yii;
use yii\base\Model;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use app\models\User;
use app\models\Profile;
class UserController extends Controller
{
public function actionUpdate($id)
{
$user = User::findOne($id);
$profile = Profile::findOne($id);
if (!isset($user, $profile)) {
throw new NotFoundHttpException("The user was not found.");
}
$user->scenario = 'update';
$profile->scenario = 'update';
if ($user->load(Yii::$app->request->post()) && $profile->load(Yii::$app->request->post())) {
if ($user->validate() && $profile->validate()) {
$user->save(false);
$profile->save(false);
return $this->redirect(['user/view', 'id' => $id]);
}
}
return $this->render('update', [
'user' => $user,
'profile' => $profile,
]);
}
}
```
W akcji `update`, najpierw ładujemy modele `$user` oraz `$profile`, które zostaną zaktualizowane danymi z bazy danych.
Następnie wywołujemy metodę [[yii\base\Model::load()]] aby wypełnić te dwa modele danymi wprowadzonymi przez użytkownika.
Kolejnie modele zostaną poddane waliacji i, w przypadku prawidłowej walidacji, zapisane.
W przeciwnym razie zostanie wyrenderowany widok `update`, który zawiera następujący kod:
```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$form = ActiveForm::begin([
'id' => 'user-update-form',
'options' => ['class' => 'form-horizontal'],
]) ?>
<?= $form->field($user, 'username') ?>
...other input fields...
<?= $form->field($profile, 'website') ?>
<?= Html::submitButton('Update', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end() ?>
```
Tak jak widzisz, w widoku `update` tworzymy pola tekstowe używając dwóch modeli: `$user` oraz `$profile`.