<?php
$list = array('apple', 'banana', 'orange', 'melon', 'mango');
$html = new HtmlInput;
?>
<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <?php
        echo $html->setName('fruit')
                //항목 설정
                ->addItemArray($list)
                //선택 값 === 로 비교하니 자료형을 맞춰주세요.
                ->addSelectValue(0)
                //셀력트박스 만들기
                ->makeSelect();

        echo '';

        echo $html->setName('fruit')
                //항목 설정
                ->addItemArray($list)
                //항목 값을 텍스트로 설정?
                ->setValueType(HtmlInput::ITEM_TEXT)
                //선택값 비교시 텍스트와 비교
                ->setCompareType(HtmlInput::ITEM_TEXT)
                //선택값
                ->addSelectValue('banana')
                //라디오버튼 만들기
                ->makeInput(HtmlInput::INPUT_RADIO);

        echo '';

        echo $html->setName('fruit[]')
                //항목 설정
                ->addItem('', 'All', array('onclick' => "alert('all!')"))
                //항목 설정
                ->addItemArray($list)
                //항목 값을 텍스트로 설정?
                ->setValueType(HtmlInput::ITEM_TEXT)
                //선택값 비교시 텍스트와 비교
                ->setCompareType(HtmlInput::ITEM_TEXT)
                //선택값
                ->addSelectValueArray(array('orange', 'mango'))
                //특정 항목에 속성을 설정
                ->addItemAttr(HtmlInput::ITEM_TEXT, 'banana', array('onclick' => "alert('banana!')"))
                //라디오버튼 만들기
                ->makeInput(HtmlInput::INPUT_CHECKBOX);
        ?>
    </body>
</html>
<?php

/**
 * Onhae
 *
 * 라디오버튼, 체크박스, 셀렉트박스 html 제작
 *
 * @author      onhae
 * @copyright   onhae
 * @license     GPL
 * @link        http://www.onhae.com
 * @since       Version 1.0
 */
class HtmlInput {

    const INPUT_RADIO = 'radio';
    const INPUT_CHECKBOX = 'checkbox';
    const ITEM_TEXT = 'Text';
    const ITEM_VALUE = 'Value';

    /**
     * 속성 배열
     * @var array
     */
    protected $attrArray = array();

    /**
     * 태그 이름
     * @var string 
     */
    protected $name;

    /**
     * 태그 아이디
     * @var string 
     */
    protected $id;

    /**
     * 태그 클래스
     * @var string 
     */
    protected $class;

    /**
     * 선택 값 배열
     * @var string
     */
    protected $selectValueArray = array();

    /**
     * 항목 배열
     * @var array 
     */
    protected $itemArray = array();

    /**
     * 값 타입
     * @var string ITEM_VALUE, ITEM_TEXT
     */
    protected $valueType = self::ITEM_VALUE;

    /**
     * 문자열 타입
     * @var string ITEM_VALUE, ITEM_TEXT
     */
    protected $textType = self::ITEM_TEXT;

    /**
     * 비교 타입
     * @var string ITEM_VALUE, ITEM_TEXT
     */
    protected $compareType = self::ITEM_VALUE;

    /**
     * 값 타입 설정
     * @param string $valueType ITEM_VALUE, ITEM_TEXT
     * @return this
     */
    public function setValueType($valueType) {
        $this->valueType = $valueType;
        return $this;
    }

    /**
     * 문자열 타입 설정
     * @param type $textType ITEM_VALUE, ITEM_TEXT
     * @return this
     */
    public function setTextType($textType) {
        $this->textType = $textType;
        return $this;
    }

    /**
     * 비교할 타입 설정
     * @param type $compareType ITEM_VALUE, ITEM_TEXT
     * @return this
     */
    public function setCompareType($compareType) {
        $this->compareType = $compareType;
        return $this;
    }

    /**
     * 항목 배열 설정
     * @param array $itemArray
     * @return this
     */
    public function addItemArray(array $itemArray) {
        foreach ($itemArray as $value => $text) {
            $this->itemArray[] = new HtmlInputItem($value, $text);
        }
        return $this;
    }

    /**
     * 항목 추가
     * @param string $value
     * @param string $text
     * @param array $attr 항목 옵션
     * @return this
     */
    public function addItem($value, $text, array $attr = array()) {
        $this->itemArray[] = new HtmlInputItem($value, $text, $attr);
        return $this;
    }

    /**
     * 이름 설정
     * @param string $name
     * @return this
     */
    public function setName($name) {
        $this->name = $name;
        return $this;
    }

    /**
     * 아이디 설정
     * @param string $id
     * @return this
     */
    public function setId($id) {
        $this->id = $id;
        return $this;
    }

    /**
     * 클래스 설정
     * @param string $class
     * @return this
     */
    public function setClass($class) {
        $this->class = $class;
        return $this;
    }

    /**
     * 선택값 설정 ===로 비교하니 변수형을 맞춰주세요
     * @param string $selectValue
     * @return this
     */
    public function addSelectValue($selectValue) {
        $this->selectValueArray[] = $selectValue;
        return $this;
    }

    /**
     * 선택 값 배열 설정 ===로 비교하니 변수형을 맞춰주세요
     * @param array $selectValueArray
     * @return this
     */
    public function addSelectValueArray($selectValueArray) {
        $this->selectValueArray = array_merge($this->selectValueArray, $selectValueArray);
        return $this;
    }

