Архив метки: Yii

Мои идеи, или одним выстрелом — трех зайцев

Этой заметкой я хочу убить сразу трех зайцев…

Первый заяц — это движок блога на Yii о котором шла речь тут и тут…

Что хочется сказать…работа потихоньку идет, но очень медленно. Для проекта я выбрал рабочее название — Юпи! (Yupe!), если к моменту выхода версии 0.0.1 ничего не изменится — то так и буду его называть (а пока можно предлагать другие названия!)! Для Юпи!, создан проект на code.google.com — это собственно говоря, это мой второй заяц. code.google.com/p/xomaprojects — все  что пишется мной, будет появляться в этом репозитории, пока там не густо, но со временм думаю наполнится!

И наконец третий заяц!Мне очень нравится форум linuxforum.ru, а нравится вот почему…Одно время, я пользовался OpenSuse Linux и постоянно искал материал в ветке о OpenSuse…потом мне потребовалась какая-то информация о Mandriva — нет ничего проще — я просто перехожу в соответствующую ветку и узнаю все, что мне необходимо там. Бывают случаи когда на форуме говорили: «…а вот в Убунту, это сделано лучше и удобнее», на вопрос «…а как именно?» получал ссылку в ветку про убунту и там мог все разузнать «из первых рук» )  Собственно к чему это все я говорю. А вот к чему…Наверное у любого web-разработчика, рано или поздно появляется интерес к фреймворкам (на каком языке вы бы не писали) ведь так же??? Рзработчик начинает искать необходимую ему информацию на офф сайтах, форумах и т.д. При этом ему необходимо зарегистрироваться везде, где он хочет что-либо спросить и получить отчет. Неплохо было бы иметь форум, подобный linuxforum, про современные web frameworks и их место в разработке приложений (я такой не нашел — если есть…что ж….я зря потратил 370р на домен…:-) только не забудьте кинуть ссылочку ). Не долго думая (!) я зарегистрировал домен allframeworks.ru и установил там форум SMF (на все про все ушло 10-15 минут, спасибо моему хостеру).

И вот…он!
Первый раз ставлю форум на хостинг (в локалке пару раз приходилось разворачивать нечто подобное),  к тому же тариф у меня не самый «вип» ))), поэтому возможны проблемы с производительностью. Ну…как говорится будем решать проблемы по мере их поступления (если будет необходимость можно и на вип тариф переехать или на VDS даже).
А пока:

  • форум установлен
  • создана примерная структура
  • есть небольшое первоначальное заполнение

Если кого то заинтересует эта тема, приглашаю в ряды модераторов, администраторов или простых пользователей.

Так же было бы неплохо услышать просто Ваши мысли по этому поводу!

Добро пожаловать на forum.allframeworks.ru!

Yii на ru.wikipedia.org

До сегодняшнего дня на ru.wikipedia.org не было страницы о Yii (может конечно я плохо искал 🙁 )….
Теперь она там есть http://ru.wikipedia.org/wiki/Yii!
В качестве моего бонуса — оставил ссылку на свой блог!

p.s. то моя первая статья на вики — так что прошу сильно не пинать!

Yii, создаем свою CMS. База данных.

Краткое содержание предыдущих серий

1 Вступление

И так, имея скромный набор требований, описанный в первой статье, перейдем непосредственно к разработке.

Когда я приступаю к разработке нового приложения или сайта, и уже более или менее понятно с какими сущностями придется работать и какие данные хранить, лично я, предпочитаю нарисовать схему базы данных, которая в будущем будет хранить всю информацию приложения. Такая схема позволит более наглядно представить все объекты, разрабатываемого приложения и взаимосвязи между ними. Для рисования таких схем, можно воспользоваться любым инструментом, начиная от листа бумаги и карандаша, заканчивая специализированным ПО, типа MS VISIO. Однако, я предпочитаю программное обеспечение, специально предназначенное для этих целей. Довольно давно, я пользуюсь Mysql Workbench, для проектирования баз данных Mysql, подробнее узнать про эту программу и скачать ее, можно тут.

Примерно за 40 минут работы, у меня получилась вот такая вот схема БД.

Схема бвзы данных

Сейчас постараюсь подробно рассказать про назначение каждой таблицы и каждого столбца.

И так поехали!

