Slide 1

Slide 1 text

CakePHP 3 Modelless Form +VO 'VLVPLBQIQWPM

Slide 2

Slide 2 text

About Me ໊લɿ໺ౡོʢͷ͡·͔ͨ͠ʣ ॴଐɿΠϥεςΟοΫίϯαϧλϯπגࣜձࣾ
 w CMPHIUUQQIQUJQTDPN w 5XJUUFS!OPKJNBHF

Slide 3

Slide 3 text

CakePHPެࣜͷSlackʹ
 ೔ຊޠνϟϯωϧͰ͖·ͨ͠ ! w IUUQDBLFTGIFSPLVBQQDPN͔Βొ࿥ w νϟϯωϧʮKBQBOFTFʯͰ͓଴͍ͪͯ͠·͢ ! w ৄ͍͠ࢀՃͷ࢓ํͳͲ͸ʮ$BLF1)1ެࣜ4MBDL೔ຊޠʯͰάά͍ͬͯͩ͘͞

Slide 4

Slide 4 text

࿩͢͜ͱ w .PEFMMFTT'PSNͷػೳ w ར༻έʔε

Slide 5

Slide 5 text

Modelless Form ͱ͸

Slide 6

Slide 6 text

Modelless Form 'PSN)FMQFSʁ Ͱ͸ͳͯ͘ ίϯτϩʔϥ͔Βݺͼग़ͯ͠࢖͏΋ͷ

Slide 7

Slide 7 text

Cake\Form\Form wεΩʔϚఆٛ wೖྗݕࠪʢόϦσʔγϣϯʣ wॲཧ࣮ߦ

Slide 8

Slide 8 text

Cake\Form\Form w@CVJME4DIFNB  w@CVJME7BMJEBUPS  w@FYFDVUF

Slide 9

Slide 9 text

