Вступление
Как то раз пришлось мне создать небольшой проект портала с большим количеством форм как в «back» так и в «front» и тут возник вопрос что использовать? Сначала решил прикрутить что то на подобии Symfony. Но при разработке вышло такое количество строк кода что через некоторое время я сам начал путаться. И тут я решил изобрести велосипед.
Разработка
Для начала создал все таблицы в БД, вот например листинг одной:
CREATE TABLE IF NOT EXISTS `cms_articles` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL, `article` text, `author` varchar(255) DEFAULT NULL, `edited` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `url` varchar(100) DEFAULT NULL, `rating` int(10) NOT NULL DEFAULT '0', `views` int(10) NOT NULL DEFAULT '0', `comments` int(10) unsigned NOT NULL DEFAULT '0', `parent` int(10) NOT NULL DEFAULT '0', `key` text NOT NULL, `desc` text NOT NULL, `tags` varchar(250) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Следующим этапом стало написание HTML кода для формы.
И тут начинается суть моего способа: название элементов в шаблоне должно соответствовать названиям полей таблицы.
<body> <font size='5px' class='title'>[page:name]</font> <span style="float: right; padding-top: 10px;">[page:path]</span> [page:message] <form class="form-list" action="" method="post" name="Form" enctype="multipart/form-data" accept-charset="UTF-8"> <div class="section"> <ul class="tabs"> <li class="current"><a href="#tab1">Основные параметри статьи</a></li> <li class=""><a href="#tab2">Текст статьи</a></li> </ul> <div class="boxu visible"> <div class="item"> <label>Заголовок</label><span class="required">*</span><br> <input type="text" class="big" value="" name="title"> <br> <label class="descript">Заголовок должен содержать смысл страницы</label> </div> <div class="item"> <label>Родитель</label><br> <select class="big" name="parent" id=""> <option selected value="153">- без родителя -</option> [page:parent] </select><br> <label class="descript">Содержимое, к которому добавляется страница</label></div><div class="item "> <label>Адрес</label><br> <input type="text" class="medium" value="" name="url"> <br> <label class="descript">URL адрес страницы</label> </div> <div class="item"> <label>Автор</label><br> <input type="text" class="big" value="" name="author"> <br> <label class="descript">Автор статти ...</label> </div> <div class="item"> <label>Описание</label><br> <textarea class="" name="desc" rows="2"></textarea><br> <label class="descript">Краткое описание сайта. Используются поисковыми системами (Яндекс, Google...)</label> </div> <div class="item"> <label>Ключевые слова</label><br> <textarea name="key" rows="2"></textarea><br> <label class="descript">Ключевые слова через запятую. Используются поисковыми системами (Яндекс, Google...)</label> </div> <table width="600px"> <tr><td> <div class="item"> <label>Рейтинг</label><br> <input type="text" class="lbig" value="" name="rating"> <br> <label class="descript">Рейтинг статти ...</label> </div> </td><td> <div class="item"> <label>Просмотры</label><br> <input type="text" class="lbig" value="" name="views"> <br> <label class="descript">Количество просмотров ...</label> </div> </td></tr> </table> <div class="item"> <label>Разрешыть коментирование</label><br> <span><input name="comments" type="radio" value="1" checked>Да</span> <span><input name="comments" type="radio" value="0">Нет</span><br> Пользователи могут оставлять коментарии.<br> </div> </div> <div class="boxu"> <div class="item"> <label>Текст</label><br> <textarea name="article" rows="28" id="article"></textarea><br> <label class="descript">Текст страницы. Разрешено использование HTML тегов</label> </div> <div class="item"> <label>Теги</label><br> <input type="text" style="width: 200px;" value="" name="tags" id="tags"><br> <label class="descript">Теги к даному тексту (Вводить через кому).</label> </div> <div class="item-buttons"> <input type="submit" name="submit" id="submit" value="Сохранить"> </div> </div> </div> </form> </body>
Вот как выглядит форма (Орфографические ошибки на рисунке остались от заказчика я их не правил):
Далее сохранил шаблон в файл, под названием «article.tpl». И начал писать обработчик. Для его написание решил использовать DOM кто хочет пускай перепишет под «simpleDom».
Вот маленькая функция которая находит элемент по названию а не по ID.
private function GetElementByName($_dom, $_name){ // Experimental search by name $xpath = new DOMXPath($_dom); return $xpath->query('//*[@name="'.$_name.'"]')->item(0); }
Вот тут я написал функцию которая автоматически заполняет форму из таблицы. Учитывая тип элемента и его свойства.
public function LoadShowFormAll($query, $template) { $page_encoding = 'UTF-8'; $dom = new DomDocument(); @$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=' . $page_encoding . '">' . file_get_contents(TMP_DIR.$template.".tpl")); if ($result = $this->base->select($query)) { foreach ($result as $key => $value) { $obj = $this->GetElementByName($dom, $value['name']); //$dom->getElementById($val->name); switch ($obj->nodeName) { case "input": if ($obj->getAttribute('type') == 'radio') { $optionTags = $dom->getElementsByTagName('input'); for ($i = 0; $i < $optionTags->length; $i++) { if ($optionTags->item($i)->getAttribute('name') == $value['name']) { if ($optionTags->item($i)->getAttribute('value') == $value['param']) { $optionTags->item($i)->SetAttribute('checked', 'checked'); } } } if ($value['param'] == 1) { $obj->SetAttribute('checked', 'checked'); } } else if ($obj->getAttribute('type') == 'checkbox') { if ($value['param'] == 1) { $obj->SetAttribute('checked', 'checked'); } } else { $obj->SetAttribute('value', $value['param']); } break; case "textarea": $obj->nodeValue = $value['param']; break; case "select": $optionTags = $obj->getElementsByTagName('option'); for ($i = 0; $i < $optionTags->length; $i++) { if ($optionTags->item($i)->getAttribute('value') == $value['param']) { $optionTags->item($i)->SetAttribute('selected', 'selected'); } } break; case "": break; } } } preg_match_all("#<body>(.*)</body>#isUu", $dom->saveHTML(), $str); return $str[1][0]; }
Использовать следующим образом:
echo $Core->LoadShowForm('SELECT * FROM cms_articles WHERE id='.(int)($get_id), 'article');
После этого возникла необходимость сохранять значения в базу и изменять их для этих заданий я написал две простые функции.
public function InsertNewValue($post, $table, $custom = null) { $query = ''; $sep = false; $tmp = array(); if ($result = $this->base->query("SELECT * FROM `$table` LIMIT 1")) { $fields = $result->fetch_fields(); } else { return false; exit(); } foreach ($post as $col => $val) { $col = mysql_real_escape_string($col); $val = mysql_real_escape_string($val); $tmp[$col] = $val; } if ($custom != null) { foreach ($custom as $col => $val) { $col = mysql_real_escape_string($col); $val = mysql_real_escape_string($val); $tmp[$col] = $val; } } foreach ($tmp as $column => $val) { foreach ($fields as $fval) { if ($column == $fval->name) { if ($sep == true) { $query .= ", `$column` = '$val'"; } else { $query .= "`$column` = '$val'"; } $sep = true; } } } return $this->base->query("INSERT INTO `$table` SET " . $query); } function UpdateValue($post, $table, $custom = null, $where) { $query = ''; $sep = false; $tmp = array(); if ($result = $this->base->query("SELECT * FROM `$table` LIMIT 1")) { $fields = $result->fetch_fields(); } else { return false; exit(); } foreach ($post as $col => $val) { $col = mysql_real_escape_string($col); $val = mysql_real_escape_string($val); $tmp[$col] = $val; } if ($custom != null) { foreach ($custom as $col => $val) { $col = mysql_real_escape_string($col); $val = mysql_real_escape_string($val); $tmp[$col] = $val; } } foreach ($tmp as $column => $val) { foreach ($fields as $fval) { if ($column == $fval->name) { if ($sep == true) { $query .= ", `$column` = '$val'"; } else { $query .= "`$column` = '$val'"; } $sep = true; } } } return $this->base->query("UPDATE `$table` SET " . $query . " WHERE " . $where); }
Ну и остальная часть:
$Core->UpdateValue($_POST, 'cms_articles', null, ' id='.(int)($get_id)); // обновление $Core->InsertNewValue($_POST, 'cms_articles');
Заключение
Лично мне очень понравилось работать таким образом с формами (При том что в проекте их было приблизительно: 250).
При необходимости добавления в форму элемента нужно прописать код в шаблоне и добавить значение в базе и все.
Большое спасибо!
ссылка на оригинал статьи http://habrahabr.ru/post/214085/
Добавить комментарий