2013-02-28 18 views
5

Giriş

Yeniden kullanılabilir bir Admin modülü üzerinde çalışıyorum; Kimlik Doğrulama ve ACL'yi kullanmaktan sorumludur. Bu modül, uygulanan diğer modüllerin devralacağı bir temel denetleyici ile birlikte gelir. Yani bu denetleyici Cp\AdminController'dur ve erişilemez, ancak diğer tüm denetleyiciler tarafından devralınmıştır.Zend Framework 2 - Çıktı form öğesi, HTML alanı olarak nesneler

sorun

Ben çeşitli işlemler vardır varsayılan/ev denetleyicisi Cp\HomeController var; giriş, çıkış ve unutulmuş/şifre sıfırlama. Şu anda Cp\HomeController::indexAction üzerinde çalışıyorum. Bu yöntemin içinde ben sadece aşağıdakileri yapın:

// ... controller logic ... 
public function indexAction() 
{ 
    if ($this->getAuth()->hasIdentity()) { 
     # XXX: This is the authorised view/dashboard. 
    } else { 
     # XXX: This is the unauthorised view; login page. 

     $loginForm = new Form\Login(); 

     # XXX: validation, and login form handling here. 

     return array(
      'form' => $loginForm 
     ); 
    } 
} 
// ... controller logic ... 
mesele burada

, varsayılan olarak Cp\HomeController, ./module/Cp/view/cp/home/index.phtml şablonu kullanan; Kendi formu sınıfında ./module/Cp/src/Cp/Form.php ile Zend\Form artırdık

<h1>Authorisation Required</h1> 

<section id="admin-login"> 
    <?= $form ?> 
</section> 

bu daha sonra herhangi bir biçimde sınıfları tarafından uzatılır,: gibi ve görünüyor. _Bu göz önünde bulundurularak, bu sınıfı tamamen ayrıştırılmış ve tamamen yeniden kullanılabilir hale getirecek şekilde Uygulamaya taşıyacağım.

<?php 
// @file: ./module/Cp/src/Cp/Form.php 

namespace Cp; 

use Zend\Form\Form as ZendForm; 
use Zend\Form\Fieldset; 
use Zend\InputFilter\Input; 
use Zend\InputFilter\InputFilter; 
use Zend\View\Model\ViewModel; 
use Zend\View\Renderer\PhpRenderer; 
use Zend\View\Resolver; 

class Form extends ZendForm 
{ 
    /** 
    * Define the form template path. 
    * @var String 
    */ 

    protected $__templatePath; 

    /** 
    * Define the view variables. 
    * @var Array 
    */ 

    protected $__viewVariables = array(); 

    /** 
    * Set the view variable. 
    * @param String $key The index for the variable. 
    * @param Mixed $value The value for the view variable. 
    * @return Cp\Form 
    */ 

    public function set($key, $value) 
    { 
     $this->__viewVariables[$key] = $value; 
     return $this; 
    } 

    /** 
    * Set the template path. 
    * @param String $path The path for the template file. 
    * @return Cp\Form 
    */ 

    public function setTemplatePath($path) 
    { 
     $this->__templatePath = $path; 
     return $this; 
    } 

    /** 
    * When the object is buffered in output, we're going to generate the view 
    * and render it. 
    * @return String 
    */ 

    public function __toString() 
    { 
     // Define our template file as form for resolver to map. 
     $map = new Resolver\TemplateMapResolver(array(
      'form' => $this->__templatePath 
     )); 

     // Define the render instance responsible for rendering the form. 
     $renderer = new PhpRenderer(); 
     $renderer->setResolver(new Resolver\TemplateMapResolver($map)); 

     // The form view model will generate the form; parsing the vars to it. 
     $view = new ViewModel(); 
     $view->setVariable('form', $this); 
     $view->setTemplate('form'); 

     foreach ($this->__viewVariables as $key => $value) { 
      if (! property_exists($view, $key)) { 
       $view->setVariable($key, $value); 
      } 
     } 

     return $renderer->render($view); 
    } 
} 

benim Girişi formunu, standart bir e-posta adresi ve şifre alanını, kimlik doğrulama oluşabilir yerde yeniden kullanılabilir bir şey yaratmak için bu form sınıfı devralır.

<?php 

namespace Cp\Form; 

use Zend\Form\Element; 

class Login extends \Cp\Form 
{ 
    public function __construct($name = 'Login', $action) 
    { 
     // Parse the form name to our parent constructor. 
     parent::__construct($name); 

     // Override default template, defining our form view. 
     $this->setTemplatePath(MODULE_DIR . 'Cp/view/cp/form/login.phtml'); 

     // Create our form elements, and validation requirements. 
     $email = new Element\Email('email'); 
     $email->setLabel('E-mail Address'); 

     $password = new Element\Password('password'); 
     $password->setLabel('Password'); 

     $submit = new Element\Submit('login'); 

     $this->setAttribute('action', $action) 
      ->setAttribute('method', 'post') 
      ->setAttribute('autocomplete', 'autocomplete') 
      ->add($email) 
      ->add($password) 
      ->add($submit); 
    } 
} 

miras __toString yöntem tanımlanmış formu görünümünü almak ve bunu işlemek hangi. Bu benim sorunum nerede ve benim sorumu oluşur. Görünüm içinde (aşağıya bakınız) HTML öğelerini kodlamadan çerçeveyi kullanarak formu oluşturmaya çalışıyorum. Cp\Form\Login sınıfı, farklı bir alan ya da ek alanlar, isteğe bağlı ya da zorunlu ya da koşullu olarak genişletilip değiştirilebilir.