ྫ: ͓໰͍߹ΘͤϑΥʔϜ namespace App\Form; ! use Cake\Form\Form; use Cake\Form\Schema; use Cake\Validation\Validator; ! class ContactForm extends Form { ! protected function _buildSchema(Schema $schema) { return $schema->addField('name', 'string') ->addField('email', ['type' => 'string']) ->addField('body', ['type' => 'text']); } ! protected function _buildValidator(Validator $validator) { return $validator->add('name', 'length', [ 'rule' => ['minLength', 10], 'message' => '໊લ͸ඞਢͰ͢' ])->add('email', 'format', [ 'rule' => 'email', 'message' => '༗ޮͳϝʔϧΞυϨε͕ཁٻ͞Ε·͢', ]); } ! protected function _execute(array $data) { // ϝʔϧΛૹ৴͢Δ return true; } } ^@CVJME4DIFNB ^@CVJME7BMJEBUPS ^@FYFDVUF ˞$BLFa'PSNa'PSNΛܧঝ http://book.cakephp.org/3.0/en/core-libraries/form.html

Slide 10

Slide 10 text

ྫ: ͓໰͍߹ΘͤϑΥʔϜ class ContactController extends AppController { public function index() { $contact = new ContactForm(); ! if ($this->request->is('post')) { if ($contact->execute($this->request->data)) { $this->Flash->success('͙͢ʹ͝࿈བྷ͍ͨ͠·͢ɻ'); } else { $this->Flash->error('ϑΥʔϜૹ৴ʹ໰୊͕͋Γ·ͨ͠ɻ'); } } ! $this->set('contact', $contact); } } http://book.cakephp.org/3.0/en/core-libraries/form.html

Slide 11

Slide 11 text

ྫ: ͓໰͍߹ΘͤϑΥʔϜ Form->create($contact); echo $this->Form->input('name'); echo $this->Form->input('email'); echo $this->Form->input('body'); echo $this->Form->button('Submit'); echo $this->Form->end(); http://book.cakephp.org/3.0/en/core-libraries/form.html

Slide 12

Slide 12 text

࢖͍ํ w $BLFa'PSNa'PSNΛܧঝͨ͠ΫϥεΛ࣮૷ w $POUSPMMFSଆͰ࣮૷ͨ͠ΫϥεΛOFX w ϦΫΤετσʔλΛϑΥʔϜͷFYFDVUF ʹ ౉ͯ͠ॲཧ࣮ߦ

Slide 13

Slide 13 text

࢖͍ํ w ςϯϓϨʔτଆͰΤϯςΟςΟͷ୅ΘΓʹ 'PSN)FMQFSDSFBUF΁౉͢ ‣ ೖྗΤϥʔ͕͋Ε͹ΤϥʔදࣔΛߦͬͯ͘ΕΔ

Slide 14

Slide 14 text

Fat Controller! Fat Model

Slide 15

Slide 15 text

Fat Controller ϏδωεϩδοΫΛͲ͜ʹॻ͔͘໰୊ $POUSPMMFS  $PNQPOFOU  .PEFM

Slide 16

Slide 16 text

Fat Model େྔͷϝιου େྔͷόϦσʔγϣϯ ! ॲཧຖʹϞσϧΛ༻ҙ͢Δʁ

Slide 17

Slide 17 text

Α͋͘Δ͜ͱ w ෳ਺ͷϞσϧʹରͯ͠ॲཧΛߦ͍͍ͨ w ೖྗ͞ΕΔύϥϝʔλʔ໊ͱϞσϧͷϑΟʔ ϧυ໊͕ҧ͏ʢ"1*ͱ͔ w 4IFMM͔Β΋ಉ͡ૢ࡞Λ͍ͨ͠

Slide 18

Slide 18 text

શ෦Formʹॻ͚͹͍͍ ೖྗΛ͏͚ͯ ೖྗΛνΣοΫͯ͠ ॲཧͯ͠ ݁ՌΛฦ͢

Slide 19

Slide 19 text

࣮૷ྫ

Slide 20

Slide 20 text

ύεϫʔυมߋϑΥʔϜ w ݱࡏͷύεϫʔυͱ৽͍͠ύεϫʔυɺ৽͍͠ύ εϫʔυͷ֬ೝΛೖྗ w ݱࡏͷύεϫʔυ͕Ұகͯ͠ɺ͔ͭɺ৽͍͠ύε ϫʔυͱ֬ೝೖྗ͕Ұக͢Δ৔߹ʹɺύεϫʔυ Λߋ৽͢Δ w ύεϫʔυ͕ߋ৽͞ΕͨࢫΛϝʔϧૹ৴

Slide 21

Slide 21 text

change_password.ctp Form->create($form, $formOptions); ?> Form->input('password', [ 'label' => ['text' => __('ݱࡏͷύεϫʔυ')], 'placeholder' => __('ύεϫʔυΛೖྗ'), ]); ?> Form->input('new_password', [ 'type' => 'password', 'label' => ['text' => __('৽͍͠ύεϫʔυ')], 'placeholder' => __('ύεϫʔυΛೖྗ'), ]) ?> Form->input('confirm_password', [ 'type' => 'password', 'label' => ['text' => __('ύεϫʔυʢ֬ೝʣ')], 'placeholder' => __('֬ೝͷͨΊ΋͏Ұ౓ೖྗ'), ]) ?> Form->button(__('อଘ'), ['class' => 'btn btn-primary']) ?> Form->end() ?>

Slide 22

Slide 22 text

Controller Auth->user('id')); ! if ($this->request->is(['patch', 'post', 'put'])) { // POST/PUT/PATCH if ($form->execute($this->request->data)) { $this->Flash->success(__('ύεϫʔυΛߋ৽͠·ͨ͠ɻ')); $this->redirect(['action' => 'edit']); } else { $this->Flash->error(__('ύεϫʔυͷߋ৽ʹࣦഊ͠·ͨ͠ɻ')); } } else { // GET $this->request->data['id'] = $this->Auth->user('id'); } ! $this->set('form', $form); } }

Slide 23

Slide 23 text

ChangePasswordForm table = TableRegistry::get('Users'); $this->user = $this->table->get($id); } ! protected function _buildSchema(Schema $schema) { // ϑΟʔϧυఆٛ return $schema ->addField('password', ['type' => 'string']) ->addField('new_password', ['type' => 'string']) ->addField('confirm_password', ['type' => 'string']); } ! protected function _buildValidator(Validator $validator) { // UsersTableʹఆٛͯ͋͠ΔvalidationΛར༻͢Δ // ݱࡏͷύεϫʔυͱҰக͢Δ $this->table->validationRequireCurrentPassword($validator); ! // ৽͍͠ύεϫʔυͱ֬ೝύεϫʔυͷೖྗ͕Ұக͢Δ $validator ->notEmpty('new_password', __('ύεϫʔυ͸ඞͣೖྗ͍ͯͩ͘͠͞ɻ')) ->notEmpty('confirm_password', __('ύεϫʔυ͸ඞͣೖྗ͍ͯͩ͘͠͞ɻ')); $validator->add('new_password', 'minLength', [ 'rule' => ['minLength', 6], 'message' => __('ύεϫʔυ͸6จࣈҎ্Ͱೖྗ͍ͯͩ͘͠͞ɻ'), ]) ->add('new_password', 'maxLength', [ 'rule' => ['maxLength', 255], 'message' => __('ύεϫʔυ͸255จࣈҎ಺Ͱೖྗ͍ͯͩ͘͠͞ɻ'), ]); $validator->add('confirm_password', 'maxLength', [ 'rule' => ['maxLength', 255], 'message' => __('ύεϫʔυ͸255จࣈҎ಺Ͱೖྗ͍ͯͩ͘͠͞ɻ'), ]) ->add('confirm_password', 'compareWith', [ 'rule' => ['compareWith', 'new_password'], 'message' => __('ύεϫʔυ͕Ұக͠·ͤΜɻ'), ]); ! return $validator; } ! protected function _execute(array $data) { // ύεϫʔυߋ৽ $newpassword = ['password' => $data['new_password']]; $this->table->patchEntity($this->user, $newpassword); if (!$this->table->save($this->user)) { return false; } ! // send email $mailer = new Email('default'); $mailer->to($this->user) ->subject(__('ύεϫʔυ͕มߋ͞Ε·ͨ͠')) ->template('change_password') ->viewVars(['user' => $user]) ->send(); ! return true; } ! public function getUser() { return $this->user; } }

Slide 24

Slide 24 text

ChangePasswordForm table = TableRegistry::get('Users'); $this->user = $this->table->get($id); } ! !

Slide 25

Slide 25 text

ChangePasswordForm addField('password', ['type' => 'string']) ->addField('new_password', ['type' => 'string']) ->addField('confirm_password', ['type' => 'string']); } ! ! ! !

