Bookmark for researching :D
Abstract Factory
Factory Method
Builder
Adapter
Composite
Decorator
Facade
Proxy
Flyweight
Chain of responsibility
Command
Iterator
Observer
State
Strategy
Template method
Dependency Injection
Repository
Source: http://www.yiiframework.com/forum/index.php/topic/70584-design-pattern-used-in-yii-framework/
Thứ Ba, 18 tháng 4, 2017
Thứ Hai, 17 tháng 4, 2017
RestFul - HTTP status codes
HTTP định nghĩa một nhóm các mã lỗi để có thể dùng trong response API. Dưới đây là danh sách những mã lỗi mà bạn sẽ sử dụng:
- 200 OK - Trả về thành công cho các request GET, PUT, PATCH hoặc DELETE. Cũng có thể sử dụng cho POST
- 201 Created - Trả về cho POST trong trường hợp tạo mới. Nên được kết hợp với Location header để chỉ định tài nguyên mới
- 204 No Content - Trả về thành công cho một request nhưng ko có body (ví dụ DELETE request)
- 304 Not Modified - Khi sử dụng HTTP caching headers
- 400 Bad Request - Yêu cầu không đúng định dạng
- 401 Unauthorized - Xác thực không hợp lệ.
- 403 Forbidden - Xác thực thành công nhưng user không có quyền truy cập tài nguyên
- 404 Not Found - Tài nguyên không tồng tại
- 405 Method Not Allowed - Khi một method HTTP được request nhưng ko cho phép tới user đã xác thực
- 410 Gone - Tài nguyên ở endpoint không còn tồn tại.
- 415 Unsupported Media Type - Content type không hợp lệ
- 422 Unprocessable Entity - Sử dụng cho các lỗi validation
- 429 Too Many Requests - Request bị reject do giới hạn rate limiting
Source: https://viblo.asia/duongichi/posts/1VgZv3mYlAw
Thứ Ba, 14 tháng 2, 2017
Generate APNS p12
- Export the private key from the Keychain and name it
aps_private-key.p12. - Convert the key with the following command
openssl pkcs12 -nocerts -out aps_private-key.pem -in aps_private-key.p12, make sure to enter a PEM pass phrase of at least 4 characters. - Download the certificate for your app from https://developer.apple.com/account/ios/identifiers/bundle/bundleList.action. The downloaded file should be called something like
aps_development.cer. - Convert the certificate with the following command
openssl x509 -in aps_development.cer -inform der -out aps_development.pem - Generate the credentials using
openssl pkcs12 -export -in aps_development.pem -out aps_dev_credentials.p12 -inkey aps_private-key.pem. - And I'm ready to use the credentials generated in step 5 (
aps_dev_credentials.p12).final InputStream certificate = Thread.currentThread().getContextClassLoader() .getResourceAsStream("aps_dev_credentials.p12"); final char[] passwd = {'1','2','3','4'}; final ApnsService apnsService = com.notnoop.apns.APNS.newService() .withCert(certificate, new String(passwd)) .withSandboxDestination().build(); apnsService.testConnection();
Source: http://stackoverflow.com/questions/20077626/whats-the-correct-format-for-java-apns-certificate
Thứ Hai, 13 tháng 2, 2017
ADVANCED MULTI-MODEL FORMS IN YII2
Manage multiple models in a form, supporting validation for each model.
Consider a
Product model that has a single Parcel model related, which represents a parcel that belongs to the product. In the form you want to enter information for the product and the parcel at the same time, and each one should validate according to the model rules.
TABLE MODELS
Start with the following tables:
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `parcel` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`code` varchar(255) NOT NULL,
`height` int(11) NOT NULL,
`width` int(11) NOT NULL,
`depth` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `product_id` (`product_id`),
CONSTRAINT `parcel_product_id` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`)
);
And the models that represent the tables are:
models/Product.php<?php
namespace app\models;
use \yii\db\ActiveRecord;
class Product extends ActiveRecord
{
public static function tableName()
{
return 'product';
}
public function rules()
{
return [
[['name'], 'required'],
[['name'], 'string', 'max' => 255]
];
}
public function getParcel()
{
return $this->hasOne(Parcel::className(), ['product_id' => 'id']);
}
}
models/Parcel.php<?php
namespace app\models;
use \yii\db\ActiveRecord;
class Parcel extends ActiveRecord
{
public static function tableName()
{
return 'parcel';
}
public function rules()
{
return [
[['code', 'height', 'width', 'depth'], 'required'],
[['product_id', 'height', 'width', 'depth'], 'integer'],
[['code'], 'string', 'max' => 255],
[['product_id'], 'exist',
'skipOnError' => true,
'targetClass' => Product::className(),
'targetAttribute' => ['product_id' => 'id']]
];
}
public function getProduct()
{
return $this->hasOne(Product::className(), ['id' => 'product_id']);
}
}
THE FORM MODEL
Now we get to the advanced form, but don’t worry, it’s all quite straight forward. We need a model to handle loading, validating and saving the data.
The purpose of
ProductForm form is to: - handle loading Product and Parcel models - assigning the submitted data to model attributes - saving data after validation - displaying error summaries on the formmodels/form/ProductForm<?php
namespace app\models\form;
use app\models\Product;
use app\models\Parcel;
use Yii;
use yii\base\Model;
use yii\widgets\ActiveForm;
class ProductForm extends Model
{
private $_product;
private $_parcel;
public function rules()
{
return [
[['Product'], 'required'],
[['Parcel'], 'safe'],
];
}
public function afterValidate()
{
$error = false;
if (!$this->product->validate()) {
$error = true;
}
if (!$this->parcel->validate()) {
$error = true;
}
if ($error) {
$this->addError(null); // add an empty error to prevent saving
}
parent::afterValidate();
}
public function save()
{
if (!$this->validate()) {
return false;
}
$transaction = Yii::$app->db->beginTransaction();
if (!$this->product->save()) {
$transaction->rollBack();
return false;
}
$this->parcel->product_id = $this->product->id;
if (!$this->parcel->save(false)) {
$transaction->rollBack();
return false;
}
$transaction->commit();
return true;
}
public function getProduct()
{
return $this->_product;
}
public function setProduct($product)
{
if ($product instanceof Product) {
$this->_product = $product;
} else if (is_array($product)) {
$this->_product->setAttributes($product);
}
}
public function getParcel()
{
if ($this->_parcel === null) {
if ($this->product->isNewRecord) {
$this->_parcel = new Parcel();
$this->_parcel->loadDefaultValues();
} else {
$this->_parcel = $this->product->parcel;
}
}
return $this->_parcel;
}
public function setParcel($parcel)
{
if (is_array($parcel)) {
$this->parcel->setAttributes($parcel);
} elseif ($parcel instanceof Parcel) {
$this->_parcel = $parcel;
}
}
public function errorSummary($form)
{
$errorLists = [];
foreach ($this->getAllModels() as $id => $model) {
$errorList = $form->errorSummary($model, [
'header' => '<p>Please fix the following errors for <b>' . $id . '</b></p>',
]);
$errorList = str_replace('<li></li>', '', $errorList); // remove the empty error
$errorLists[] = $errorList;
}
return implode('', $errorLists);
}
private function getAllModels()
{
return [
'Product' => $this->product,
'Parcel' => $this->parcel,
];
}
}
CONTROLLER ACTIONS
The
ProductForm class is used in actionUpdate() and actionCreate() methods in ProductController.controllers/ProductController.php<?php
namespace app\controllers;
use app\models\form\ProductForm;
use app\models\Product;
use Yii;
use yii\web\Controller;
class ProductController extends Controller
{
public function actionCreate()
{
$productForm = new ProductForm();
$productForm->product = new Product;
$productForm->setAttributes(Yii::$app->request->post());
if (Yii::$app->request->post() && $productForm->save()) {
Yii::$app->getSession()->setFlash('success', 'Product has been created.');
return $this->redirect(['update', 'id' => $productForm->product->id]);
} elseif (!Yii::$app->request->isPost) {
$productForm->load(Yii::$app->request->get());
}
return $this->render('create', ['productForm' => $productForm]);
}
public function actionUpdate($id)
{
$productForm = new ProductForm();
$productForm->product = $this->findModel($id);
$productForm->setAttributes(Yii::$app->request->post());
if (Yii::$app->request->post() && $productForm->save()) {
Yii::$app->getSession()->setFlash('success', 'Product has been updated.');
return $this->redirect(['update', 'id' => $productForm->product->id]);
} elseif (!Yii::$app->request->isPost) {
$productForm->load(Yii::$app->request->get());
}
return $this->render('update', ['productForm' => $productForm]);
}
protected function findModel($id)
{
if (($model = Product::findOne($id)) !== null) {
return $model;
}
throw new HttpException(404, 'The requested page does not exist.');
}
}
FORM VIEWS
The views
views/product/create.php and views/product/update.php will both render a form.<?= $this->render('_form', ['productForm' => $productForm]); ?>
The form will have a section for the Product, and another section for the Parcels.
After saving, each Product and Parcel field will be validated individually, if any fail the error will be displayed at the top as well as on the errored field.
views/product/_form.php<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<div class="product-form">
<?php $form = ActiveForm::begin(); ?>
<?= $productForm->errorSummary($form); ?>
<fieldset>
<legend>Product</legend>
<?= $form->field($productForm->product, 'name')->textInput() ?>
</fieldset>
<fieldset>
<legend>Parcel</legend>
<?= $form->field($productForm->parcel, 'code')->textInput() ?>
<?= $form->field($productForm->parcel, 'width')->textInput() ?>
<?= $form->field($productForm->parcel, 'height')->textInput() ?>
<?= $form->field($productForm->parcel, 'depth')->textInput() ?>
</fieldset>
<?= Html::submitButton('Save'); ?>
<?php ActiveForm::end(); ?>
</div>
ADDITIONAL INFORMATION
The
$_POST data will look something like the following:$_POST = [
'Product' => [
'name' => 'Keyboard and Mouse',
],
'Parcel' => [
'code' => 'keyboard',
'width' => '50',
'height' => '5',
'depth' => '20',
],
];
Source: https://mrphp.com.au/blog/advanced-multi-model-forms-yii2/
Đăng ký:
Bài đăng (Atom)