    /**
     * 속성 배열 설정
     * @param string $key
     * @param string $value
     * @return this
     */
    public function addAttrArray($attrArray) {
        $this->attrArray = array_merge($this->attrArray, $attrArray);
        return $this;
    }

    /**
     * 속성 추가
     * @param string $key
     * @param string $value
     * @return this
     */
    public function addAttr($key, $value) {
        $this->attrArray[$key] = $value;
        return $this;
    }

    /**
     * 항목 속성 추가
     * @param type $type ITEM_VALUE, ITEM_TEXT
     * @param type $value
     * @param array $attrArray
     * @return this
     */
    public function addItemAttr($type, $value, array $attrArray) {
        $method = 'get' . $type;
        foreach ($this->itemArray as $item/* @var $item HtmlInputItem */) {
            if ($item->$method() !== $value) {
                continue;
            }
            $item->addAttrArray($attrArray);
            break;
        }
        return $this;
    }

    /**
     * 속성 문자열로 가져오기
     * @return type
     */
    protected function fetchAttrString() {
        $attr = array();

        foreach (array('id', 'name', 'class') as $value) {
            if (is_null($this->{$value}) === true) {
                continue;
            }
            $attr[$value] = sprintf('%s="%s"', $value, $this->{$value});
        }

        foreach ($this->attrArray as $key => $value) {
            $attr[] = sprintf('%s="%s"', $key, $value);
        }

        if (count($attr) === 0) {
            return '';
        } else {
            return ' ' . implode(' ', $attr);
        }
    }

    /**
     * 셀렉트 박스 만들기
     * @return string 
     */
    public function makeSelect() {
        $startTag = "<select{$this->fetchAttrString()}>";

        $optionTag = '';
        foreach ($this->itemArray as $item/* @var $item HtmlInputItem */) {
            $valueType = 'get' . $this->valueType;
            $textType = 'get' . $this->textType;
            $optionTag .= sprintf('<option value="%s"%s%s>%s</option>', htmlspecialchars($item->$valueType()), ($this->chkSelect($item) === true) ? ' selected="selected"' : '', $item->fetchAttrString(), htmlspecialchars($item->$textType())
            );
        }

        $endTag = '</select>';

        $this->clean();
        return $startTag . $optionTag . $endTag;
    }

    /**
     * 입력품 만들기
     * @param type $type INPUT_RADIO, INPUT_CHECKBOX 클래스 상수 
     * @param type $glue 태그끼리 연결 문자열
     * @return type
     */
    public function makeInput($type, $glue = ' ') {
        $this->addAttr('type', $type);

        $tagArray = array();
        foreach ($this->itemArray as $item/* @var $item HtmlInputItem */) {
            $valueType = 'get' . $this->valueType;
            $textType = 'get' . $this->textType;

            $tagArray[] = sprintf('<label><input type="%s" value="%s"%s%s/>%s</label>', $type, htmlspecialchars($item->$valueType()), ($this->chkSelect($item) === true) ? ' checked="checked"' : '', $item->fetchAttrString(), htmlspecialchars($item->$textType())
            );
        }
        $this->clean();
        return implode($glue, $tagArray);
    }

    /**
     * 선택값 확인
     * @param HtmlInputItem $item
     * @return type
     */
    protected function chkSelect(HtmlInputItem $item) {
        if ($this->compareType === self::ITEM_VALUE) {
            return (array_search($item->getValue(), $this->selectValueArray, true) === false) ? false : true;
        } else {
            return (array_search($item->getText(), $this->selectValueArray, true) === false) ? false : true;
        }
    }

    /**
     * 청소한다
     * @return this
     */
    public function clean() {
        $this->attrArray = array();
        $this->itemArray = array();
        $this->selectValueArray = array();
        $this->valueType = self::ITEM_VALUE;
        $this->textType = self::ITEM_TEXT;
        $this->compareType = self::ITEM_VALUE;
        unset($this->class);
        unset($this->id);
        unset($this->name);

        return $this;
    }

}

/**
 * Onhae
 *
 * HtmlInputItem
 *
 * @author      onhae
 * @copyright   onhae
 * @license     GPL
 * @link        http://www.onhae.com
 * @since       Version 1.0
 */
class HtmlInputItem {

    /**
     * 값
     * @var string 
     */
    protected $value;

    /**
     * 문자
     * @var string 
     */
    protected $text;

    /**
     * 속성 배열
     * @var array
     */
    protected $attrArray = array();

    /**
     * 생성자
     * @param type $value 값
     * @param type $text 문자
     * @param array $attr 속성 배열
     */
    public function __construct($value, $text, array $attr = array()) {
        $this->value = $value;
        $this->text = $text;
        $this->attrArray = $attr;
    }

    /**
     * 값 얻기
     * @return string
     */
    public function getValue() {
        return $this->value;
    }

    /**
     * 문자 얻기
     * @return string
     */
    public function getText() {
        return $this->text;
    }

    /**
     * 속성 배열추가
     * @param type $attrArray
     */
    public function addAttrArray(array $attrArray) {
        $this->attrArray = array_merge($this->attrArray, $attrArray);
    }

    /**
     * 속성 문자열로 얻기
     * @return string
     */
    public function fetchAttrString() {

        if (count($this->attrArray) === 0) {
            return '';
        }

        $attr = array();
        foreach ($this->attrArray as $key => $value) {
            $attr[] = sprintf('%s="%s"', $key, $value);
        }

        return ' ' . implode(' ', $attr);
    }

}