User — предназначена для хранения данных о зарегистрированных пользователях (на первом этапе разработки, наша цмска будет однопользовательской — т.е.  добавлять контент сможет любой пользователь прошедший авторизацию, в связи с этим, на первом этапе не будет возможности регистрироваться новым пользователям).

  • userId — идентификатор пользователя;
  • name   — имя пользователя;
  • email  — email пользователя;
  • password — пароль пользователя;
  • creationDate — дата регистрации пользователя (пока система однопользовательская — особого смысла в этом поле нет);
  • status  — 0 — пользователь активен 1 — пользователь заблокирован;
  • accessLevel — 0 — простой пользователь 1 — администратор (может управлять контентом и совершать административные действия)

System — таблица для хранения всех системных параметров.

  • systemId   — идентификатор записи
  • siteUrl  — основной url сайта
  • siteInfo— информация о сайте
  • siteDescription — описание сайта
  • ownerInfo            — информация о владельце
  • ownerEmail        — email администратора сайта
  • userId                      — пользователь создавший настройку (в однопользовательской работе на учитывается)

Content — данная таблица будет содержать все записи (посты), страницы и все остальное наполнение нашего движка.

  • contentId — идентификатор записи
  • title  — заголовок записи
  • alias  — строка Url данного записи
  • content — содержимое поста
  • status  — 0 — черновик, 1 — опубликовано
  • keywords — ключевые слова для записи (meta)
  • description — описание записи (meta)
  • createdBy   — идентификатор пользователя создавшего запись
  • creationDate — дата создания
  • active       — признак того что эта запись является самой последней (актуальной)
  • canComment   — разрешены ли комментарии для данной записи
  • isPrivate    — пост доступен только авторизованным пользователям (в версии 1 нашего движка это работать не будет)
  • publishDate  — дата публикации
  • revision — номер версии записи
  • contentParentId — идентификатор, изначально созданной записи
  • revisionParentId — идентификатор, предыдущей ревизии
  • contentType — тип контента  2 — запись (пост) 1 — страница
  • modifyDate — дата изменения
  • modifyBy                   — кем изменено
  • commentCnt          — количество комментариев

Comment — таблица хранит комментарии к постам и страницам (?).

  • commentId — идентификатор комментария
  • parentId  — родительский комментарий (в первой версии движка мы его использовать скорее всего не будем)
  • postId    — идентификатор поста, к которому относится комментарий
  • comment   — текст комментария
  • creationDate — дата создания комментария
  • userName     — имя пользователя, создавшего комментарий
  • userEmail    — email пользователя, создавшего комментарий
  • userUrl      — url пользователя, создавшего комментарий
  • userIp       — ip-адрес пользователя оставившего комментарий
  • status       — 0 — комментарий не подтвержден, 1 — комментарий одобрен, 2 — спам


Tag —
таблица хранит тэги.

  • tagId — идентификатор тэга
  • tag   — название тэга

TagContent- таблица предназначена для хранения отношения тегов и постов

  • tagContentId — идентификатор контента
  • contentId    — идентификатор записи
  • tagId     — идентификатор тэга

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

Если есть какие-то замечание или предложения — прошу высказываться в комментариях.

p.s. Названия движка, пока так и не выбрано — любые варианты приветствуются!

Основной сайт Юпи! — http://yupe.ru

Исходный код — https://github.com/yupe/yupe

Присоединяйтесь!

Yii, пишем фильтр для предотвращения XSS атак.

Начну с небольшого отступления.

И все таки правильно говорят, а на некторых форумах (особенно UNIX-овых), прямо кричат — RTFM! Кто не понял очем идет речь — RTFM в переводе означает «читай эту чертову документацию!».  Это все я собственно вот к чему: изучая и что-то пытаясь написать на фреймворке Yii,  возникла задача фильтрации входных данных от различного рода «зловредных» символов (аля XSS-атака) и первое что пришло в голову — это написать свой фильтр (что я все таки и сделал), однако creocoder, на форуме Yii , совершенно спрпаведливо заметил, что не зачем изобретать велосипед, все уже есть готовое, необходимо только RTFM! Речь шла о классе CHtmlPurifier, который является оберткой для библиотеки HTML Purifier , и выполняет все те функции, которые мне необходимы (правда я так и не попробывал его в действии, может и зря конечно). Но раз уж я начал писать свой фильтр — решил все таки это дело завершить, да и просто написать статью о фильтрах в Yii.

И так!

Фильтры — фрагменты кода, которые могут быть выполнены до и\или после выполнения экшена  контроллера.  Фильтры, при необходимости, могут  не допустить выполнения запрошенного экшена.