Slide 26

Slide 26 text

ChangePasswordForm table->validationRequireCurrentPassword($validator); ! // ৽͍͠ύεϫʔυͱ֬ೝύεϫʔυͷೖྗ͕Ұக͢Δ $validator ->notEmpty('new_password', __('ύεϫʔυ͸ඞͣೖྗ͍ͯͩ͘͠͞ɻ')) ->notEmpty('confirm_password', __('ύεϫʔυ͸ඞͣೖྗ͍ͯͩ͘͠͞ɻ')); $validator->add('new_password', 'minLength', [ 'rule' => ['minLength', 6], 'message' => __('ύεϫʔυ͸6จࣈҎ্Ͱೖྗ͍ͯͩ͘͠͞ɻ'), ]) ->add('new_password', 'maxLength', [ 'rule' => ['maxLength', 255], 'message' => __('ύεϫʔυ͸255จࣈҎ಺Ͱೖྗ͍ͯͩ͘͠͞ɻ'), ]); $validator->add('confirm_password', 'maxLength', [ 'rule' => ['maxLength', 255], 'message' => __('ύεϫʔυ͸255จࣈҎ಺Ͱೖྗ͍ͯͩ͘͠͞ɻ'), ]) ->add('confirm_password', 'compareWith', [ 'rule' => ['compareWith', 'new_password'], 'message' => __('ύεϫʔυ͕Ұக͠·ͤΜɻ'), ]); !

Slide 27

Slide 27 text

ChangePasswordForm $data['new_password']]; $this->table->patchEntity($this->user, $newpassword); if (!$this->table->save($this->user)) { return false; } ! // มߋͨ͠Βϝʔϧૹ৴ $mailer = new Email('default'); $mailer->to($this->user) ->subject(__('ύεϫʔυ͕มߋ͞Ε·ͨ͠')) ->template('change_password') ->viewVars(['user' => $user]) ->send(); ! return true; }

Slide 28

Slide 28 text

·ͱΊ

Slide 29

Slide 29 text

·ͱΊ w .PEFMMFTT'PSN͸εΩʔϚఆٛɺೖྗݕূɺॲཧ࣮ߦ͕Ͱ͖Δ w .PEFMMFTT'PSNΛ࢖͏ͱίϯτϩʔϥͷهड़Λ؆ૉԽͰ͖Δ w .PEFMMFTT͚ͩͲɺॲཧதʹ.PEFMΛར༻ͯ͠΋0, w ϏδωεϩδοΫΛهड़͢Δͷʹద͍ͯ͠Δ

Slide 30

Slide 30 text

υΩϡϝϯτ w $PPLCPPL.PEFMMFTT'PSN
 IUUQCPPLDBLFQIQPSHFODPSFMJCSBSJFTGPSNIUNM w ೔ຊޠ༁
 IUUQCPPLDBLFQIQPSHKBDPSFMJCSBSJFTGPSNIUNM

Slide 31

Slide 31 text

ฉ͖͍ͨ͜ͱ͋Δʁ

Slide 32

Slide 32 text

͓·͚

Slide 33

Slide 33 text

Entityͷศརϝιου w EJSUZ  w HFU0SJHJOBM  w FYUSBDU  w FYUSBDU0SJHJOBM  w FYUSBDU0SJHJOBM$IBOHFE

Slide 34

Slide 34 text

Entityͷศརϝιου w EJSUZ  ‣ ϓϩύςΟ͕มߋ͞Ε͔ͨνΣοΫ $entity = $Articles->get($id); // title = 'Original Title' $entity->title = 'New Title'; $entity->dirty('title'); // true

Slide 35

Slide 35 text

Entityͷศརϝιου w HFU0SJHJOBM  ‣ มߋલͷ஋Λऔಘ $entity = $Articles->get($id); // title = 'Original Title' $entity->title = 'New Title'; $entity->getOriginal('title'); // 'Original Title'

Slide 36

Slide 36 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