CakePHP 2.0 - Используйте поле MySQL ENUM с помощником формы для создания Select Input - PullRequest
2 голосов
/ 22 декабря 2011

Я немного исследовал и обнаружил, что помощник по формам в CakePHP неправильно интерпретирует поля ENUM, поэтому он просто выводит текстовый ввод. Я нашел сообщение , в котором предлагалось использовать помощника для этой конкретной цели. Кто-нибудь знает лучший способ достичь этого? Или если разработчики CakePHP намереваются исправить это когда-нибудь?

Спасибо за чтение!

Ответы [ 7 ]

5 голосов
/ 16 октября 2012

Ниже приведено одно из вспомогательных расширений.

App::uses('FormHelper', 'View/Helper');
/**
 * APP/View/Helper/MySqlEnumFormHelper.php
 * It extends FormHelper to implement ENUM datatype of MySQL.
 * 
 * http://blog.xao.jp/blog/cakephp/implementation-of-mysql-enum-datatype-in-formhelper/
 *
 * created Oct. 15, 2012
 * CakePHP 2.2.3
 */
class MySqlEnumFormHelper extends FormHelper
{
    public function input($fieldName, $options = array())
    {
        if (!isset($options['type']) && !isset($options['options'])) {
            $modelKey = $this->model();
            if (preg_match(
                    '/^enum\((.+)\)$/ui',
                    $this->fieldset[$modelKey]['fields'][$fieldName]['type'],
                    $m
               )) {

                $match = trim($m[1]);
                $qOpen = substr($match, 0, 1);
                $qClose = substr($match, -1);
                $delimiter = $qOpen . ',' . $qClose;
                preg_match('/^'.$qOpen.'(.+)'.$qClose.'$/u', $match, $m);
                $_options = explode($delimiter, $m[1]);
                $options['type'] = 'select';
                $options['options'] = array_combine($_options, $_options);

            }
        }
        return parent::input($fieldName, $options);
    }
}
4 голосов
/ 22 декабря 2011

Cake пытается быть независимым от базы данных, и поэтому эта проблема не будет "исправлена", так как это не ошибка.Например, сервер SQL не имеет точного эквивалента типа поля ENUM в MySQL.

Я бы порекомендовал получить список возможных значений перечисления, например:

YourController.php

// get column type
$type = $this->Model->getColumnType('field');

// extract values in single quotes separated by comma
preg_match_all("/'(.*?)'/", $type, $enums);

// enums
var_dump($enums[1]);

Затем используйте поле select в вашем представлении и передайте перечисления в качестве параметров.Ваше текущее значение вы уже будете иметь.Как это звучит?

2 голосов
/ 12 февраля 2012

Я новичок в CakePHP. Я нашел старый код и собрал список выбора enum для вашего удовольствия

/**
* Behavior with useful functionality around models containing an enum type field
*
* Copyright (c) Debuggable, http://debuggable.com
*
*
*
* @package default
* @access public
*
* reworked by Nathanael Mallow for cakephp 2.0
*
*/
/*
 *Use case:Add this (EnumerableBehavior.php)  to app/Model/Behavior/
 *  -->in the Model add public $actsAs = array('Enumerable');     
 *  -->in the *_controller add $enumOptions = $this->Categorie->enumOptions('Section');
 *  -->in the view add print $this->Form->input('{db_field_name}', array('options' =>       $enumOptions, 'label' => 'here'));
 *
 *
 */
class EnumerableBehavior extends ModelBehavior {
/**
 * Fetches the enum type options for a specific field
 *
 * @param string $field 
 * @return void
 * @access public
 */
  function enumOptions($model, $field) {

 //Cache::clear(); 
 $cacheKey = $model->alias . '_' . $field . '_enum_options';
 $options = Cache::read($cacheKey);

 if (!$options) {
  $sql = "SHOW COLUMNS FROM `{$model->useTable}` LIKE '{$field}'";
  $enumData = $model->query($sql);


      $options = false;
      if (!empty($enumData)) {
    $enumData = preg_replace("/(enum|set)\('(.+?)'\)/", '\\2', $enumData[0]['COLUMNS']['Type']);
    $options = explode("','", $enumData);   
      }
      Cache::write($cacheKey, $options);
    }
    return $options;
  }
}
?>
1 голос
/ 29 июля 2013

Если вы хотите использовать MySqlEnumFormHelper вместо обычного и назвать его по $this->Form-> вместо $this->MySqlEnumFormHelper.Вы должны добавить эту строку в вашем контроллере к псевдониму MySqlEnumFormHelper как Form.

public $helpers = array('Form' => array(
    'className' => 'MySqlEnumForm'
));
0 голосов
/ 15 мая 2014

Я создал функцию, которая входит в AppController, чтобы справиться с этим.Я объединил некоторую информацию, представленную выше.

Использование:

$enumList = getEnumValues($ModelField)  where ModelField is in this format:  'Model.Field'

Функция, которую я вставил в AppController:

function getEnumValues($ModelField){

        // split input into Model and Fieldname
        $m = explode('.', $ModelField);
        if ($m[0] == $ModelField) {
                return false;
        } else {                

                (! ClassRegistry::isKeySet($m[0])) ? $this->loadModel($m[0]): false;
                $type = $this->$m[0]->getColumnType($m[1]);
                preg_match_all("/'(.*?)'/", $type, $enums);
                foreach ($enums[1] as $value){$enumList[$value] = $value;}
                return $enumList;
        }                
}
0 голосов
/ 30 сентября 2012

Я думаю, что Поведение это хорошо ... но ключи массива целочисленные

, поэтому я изменил функцию следующим образом

function enumOptions($model, $field) {

 //Cache::clear(); 
 $cacheKey = $model->alias . '_' . $field . '_enum_options';
 $options = Cache::read($cacheKey);
 $enumOptions = array();
 if (!$options) {
 $sql = "SHOW COLUMNS FROM `{$model->useTable}` LIKE '{$field}'";
 $enumData = $model->query($sql);


  $options = false;
  if (!empty($enumData)) {
    $enumData = preg_replace("/(enum|set)\('(.+?)'\)/", '\\2', $enumData[0]['COLUMNS']['Type']);
    $options = explode("','", $enumData);

    foreach ($options as $option) {
        $enumOptions["$option"] = $option;
    }
  }
  Cache::write($cacheKey, $enumOptions);
}
return $enumOptions;

}

вчтобы иметь возможность сохранить правильное значение в поле БД при отправке формы

0 голосов
/ 28 марта 2012

/ * комментарии о предыдущих ответах ***

  • Вариант использования: Добавить это (EnumerableBehavior.php) в приложение / модель / поведение /
  • -> в Модель добавить public $ actAs = array ('Enumerable');
  • -> в действии * _controller добавьте $ enumOptions = $ this-> YourModelName-> enumOptions ('db_field_name');$ this-> set ('enumOptions', $ enumOptions);
  • -> в представлении добавить печать $ this-> Form-> input ('{db_field_name}', массив ('options' =>$ enumOptions, 'label' => 'here'));* * /
...