Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Теги(метки) под Zend Framework. 
:(
    Опции темы
Fulminator
Дата 28.11.2007, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 16.2.2006
Где: Молдова

Репутация: нет
Всего: нет



Привет. Хочу поделиться своим способом реализации тегов(меток) под Zend Framework. Предположим, что он установлен, и вы умеете под него немного писать. Если не умеете - самое время научиться, это довольно просто и чует мой главный орган интуиции, что будущее за подобными штуковинами. 
Это будет простое приложение, позволяющее добавлять, удалять и редактировать новости или записи в личном дневнике - подогнать можно под разное. Для начала распланируем БД и создадим нужные таблицы. Всего их три. В первой таблице будут храниться сами посты, во второй теги и третья, кросс-таблица, будет содержать id поста и имя привязанного к нему тега. Что-то вроде того:
POSTS: post_Id;post_title;post_post;post_date. TAGS: tag_name. POSTS2TAGS: post_id, tag_name. 
Допустим, за все эту прелесть будет отвечать AdminController.php, как вы будете проверять, что это действительно админ - проблема! Ваша проблема, я не об этом. И так первым action'ом будет addPostAction(). С простецкой, можно сказать, детсадовской логикой. Если _POST не отослан - выводим HTML-форму для заполнения, а если отослан - данные обрабатываем и куда нужно пихаем. Для обработки и запихивания воспользуемся богатым арсеналом зенда и методами классов Tags, Posts, Posts2Tags. Вот написанием этих методов и займемся. Понадобится 3 модели: Posts.php, Posts2Tags.php, Tags.php. 
Для начала нужно привести в чувство теги (подрузумевается, что пустым _POST[tags] быть не может, хотя бы одним тегом, но пометить надо), которые сейчас в виде строчки и через запятую, вроде: tag0, tag1, tag2. Пусть даже невнимательный пользователь забыл запяту в конце или лишний пробел, preWorkTags() решит эту проблему. preWorkTags() находится у меня в модели tags.php - это не совсем правильно.. )) 
Код

function preWorkTags($tags) {
    $tags = explode(',',$tags);
    $checkKey = count($tags);
    if(empty($tags[$checkKey-1]))
        unset($tags[$checkKey-1]);
    return $tags;
}


Все просто. Берется строка, по запятой разбивается в массив. Если в конце была забыта запятая, происходит unset пустой ячейки. Дальше нужно проверить, существует ли тег. И если не существует, нужно его добавить.  

Код

function tagExists($tagName) {
    $where = "tag_name='".$tagName."'";
    if($this->fetchRow($where))
        return true;
    return false;
}

function addNewTag($tagName) {
    $data = array('tag_name'=>$tagName);
    $this->insert($data);
    return $tagName;
}


С тегами разобрались, самое время добавить запись в таблицу для этого нужно сделать массив с данными и отправить его в addPost. 
$data = array('post_title'=>$title,'post_post'=>$post,'post_date'=>$date); // вот например такой массив

Код

function addPost($data) {
    if($this->insert($data)) {
        return $this->lastInsertId();
    }
    else {
        return false;
    }
}


Функция возвращает id добавленного поста, для того чтобы чуть дальше можно было прилинковать теги в кросс-таблице. 

Код

function linkPost2Tags($postId,$tagsName) {
    for ($i=0;$i<count($tagsName);$i++) {
        $data = array('post_id'=>$postId,'tag_name'=>$tagsName[$i]);
        $this->insert($data);
    }
}


линкуем. linkPost2Tags() должна находится в модели Posts2Tags.php
Вот и всё. С добавлением покончено, можно приступить и к редактированию. Отличаться оно сильно не будет editPostAction() в _GET получает id поста и если _POST не отосланы выводит форму для редактирования, в противном случае - редактирует  Можно просто закопипастить addPostAction() и изминить пару строк. Вместо addPost($data) - editPost($data,$where). И перед линковкой старые ссылки удаляются по id поста(deletePosts2Tags).

Код

function editPost($data,$postId) {
    $where = "post_id='".$postId."'";
    $this->update($data,$where);
}

function deletePosts2Tags($postId) {
    $where = "post_id='".$postId."'";
    $this->delete($where);
    return true;
}


Далее getPostsByTagAction() - этот action будет выводить посты по заданному тегу. Тег получает из _GET, далее id постов и сами посты по этим id.

Код

function getPostIdsByTagName($tagName) {
    $where = "tag_name='".$tagName."'";
    $result = $this->fetchAll($where);
    $i=0;
    foreach ($result as $value) {
        $postsId[$i] = $value->post_id;
        $i++;
    }
    $postsId = implode(',',$postsId);
    return $postsId;
}

function getPostsByIds($postsIds) {
    $where = "post_id IN (".$postsIds.")";
    return $this->fetchAll($where);
}


На этот раз мы разбиваем массив в строку(getPostIdsByTagName()) и уже строку передаем в getPostsByIds().
Осталось вывести все посты с прилинкованными тегами. В качестве бонуса - постраничная разбивка =)))

Код

function getAllPosts($limit,$page) {
    $posts = $this->_db->fetchOne("SELECT COUNT(*) FROM ".$this->_name);
    $total = intval(($posts-1)/$limit)+1;
    $page = intval($page);
    if(empty($page) or $page<0) $page=1;
    if($page>$total) $page=$total;
    $start = $page*$limit-$limit+1;
    $result = $this->fetchAll(null,null,$limit,$start-1);
    return $result;
        
}


$limit - это кол-во постов на страницу и $page - страница из _GET. Теперь на руках есть все посты, воспользуемся getTagsByPostId($postId).

Код

function getTagsByPostId($postId) {
    $where = "post_id='".$postId."'";
    $result = $this->fetchAll($where);
    $i=0;
    foreach ($result as $value) {
        $tags[$i] =  $value->tag_name;
        $i++;
    }
    $tags = implode(',',$tags);
    return $tags;
}


И в самом конце, когда есть массив с ключами(равными id постов) и сами тегами, превратим его в готовый массив со ссылками, которые будут отфутболивать пользователя на написанный ранее getPostsByTagAction().

Код

foreach ($tags as $key=>$value) {
    $temp = split(",",$value);
    $string = "";
    foreach ($temp as $_key=>$_value){
        $string .="<a href='".$this->_request->getBaseUrl()."/admin/getPostsByTag/tagName/".$_value."'>".$_value."</a>,";
    }
    $tags[$key] = substr($string,0,(strlen($string)-1));
}


финита.

Присоединённый файл ( Кол-во скачиваний: 13 )
Присоединённый файл  AdminController.php 3,89 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0892 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.