Hızla, Zend'i aşağıdaki HTML'yi oluşturmanın bir yolu var mı? Kısmi görünümler kullanmadan veya fiziksel olarak <input type="<?= ... ?>" name="<?= ... ?>" /> yazarak. Bunun nedeni, özniteliklerin denetleyiciler içinde tanımlanabilmesi veya üzerine yazılabilmesidir, bu nedenle öznitelikler bu noktada bilinmemektedir; ve esnekliğe açık olmalıdır.

<section class="authentication-form"> 
    <h2>Authentication Required</h2> 

    <!-- How-to: Generate the <form> tag and all it's attributes. --> 
    <?= $form->openTag() ?> 

    <? if ($ipAllowed): ?> 
     <p>Please choose an account to log in through.</p> 

     <fieldset> 
      <?= $form->get('email') ?> 
     </fieldset> 
    <? else: ?> 
     <p>Please log in using your e-mail address and password.</p> 

     <fieldset> 
      <?= $form->get('email') ?> 
      <?= $form->get('password') ?> 
     </fieldset> 
    <? endif ?> 

    <div class="action"> 
     <!-- How-To: Generate the <input type="submit" name="" ... attributes ... /> 
     <?= $form->get('login') ?> 
    </div> 

    <!-- How-To: Generate the form close tag. 
    <?= $form->closeTag() ?> 
</section> 

Umarım bu, daha önce olduğundan daha nettir.

+0

basitçe "echo $ this-> form ($ form);". Tam sorunun ne olduğunu açıklayabilir misiniz? – Ocramius

+0

Soruyu güncelledim, umarım sorumum ve niyetler daha açık – ash

cevap

4

Asıl sorunun ne olduğundan emin değilim. Açıkça belirtebilir misiniz lütfen?

Zend\Form

kendisini işlemek kalmaması tasarlanmıştır ancak görünüm yardımcıları tarafından verilir: Sen elbette sizin için yapar bir görünüm yardımcı yazabilirsiniz

<?php 
echo $this->form()->openTag($this->form); 
echo $this->formCollection($this->form); 
echo $this->form()->closeTag($this->form); 

.

<?php 
namespace MyModule\View\Helper; 

use Zend\View\Helper\AbstractHelper; 


class RenderForm extends AbstractHelper 
{ 
    public function __invoke($fieldsToRender, $form) 
    { 
     $html = $this->view->form()->openTag($form) . PHP_EOL; 

     foreach ($fieldsToRender as $fieldName) { 
      $element = $form->get($fieldName); 
      $html .= $this->view->formRow($element) . PHP_EOL; 
     } 

     $html .= $this->view->form()->closeTag($form) . PHP_EOL; 

     return $html; 
    } 
} 

Sonra görünümü komut gereken tüm renderForm() çağırmaktır;

Alternatif olarak, işlemek ve böyle bir şey yapan bir görünüm yardımcı yazmak için öğelerin listesini götüren bir görünüm yardımcı yazabilirsiniz .Rob tepkisini kullanma

+0

Ash'in, kendi görüş modelinin içine yerleştirilmesi gibi yardımcıların kullanımı olmadan formun oluşturulmasının bir yolunu istediğini düşünüyorum. Başka bir oluşturucu kullanan görünüm modeli) – Ocramius

+0

oh! Bunu yapmanın en kolay yolu, ServiceManager formunu fark etmektir ve ardından bir render() yönteminde bir PHPRenderer'ı alır ve burada yardımcı yardımcıları kullanır. –

+0

Üzgünüm çocuklar, makalemi yeniden yazdım, umarım biraz daha açık olur. Özgün sorumun _was_ diye belirsiz düşünüyorum. @Ocramius - tam olarak bunu yapmaya çalışıyorum. – ash

0

, ben metin olarak farklı alanlar (örneğin bir Vakfı 5 satırı olan) işlemek için kendi yardımcı inşa: o nasıl inşa edildiğini, yaparsın bilmeden bir form render konusunda ise

namespace MyApp\View\Helper; 

use Zend\Form\View\Helper\FormRow; 
use Zend\Form\ElementInterface; 


class RenderForm extends AbstractHelper 
{ 
    public function __invoke(ElementInterface $element) 
    { 

     $html = ''; 
     $value = ''; 

     $attributes = $element->getAttributes(); 

     $type = $attributes['type']; 
     $label = $element->getLabel(); 

     if($type == 'text' or $type == 'textarea' or $type == 'datetime' or $type == 'hidden'){ 
      $value = $element->getValue(); 
     } 

     if($type == 'select'){ 
      $selectedValue = $element->getValue(); 
      if(is_bool($selectedValue)){ 
       $selectedValue = (int) $selectedValue; 
      } 
      $options = $element->getValueOptions(); 
      $values = ''; 
      foreach($options as $value => $option){ 
       if((!empty($value) or $value == 0) and $value === $selectedValue){ 
        $values .= $option . '<br />'; 
       } 
      } 
      $value = $values; 
     } 

     if($type == 'multi_checkbox' ){ 
      $selectedOptions = $element->getValue(); 
      $options   = $element->getValueOptions(); 
      $values = ''; 
      foreach($options as $option){ 
       $optionValue = $option[ 'value' ]; 
       if( in_array($optionValue, $selectedOptions)){ 
        $values .= $option[ 'label' ]. '<br />'; 
       } 
      } 

      $value = $values; 
     } 

     if($value == ''){ 
      $value = 'N/A'; 
     } 

     $html .= '<div class="row"> 
         <div class="small-12 column"> 
          <div class="row"> 
           <div class="small-3 columns"><label class="right inline" for="tag_id">' . $label . '</label></div> 
           <div class="small-9 columns left" style="padding-top:10px">' . $value . '</div> 
          </div> 
         </div> 
        </div>'; 
     return $html; 
    } 
} 
İlgili konular