Фильтры могут быть как методами текущего контроллера, так и отдельными классами — что позволяет повторно их использовать. Если фильтр реализуется как метод класса, он должен иметь префикс «filter».

Пример:

public function filterAccessControl()
{
 .......
}

Фильтр, реализованный в виде отдельного класса, должен быть наследником класса CFilter.

Пример:

class XssFilter extends CFilter
{
   // код который выполнится до выполнения экшена
 public function preFilter()
 {
  .......
 }
 // код который выполнится после выполнения экшена
 public function postFilter()
 {
 .......
 }
}

Для активации фильтров, необходимо в контроллере переопределить метод filters,который должен вернуть массив всех фильтров для данного контроллера (или его отдельных экшенов).

Пример:

public function filters()
{
 return array(
           'accessControl',
           array(
             'application.filters.XssFilter',
             'clean' => 'all'
          )
  );
}

В этом примере ‘accessControl’ — фильтр, реализованный как метод контроллера, а ‘application.filters.XssFilter’ — фильтр, реализованный в виде отдельного класса, который хранится в каталоге /protected/filters/. ‘clean’ — устанавливаем свойство фильтра.

Это была краткая справка  по фильтрам в Yii, более подробно можно почитать тут.

Теперь непосредственно приступим к реализации нашего фильтра. Функцию очистки данных, которая и выполняет всю работу — я взял из фреймворка Kohana. Ну на этом достаточно слов, приведу сам код фильтра — он  совсем простой, так что думаю проблем быть не должно.

  /**
   *  @author  Opeykin A. <opeykin.ru&; <aopeykin@gmail.com>
   *  @version 0.0.1
   *  @package filters
   *
   * Фильтр предназначен для фильтрации входных данных, c целью предотвратить xss атаки.
   * Для фильтрации используются регулярные выражения из фреймворка Kohana 2.3.1
   * @example
   *
   *  public function filters()
   *  {
   *         return array(
   *                 array('application.filters.XssFilter',
   *                       'clean' =>; 'all'
   *                 )
   *         );
   *
   *   }
   *
   *   В качетве параметра 'clean' могут быть:
   *  - 'all' - фильтруются GET,POST,COOKIE,FILES массивы;
   *  - '*'   - аналог ALL;
   *  - так же возможно сочетание любых из параметров, например GET,COOKIE или POST,FILES
   */

class XssFilter extends CFilter
{
   public  $clean = 'all';

  protected function preFilter($filterChain)
  {
  $this->clean  = trim(strtoupper($this->clean));
  $data = array(
  'GET'    =>&$_GET,
  'POST'   =>&$_POST,
  'COOKIE' =>&$_COOKIE,
  'FILES'  =>&$_FILES
  );

  if($this->clean === 'ALL' || $this->clean === '*')
  {
    $this->clean = 'GET,POST,COOKIE,FILES';
  }
  $dataForClean = split(',',$this->clean);
  if(count($dataForClean))
  {
     foreach ($dataForClean as $key => $value)
     {
        if(isset ($data[$value]) && count($data[$value]))
        {
           $this->doXssClean($data[$value]);
        }
     }
 }
return true;
}

  protected function postFilter($filterChain)
  {
    // logic being applied after the action is executed
  }

  private function doXssClean(&$data)
  {
     if(is_array($data) && count($data))
  {
    foreach($data as $k => $v)
  {
     $data[$k] = $this->doXssClean($v);
  }
     return $data;
}

if(trim($data) === '')
{
return $data;
}

// xss_clean function from Kohana framework 2.3.1
$data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');
// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);
// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);
// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);
// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);
do
{
// Remove really unwanted tags
$old_data = $data;
$data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);
return $data;
}

}

Я совсем немного протестировал это фильтр — на первый взгляд — все работает!

Любые замечания и комментарии приветствуются!

Хочу добавить свои замечания к реализации фильтров в Yii…

Мне кажется было удобно иметь метод, который вызывается перед выполнением preFilter и postFilter, например init() — который выполняет инициализацию фильтра, при этом в нем должны быть доступны параметры, передавемые в фильтр из контроллера  (по этой причине невозможно использовать __construct). Конечно можно расширить CFilter для этих целей, но «родная» возможность сделать это была бы лучшим вариантом.

Надеюсь, описанный материал окажется полезен!

Ищите разработчиков на Yii ?

Мы решим Ваши задачи!

Скачать xssfilter