انجمن پشتیبانی فارسی فریم ورک کیک پی اچ پی - cakephp
entity و table در کیک +3 - نسخه قابل چاپ

+- انجمن پشتیبانی فارسی فریم ورک کیک پی اچ پی - cakephp (http://forum.cakephp.ir)
+-- انجمن: پرسش و پاسخ و رفع اشکال - نسخه ۳ (http://forum.cakephp.ir/forum-37.html)
+--- انجمن: مدل ها (Models) (http://forum.cakephp.ir/forum-42.html)
+--- موضوع: entity و table در کیک +3 (/thread-1614.html)



entity و table در کیک +3 - saeid - 2018/05/10

با سلام
در ادامه تاپیک http://forum.cakephp.ir/thread-1594-post-8841.html و تفاوت های کیک 2 و 3 این مطلب را مینویسیم

در این مطلب میخواهیم تنها در مورد table , entity صحبت کنیم

مطلب را با مثال ادامه میدهیم

- فرض کنید در دیتابیس جدولی داریم به نام articles


- رویداد ها , متد ها , ولیدیشن ها و تمام مواردی که قبلا در

کد پی‌اچ‌پی:
/app/Model/Article.php 
تعریف می شد این بار در Table ذخیره میشود که آدرس آن را در زیر میبینید

کد پی‌اچ‌پی:
src/Model/Table/ArticlesTable.php 


بنابراین میتوان model نسخه 2 را تقریبا با Table نسخه 3 یکی دانست

ٍ
  Heart Entity

اما مطلب مهمی که میخواهیم در مورد آن صحبت کنیم entity میباشد

شاید قبلا که که با کیک 2 کد میزدید مجبور بودید اطلاعات را به صورت آرایه به تابع save ارسال کنید تا ذخیره شود

این مورد در مورد ویرایش / حذف / و خواندن هم صادق بود

اما entity به چه معناست ؟ Dodgy

فرض کنید میخواهیم در مورد چیزی اطلاعات کسب کنیم
میخواهیم فقط در مورد یک شی یا یک مورد خاص صحبت کنیم
در این مثال article
میخواهیم مقاله ای داشته باشیم که شامل id , title, content , created, باشد

تمام این موارد را میخواهیم در یک مجموعه داشته باشیم که به راحتی به آن دسترسی داشته باشیم
به عنوان مثال وقتی خواستیم title یا id    آن دسترسی داشته باشیم بتوانیم  به این شکل عمل کنیم
کد پی‌اچ‌پی:
$article1->id

$article1
->content
$article1
->title 


به راحتی میتواتیم به دیگر عناصر آن  دسترسی داشته باشیم

حال اگر چند مقاله داشته باشیم کافیست object آن ها دسترسی داشته باشیم
کد پی‌اچ‌پی:
$article1

$article2
$article3 

همان طور که میبینید بر خلاف کیک 2 دیگر با آرایه به عناصر دسترسی پیدا نمیکنیم
همه چیز در شیئ موجوده

- شاید حدث زده باشید Tongue
فیلد های دیتابیس ,  عناصر entity ما می باشد
 $article1 و 2 ... entity های ما می باشد

- بنابراین با یک تعریف نه چندان دقیق میتوان گفت هر رکورد در دیتابیس معادل یک entity میباشد

- اگر سه رکود داشته باشیم در واقع 3 entity داریم

entity ها در پوشه
کد پی‌اچ‌پی:
src/Model/Entity
قرار داده میشوند


- خوب آیا تفاوت entity و آرایه در نسخه 2 فقط object بودن آن است ؟
 جواب ) خیر


بگذارید چند مثال را با هم مرور کنیم

در ادامه ممکن است به جای اسم $article1 از $entity استفاده کنیم


- فرض کنید میخواهید بدانید آیا entity که داریم آیا قبلا در دیتابیس ذخیره شده است یا نه ؟
یعنی آیا این entity تازه ساخته شده و مثلا از فرم های داخل سایت آمده یا این که ما آن را از دیتابیس فراخوانی کرده ایم؟

کد پی‌اچ‌پی:
$artlce1->isNew()

//or
$entity->isNew() 

اگر این مقدار مقدار true برگرداند نشان میدهد این entity در دیتابیس وجود ندارد

- خوب؟ به چه دردی میخورد ؟ Rolleyes

- جواب با شما


- یا مثلا میخواهیم رکوردی از دیتابیس را آپدیت کنیم
در این مثال میخواهیم فقط title مقاله را ویرایش کنیم

- در کیک 2 چطور فقط یک فیلد را آپدیت میکردید؟
تمام اطلاعات را به کاربر نشان میدادید و احتمالا کاربر میخواست تنها title را آپدیت کنید

-آیا راهی وجود داشت تشخیص دهیم کاربر تنها title را تغییر داده ؟ یا ما تمام عناصر را ویرایش میکردیم چه تغییر کرده بوده باشه چه نه؟
جواب با شما

اما در کیک 3 میتوانیم تشخصی دهیم Wink

میتوانیم تشخیص دهیم کدام عنصر تغییر کرده و فقط آن را ویرایش کنیم

کد پی‌اچ‌پی:
$entity->getDirty() 

لیست تمام فیلد هایی که تغییر کرده به شما نشان میدهد
در واقع به خود کیک نمایش میدهد و کیک به صورت هوشمند فقط این فیلد ها را آپدیت میکند

- شاید متوجه شده باشید save() دیگر آرایه قبول نمیکند
این تابع و توابع دیگر در ORM به جای آرایه از شما entity طلب میکنند


- میخواهید بدانید کاربر کدام فیلد را اشتباهی وارد کرده؟
مثلا ایمیل نا درست وارد کرده؟
بعد از تعریف validation ها در table  میخواهید بدانید کاربر کدام فیلد ها را نادرست وارد کرده
کد پی‌اچ‌پی:
$entity->getErrors(); 

میخواهید بدانید که فیلد ایمیل درست وارد شده یا نه؟
کد پی‌اچ‌پی:
$entity->getError('email'); 

اگر در view فیلد ها را با input تعریف کنید ( که جدیدا به نام control ) تغییر کرده
ارور هایی که در validation ها تعریف کردید به صورت اتومات به کاربر( در همان input ها )  نشان میدهد


- حال entity را فرستادیم به تابع save برای ذخیره یا ویرایش

کیک قبلا از هر کاری نگاه میکند که خطایی در entity وجود دارد یا خیر
اگر بود که اصلا اقدامی صورت نمیگیرد و این تابع false بر میگرداند

- مگر بررسی وجود خطا در زمان ذخیره (save) صورت نمیگیرد؟

در نسخه 3 این مورد موقع تبدیل آرایه به entity صورت میگیرد

کد پی‌اچ‌پی:
$entity $this->Articles->newEntity()

//
$entity $this->Articles->patchEntity($entity$this->request->getData()); 
   



در مثال بالا این مورد در patchEntity اتفاق می افتد
در این مثال newEntity یک entity خالی بر میگرداند


- نحوه ساخت یک entity به چه شکل می باشد؟

مکان ذخیره سازی و کلاس  entity  به این شکل می باشد

کد پی‌اچ‌پی:
// src/Model/Entity/Article.php

namespace App\Model\Entity;

use 
Cake\ORM\Entity;

class 
Article extends Entity
{


حال میخواهیم یک نمونه از آن بسازیم که چند راه برای آن وجود دارد

- مستقیم
کد پی‌اچ‌پی:
use App\Model\Entity\Article;


$entity = new Article(); 


یا اگر خواستید مقدار دهی اولیه هم داشته باشد
کد پی‌اچ‌پی:
use App\Model\Entity\Article;


$article = new Article([
 
   'id' => 1,
 
   'title' => 'New Article',
 
   'created' => new DateTime('now')
]); 


- راه دیگر استفاده از newEntity می باشد که بالا مثالی برای آن زدیم
- راه دیگر موقع خواندن از دیتابیس هست
- اطلاعات بازگشت شده از دیتابیس به شکل entity می باشد Tongue

کد پی‌اچ‌پی:
$entity $this->Articles->get(10

در این مثال رکورد با کلید  اصلی شماره 10 به صورت entity برگشت داده میشه

- راه های دیگر هم برای فراخوانی از دیتابیس وجود داره

که ویژگی های خودشان را داره
get با توجه به کلید اصلی این کار را میکنه و اگر پیدا نکرد یک exception رخ میده

که بسیار پر کاربر  هم هست

- Idea  توجه

بالاتر گفتیم validation ها موقع تبدیل آرایه به entity اعمال میشه ( همان که که اگر اشتباهی در ورودی کاربر باشه خطایی در entity ذخیره میشه )
فقط در متد های newEntity , newEntities , patchEntity , patchEntities اعمال میشه
و اگر  خواستید از روش مستقیم استفاده کنید validation ها اعمال نمیشه

روش مستقیم بسیار کم در کیک ( کل پروژه با کیک نوشته شود )  استفاده میشه مگر در مواردی که به آن نیاز داشته باشیم


این موارد خلاصه ای از تعریف entity در cakephp بود

کارهای دیگر هم میتواند با entity انجام داد مثل فیلد های مجازی


داکومنت entity
https://book.cakephp.org/3.0/en/orm/entities.html


RE: entity و table در کیک +3 - saeid - 2018/05/10

نمونه کامل یک crud را قرار میدهم تا با نحوه کار با entity را مشاهده کنید
کد پی‌اچ‌پی:
<?php

namespace App\Controller;

use 
App\Controller\AppController;

class 
ArticlesController extends AppController
{

   public function index()
     
       $list 
$this->Articles->find();
       $list $this->paginate($list);
   
       $this
->set(compact('list'));
   }
   

   public 
function add()
         
       $entity 
$this->Articles->newEntity();
       if ($this->request->is(['patch''post''put'])) {
           $entity $this->Articles->patchEntity($entity$this->request->getData());
           if ($this->Articles->save($entity)) {
               $this->Flash->success(__('با موفقیت ثبت گردید'));
               return $this->redirect(['action' => 'index']);
           } else {
               $this->Flash->error(__('خطایی رخ داده لطفا دوباره تلاش کنید'));
           }
       }
       $this->set(compact('entity'));
   }
   
       public 
function edit($id null)
        
       $entity 
$this->Articles->get($id);
       if ($this->request->is(['patch''post''put'])) {
           $entity $this->Articles->patchEntity($entity$this->request->getData());
           if ($this->Articles->save($entity)) {
               $this->Flash->success(__('تغییرات با موفقیت ثبت گردید'));
               return $this->redirect(['action' => 'index']);
           } else {
               $this->Flash->error(__('خطایی رخ داده لطفا دوباره تلاش کنید'));
           }
       }
       $this->set(compact('entity'));

   }
      public function delete($id null)
   {
       $this->request->allowMethod(['post''delete']);
       $entity $this->Articles->get($id);
       if ($this->Articles->delete($entity)) {
           $this->Flash->success(__('با موفقیت حذف شد'));
       } else {
           $this->Flash->error(__('خطلایی رخ داده لطفا دوباره تلاش کنید'));
       }
       return $this->redirect(['action' => 'index']);
   }




RE: entity و table در کیک +3 - saeid - 2018/05/10

توضیحی در مورد اکشن های بالا

Exclamation  index

برای نمایش مقالات  استفاده میکنیم خروجی متد های find , paginate از نوع query است
که موقع استفاده در view به دیتابیس query زده میشه و خروجی از نوع entity برمیگردونه


Idea یعنی خروجی تابع find بر خلاف کیک 2 از نوع شیي query است ( بدون جستجو در دیتابیس )

که شما میتوانید موارد بیشتری ( مثل شرط ) به آن اضافه کنید

و تا زمانی که آن را  استفاده نکردید به دیتابیس کوئری زده نمیشه

Huh  سوالی بود بپرسید

در ویو به این شکل استفاده میشه
کد پی‌اچ‌پی:
  <?php foreach ($list as  $entity) { ?>


  <tr>
    <td><?=  $entity->id ?></td>
    <td><?=  $entity->title ?></td>
  </tr>
  <?php   ?>



Exclamation  اکشن add

ابتدا یک entity خالی ایجاد میکنیم

بعد اگر درخواست از نوع post نبود آن را به ویو میفرستیم

تا در فرم استفاده بشه
در فرم ها از این entity استفاده میشه تا رفتار مناسب آن فیلد به کاربر نشان داده بشه

یعنی اگر فیلد از نوع textarea بود یک textarea به کاربر نشان بده

کد پی‌اچ‌پی:
 <?= $this->Form->create($entity,['class'=>'text-right rtl']) ?>

       <label>title</label>
       <?= $this->Form->control('title',['placeholder'=>"title"]) ?>
       <button type="submit" class="btn btn-primary">ثبت</button>

 <?= $this->Form->end(); ?>


و وقتی کاربر فرم را ارسال میکنه
چون درخواست از نوع post هست وارد بلوک if شده و اطلاعات ارسالی کاربر توسط patchEntity
 
تبدیل به entity میشه و میره برای ذخیره

Idea  توجه کنید عملیات validation در زمان patchEntity صورت میگیره



Exclamation  اکشن edit

مانند add است اما با این تفاوت که این بار entity را از دیتابیس میخونه توسط متد get
ویو آن نیز مثل add هست و تفاوتی نمیکنه

Exclamation  اکش delete

ابتدا entity را از دیتابیس میخوانیم بعد آن را delete میکنیم


Idea  توجه موقع خواندن با get به دلیل این که اگر رکوردی با id مشخص شده وجود نداشت  خطایی رخ میده exception

بنابراین نیازی نیست تا دوباره بررسی کنیم آیا اطلاعات به درستی از دیتابیس خوانده شده یا نه