Monday, August 20, 2012

Creating User Access Levels for Forum Application Software Yii Framework

One of the important things in an application is a user-level access. User level access is a categorization of user permissions based on the user level. For example, we only allow a user with admin level making new news, allowing members who are logged in to make a new thread, and others. The first thing you should create is a user-level process to determine who is doing the activity in our application. In the "protected/components/" create a file with the extension ". Php" with the name "EwebUser.php". Then enter the following code in the file:
<?php
class EWebUser extends CWebUser{
    protected $_model;
    protected function loadUser()
    { 
        if ( $this->_model === null ) { 
            $this->_model = User::model()->findByPk($this->id); 
        }
        return $this->_model; 
    } 
    function getLevel() 
    { 
        $user=$this->loadUser(); 
        if($user) 
            return $user->level_id; 
        return 100; 
    } 
}
The above code CWebUser lower class that exist in Yii. In the above code getLevel function () will return the currently logged on user level from the table "Users" to attribute "level_id". After making the above code, we can restrict certain functions based on levels like the following example:
public function accessRules()
{
 return array(
  array('allow',
   'actions'=>array('index','view'), 
   'users'=>array('*'), 
  ),
  array('allow',
   'actions'=>array('create','update'), 
   'users'=>array('@'),
  ),
  array('allow',
   'actions'=>array('admin','delete'), 
   'expression'=>'$user->getLevel()<=1',
  ), 
  array('deny', 
   'users'=>array('*'),
  ),
 );
 }
The above code allows the index action and views accessible to all the good people who are logged in or not. Create and update action can only be accessed by users who are logged. Admin and delete action can only be accessed by users who have a level value <= 1. Level value itself will be taken from the user table. In this application level_id attribute will be connected to the attribute level that existed at the table level and level 1 a user with admin type. Now, using these methods you can define your own rules of access levels each. For this application we would have to adjust to the needs of our application.

In addition to set an access level, we can also use to set the user access level access to a view. For example if login with admin level would show made A, whereas if login with normal user level would show made B. Here's an example of its use
if(Yii::app()->user->getLevel()<=2)
{
 echo "it";
}
else
{
 echo "this";
}
Yii Framework Tutorials

Creating Login and Logout Operation for Forum Application Software Yii Framework

Now I will make action to login. The first time we did generate application code Yii, Yii automatically been providing the login form and action. Rather than create it from scratch, but we'll modify the login action that has been provided by Yii. You can see the code that processes the login action in "protected/controllers/SiteController.php", "protected/view/site/login.php", "protected/models/LoginForm.php", and "protected/Components/UserIdentify.php". Although there are many log files related action, but we will modify only UserIdentify.php.
class UserIdentity extends CUserIdentity
{
 private $_id;

 public function authenticate()
 {
  $username = strtolower($this->username);
  $user = User::model()->find('LOWER(username)=?', array($username));
  if($user===null) 
   $this->errorCode=self::ERROR_USERNAME_INVALID;
  else if(!$user->validatePassword($this->password))
   $this->errorCode = self::ERROR_PASSWORD_INVALID;
  else
  {
   $this->_id = $user->id;
   $this->username = $user->username;
   $this->errorCode = self::ERROR_NONE;
  }
  return $this->errorCode == self::ERROR_NONE;
 }

 public function getId()
 {
  return $this->_id;
 }
}
The above code works retrieved from the user table and match the username and password have been inputted by the user. Surely that would be matched password is the password that has been encrypted. If the username and password that matches the user inputted username and password exist in the database, the user is logged in successfully.

Okay, we have finished making the menu register, login, and logout. Logout menu is available directly from Yii and do not need to be modified again. Please try these actions!

Creating Register Operation for Forum Application Software Yii Framework

Now I will discuss the stages of the user authentication process that consists of the operation register, login, and logout.

First of all let's create a function to do the "register". This operation is an operation performed when the user wants to register in our application. Once the user to register, then user data is saved to the database on the table "user". To enter the data into a user table, we can use the action on UserController and actionCreate(). The following permissions are contained in UserController:
public function accessRules() 
{ 
 return array( 
  array('allow', 
   'actions'=>array('create','captcha'), 
   'users'=>array('*'), 
  ), 
  array('allow', 
   'actions'=>array('update','view'), 
   'users'=>array('@'),
  ), 
  array('allow', 
   'actions'=>array('admin','index','delete'), 
   'expression'=>'$user->getLevel()<=1', 
  ), 
  array('deny', 
   'users'=>array('*'),
  ), 
 ); 
}
Action "Create" is the register menu, this action can be accessed by all visitors who visit this web application. Captcha is also permitted for all types of visitors, captcha itself is a class that allows us to use a captcha on the register form. Captcha itself is used as a confirmation at the time of registration. Update and view the menu so that user can update and view profilenya profilenya. To perform this action, then the user must log in first. Admin, index and delete the menu that can only be by the admin. There are code 'expression'=>'$user->getLevel()<=1', this code will be discussed at the next.

In the user table are attribute-attribute as follows:
  • Id = attribute is not inputted by the user but is automatically generated by the database
  • Username = username user
  • Password and saltPassword = password and saltPassword are two related attribute. Password will be inputted by the user himself, while saltPassword be generated automatically by the application. It's just the password attribute, the data entered into the database will not be the same as the data inputted by the user. The data will be entered into the password attribute itself is already encrypted data between user input and saltPassword. So do not be surprised if the next time you see the database password and saltPassword attribute is a set of characters that you never know. Why do we implement this mechanism? This was done to improve the security of the application. Even those who manage the application could not know the password of a user.
  • Email = Email from user
  • Joindate = date do register. This attribute will automatically take your user to register.
  • Level_id = level to a user. This attribute by default will be set worth 3, the regular member
  • Avatar = attribute that contains a link to a user avatar image file. In appearance, the user will be asked to select an image file to be used as avatar.
At the time of login, we will ask the user to enter the password twice. If the password1 and password2 are different, then the user is asked to repeat the process of entering a password. Then we ask the user to enter a captcha user confirmation. Therefore we need to add two variables, ie variables that we password2 and captcha verifyCode name. Therefore add the following attribute to your model:
class User extends CActiveRecord
{
 public $password2;
 public $verifyCode;
After that we created on the model of user validation in accordance with the business rules we have set:
public function rules()
 {
  return array(
   array('username, password, email,password2,verifyCode', 'required','message'=>'{attribute} Not Allow Empty'),
   array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd')),
   array('level_id', 'numerical', 'integerOnly'=>true),
   array('username', 'length', 'max'=>20),
   array('password, saltPassword, email', 'length', 'max'=>50),
   array('avatar','file', 'types'=>'gif,png,jpg'),
   array('id, username, password, saltPassword, email, joinDate, level_id, avatar, isActive', 'safe', 'on'=>'search'),
  );
 }
  • The first rule: attribute username, password, email, password2, verivyCode required.
  • The second rule: VerifyCode must conform to the same as displayed by the captcha code.
  • The third rule: level_id must be a number
  • The fourth rule: maximum length is 20 characters username
  • Fifth rule: The maximum length of the password, and email saltPassword maximum of 50
  • Rule sixth: avatar attribute files and extensions should be allowed to file is a gif, jpg, and png.
Well, since we've added a new attribute to the rules user registers in the model, then we also need to set up the display to fit our rule:
<div>

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'user-form',
    'enableAjaxValidation'=>false,
    'htmlOptions'=>array('enctype'=>'multipart/form-data'), )); ?>

    <p>Fields with <span>*</span> are required.</p>

    <?php echo $form->errorSummary($model); ?>

    <div>
        <?php echo $form->labelEx($model,'username'); ?>
        <?php echo $form->textField($model,'username',array('size'=>20,'maxlength'=>20)); ?>
        <?php echo $form->error($model,'username'); ?>
    </div>

    <div>
        <?php echo $form->labelEx($model,'password'); ?>
        <?php echo $form->passwordField($model,'password',array('size'=>50,'maxlength'=>50)); ?>
        <?php echo $form->error($model,'password'); ?>
    </div>

    <div>
        <?php echo $form->labelEx($model,'password2'); ?>
        <?php echo $form->passwordField($model,'password2',array('size'=>50,'maxlength'=>50)); ?>
        <?php echo $form->error($model,'password2'); ?>
    </div>

    <div>
        <?php echo $form->labelEx($model,'email'); ?>
        <?php echo $form->textField($model,'email',array('size'=>50,'maxlength'=>50)); ?>
        <?php echo $form->error($model,'email'); ?> 
    </div>

    <div>
        <?php echo $form->labelEx($model,'avatar'); ?>
        <?php echo $form->fileField($model,'avatar',array('size'=>30,'maxlength'=>30)); ?>
        <?php echo $form->error($model,'avatar'); ?>
    </div>

    <?php if (extension_loaded('gd')): ?>
        <div>
            <?php echo CHtml::activeLabelEx($model, 'verifyCode') ?>
            <div>
                <?php $this->widget('CCaptcha'); ?><br/>
                <?php echo CHtml::activeTextField($model,'verifyCode'); ?>
            </div>
            <div>Type in writing in the picture. Writing are not case sensitive</div>
        </div>
    <?php endif; ?>

    <div>
        <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
    </div>

<?php $this->endWidget(); ?>

</div><!-- form -->
At the top there is a code to use to activate captcha captcha and we have to add the following code to the controller user:
public function actions()
{
 return array(
  'captcha'=>array(
   'class'=>'CCaptchaAction',
   'backColor'=>0xFFFFFF,
  ),
 );
}
In the code above I added the input data for the attribute and verivyCode password2. I also make arrangements so that the attribute data input avatar that appears is ordered user to select an image file to be uploaded. After making the settings menu data input, we now also adjust the code to the controller in accordance with the rules of the register.

In action register, we will make the value of the attribute saltPassword generates and encrypts the password attribute corresponding to the data inputted by the user password and the value saltPassword. Therefore, we must do the settings on the Model "User". Add the following function to the model:
public function validatePassword($password)
{
 return $this->hashPassword($password,$this->saltPassword)===$this->password; }

public function hashPassword($password,$salt)
{
 return md5($salt.$password);
}

public function generateSalt()
{
 return uniqid('',true);
}
After that, the User Controller precisely on actionCreate made ​​to be as follows
public function actionCreate()
 {
  $model=new User; 
  
  // Uncomment the following line if AJAX validation is needed 
  // $this->performAjaxValidation($model);
 
 if(isset($_POST['User']))
 {
  $model->attributes=$_POST['User'];
  $dua=$model->password;
  $model->saltPassword=$model->generateSalt();
  $model->password=$model->hashPassword($dua,$model->saltPassword);
  $model->level_id=3;
  $model->isActive=0;
  
  $sss;
 
 
if(strlen(trim(CUploadedFile::getInstance($model,'avatar'))) > 0)
  { 
   $sss=CUploadedFile::getInstance($model,'avatar'); 
   $model->avatar=$model->username.'.'.$sss->extensionName; 
  } 
  
  if($model->save()) { 
   if(strlen(trim($model->avatar)) > 0)
    $sss->saveAs(Yii::app()->basePath . '/../avatar/' . $model->avatar); 
   $this->redirect(array('view','id'=>$model->id)); 
   } 
  }
 
  $this->render('create',array( 
   'model'=>$model,
  ));
 }
All right, here we have managed to make actionCreate. Please you try running the function.

Sunday, August 19, 2012

Yii PHP Framework v1.1.12 Download and Upgrading Instructions

Yii PHP framework has been released for v1.1.12 Stable on Aug 19, 2012 and available to download. You can download Yii Framework v1.1.12 on http://www.yiiframework.com/download/

This release mainly fixes the BC-breaking issues we have found in the prior release. It includes about 20 bug fixes, minor features and enhancements. For the complete list of changes in this release, please see:

Yii PHP Framework version 1.1.12 August 19, 2012
  • Bug #190: WSDL return tag was not generated by CWsdlGenerator when Macintosh line endings were used inside service describing docblock (resurtm)
  • Bug #1066: CMemCache: expiration time higher than 60*60*24*30 (31536000) seconds led the value to expire right away after saving (resurtm)
  • Bug #1072: Fixed the problem with getTableAlias() in defaultScope() (creocoder)
  • Bug #1076: CJavaScript::encode() was not compatible with PHP 5.1 (samdark)
  • Bug #1077: Fixed the problem with alias in CSort (creocoder)
  • Bug #1083: CFileValidator is now unsafe by default. This will prevent setting attribute when no file was uploaded (samdark)
  • Bug #1087: Reverted changes to CCookieCollection::add() introduced in 1.1.11 as they were triggering E_STRICT on some old PHP-versions (suralc)
  • Bug #1088: Fixed usage of proper CActiveForm id property when it's supplied with htmlOptions (mdomba)
  • Bug #1094: CGridView with enabled history used to clear page title in case sorting or paging performed (Opera and Firefox only) (resurtm)
  • Bug #1109: Fixed "js:" encoding BC-break in CHtml::ajax() and related methods introduced in 1.1.11 (samdark)
  • Bug #1120: Fixed duplicate events processing in CGridView when ENTER was pressed for filtering (mdomba)
  • Bug #1192: CHttpCacheFilter failed to comply with RFC 2616, section 10.3.5 (DaSourcerer)
  • Bug #1207: Fixed an issue in CHtml::resolveValue() which occurs when handling tabular data input (Qiang)
  • Bug #1225: Fixed the bug that $.fn.yiiGridView.getChecked was not working always if a custom CGridView::template was used (mdomba)
  • Bug #1243: Fixed the bug that when using CUrlManager::addRules with $append=false rules were added in reverse order (samdark)
  • Enh #243: CWebService is now able to deal with the customized WSDL generator classes, was hardcoded to the CWsdlGenerator before, added CWebService::$generatorConfig property (resurtm)
  • Enh #636: CManyManyRelation now parses foreign key for the junction table data internally, and provide public interface to access it (klimov-paul)
  • Enh #1163: CGridview does not create empty class attributes anymore (cebe)
  • Chg #1099: Changed connectionId dropdown to sticky text field in Gii model generator (mdomba)
  • Chg #1167: Reverted back the change to CComponent::evaluateExpression() about global function support (Qiang)
Upgrading Instructions for Yii Framework v1.1.12

The following upgrading instructions are cumulative. That is, if you want to upgrade from version A to version C and there is version B between A and C, you need to following the instructions for both A and B.

General upgrade instructions
  • Make a backup.
  • Clean up your 'assets' folder.
  • Replace 'framework' dir with the new one or point GIT to a fresh release and update.
  • Check if everything is OK, if not รข€” revert from backup and post issues to Yii issue tracker.

Saturday, August 18, 2012

Creating Database Design for Forum Application Software Yii Framework

After determining the features, it is time to creating database design for forum application software Yii Framework.
  • Level: Table level is used as the identity of the User level. As already exist on the features that the user in this application consists of three types of user, namely Admin, Moderator and User Ordinary. With the table level, becomes possible if we want to modify the user level.
  • Category: To divide the existing thread into certain categories. Categories can also be added, subtracted and modified as needed.
  • User: This table is used to store user information. User table is also used for the authentication process when the user login process.
  • Thread: Storing all information contained in the forum thread.
  • Comment: Keep all the comments from each thread
  • News: Saving the information inputted by the admin news which will then be displayed on the main page of the application.
  • Raputation: Keep all judgments given by the user to a user.
  • Threadstar: Storing information on an assessment carried out by the user thread.
The following SQL database on which I have made:
CREATE TABLE IF NOT EXISTS `comment` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `title` varchar(255) DEFAULT NULL,
 `content` text NOT NULL,
 `user_id` int(11) NOT NULL,
 `thread_id` int(11) NOT NULL,
 `datePost` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON
UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`),
 KEY `thread_id` (`thread_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `category` (
 id` int(11) NOT NULL AUTO_INCREMENT,
 `category` varchar(100) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `level` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `level` varchar(50) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `news` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `title` varchar(200) NOT NULL,
 `content` text NOT NULL,
 `photo` varchar(200) NOT NULL,
 `user` int(11) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `user` (`user`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `raputation` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 `jenis` tinyint(1) NOT NULL,
 `pemberi_id` int(11) NOT NULL,
 `penerima_id` int(11) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `pemberi_id` (`pemberi_id`),
 KEY `penerima_id` (`penerima_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `thread` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `title` varchar(255) NOT NULL,
 `content` text NOT NULL,
 `user_id` int(11) NOT NULL,
 `category_id` int(11) NOT NULL,
 `datePost` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`),
 KEY `category_id` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `threadstar` (
 `is` int(11) NOT NULL AUTO_INCREMENT,
 `nilai` int(11) NOT NULL,
 `user_id` int(11) NOT NULL,
 `thread_id` int(11) NOT NULL,
 PRIMARY KEY (`is`),
 KEY `user_id` (`user_id`),
 KEY `thread_id` (`thread_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `user` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `username` varchar(20) NOT NULL,
 `password` varchar(50) NOT NULL,
 `saltPassword` varchar(50) NOT NULL,
 `email` varchar(50) NOT NULL,
 `joinDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 `level_id` int(11) NOT NULL,
 `avatar` varchar(30) DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `username` (`username`),
 KEY `level_id` (`level_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

ALTER TABLE `comment`
 ADD CONSTRAINT `comment_ibfk_1` FOREIGN KEY (`user_id`)
REFERENCES `user` (`id`) ON UPDATE CASCADE,
 ADD CONSTRAINT `comment_ibfk_2` FOREIGN KEY (`thread_id`)
REFERENCES `thread` (`id`) ON UPDATE CASCADE;

ALTER TABLE `news`
 ADD CONSTRAINT `news_ibfk_1` FOREIGN KEY (`user`) REFERENCES
`user` (`id`) ON UPDATE CASCADE;

ALTER TABLE `raputation`
 ADD CONSTRAINT `raputation_ibfk_1` FOREIGN KEY (`pemberi_id`)
REFERENCES `user` (`id`),
 ADD CONSTRAINT `raputation_ibfk_2` FOREIGN KEY (`penerima_id`)
REFERENCES `user` (`id`);

ALTER TABLE `thread`
 ADD CONSTRAINT `thread_ibfk_3` FOREIGN KEY (`user_id`)
REFERENCES `user` (`id`) ON UPDATE CASCADE,
 ADD CONSTRAINT `thread_ibfk_4` FOREIGN KEY (`category_id`)
REFERENCES `category` (`id`) ON UPDATE CASCADE;

ALTER TABLE `threadstar`
 ADD CONSTRAINT `threadstar_ibfk_3` FOREIGN KEY (`user_id`)
REFERENCES `user` (`id`) ON UPDATE CASCADE,

 ADD CONSTRAINT `threadstar_ibfk_4` FOREIGN KEY (`thread_id`)
REFERENCES `thread` (`id`) ON UPDATE CASCADE;

ALTER TABLE `user`
 ADD CONSTRAINT `user_ibfk_1` FOREIGN KEY (`level_id`) REFERENCES `level` (`id`) ON UPDATE CASCADE;

After you finish creating the database, please create a new Yii Framework application with the name of  "forum", after that connect Yii application to the MySql database that we have made earlier, and activate the feature Gii on Yii Framework. If you've managed to do both, please generate CRUD operations on all existing tables in your database. You can look at my previous post.

Creating Forum Application Software Using Yii Framework

So far there is only a discussion of related issues and concepts of small examples of the use of Yii Framework in some case examples. I think it would be better if we learn how to build real applications with Yii Framework. I will discuss making the real application is the forum software application using Yii Framework. I will discuss the application itself is not a forum that is complex like a vBulletin forum software. I only discuss the basics of most forum applications can not be used to interface between a user with another user, each commenting on a thread, pass judgment on a thread, and others. If you are interested to develop it further, I think it is a good thing.

The following features of the application that we will create:
  • Users can register and login
  • If you have not logged in, everyone can see the forum but can not make a new post or make a comment on a post
  • If you have successfully logged in, users can create new posts and add comments
  • Each posts grouped by category
  • The first page will show the top member, list user posts and news (news) posted by admin
  • User consists of three levels, namely Admin, moderator, and the ordinary Member
  • Admin and moderator can add, edit, and delete the "post"
  • Admin and moderator can manage the "category" and "news"
  • Users have to log in to make comments on a thread
  • User can give reputation to other users

Thursday, April 26, 2012

Best Rich Text Editors Yii Framework Extensions for Web Projects

  1. TinyMCE
    This extension draws a TinyMCE HTML editor using a jQuery plugin. TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under LGPL by Moxiecode Systems AB.

    TinyMCE has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.
    Download - http://www.yiiframework.com/extension/tinymce
    Demo - http://www.tinymce.com/tryit/full.php
  2. CKEditor
    CKEditor is a text editor to be used inside web pages. It's a WYSIWYG editor, which means that the text being edited on it looks as similar as possible to the results users have when publishing it. It brings to the web common editing features found on desktop editing applications like Microsoft Word and OpenOffice.

    Because CKEditor is licensed under flexible Open Source and commercial licenses, you'll be able to integrate and use it inside any kind of application. This is the ideal editor for developers intending to provide easy and powerful solutions to their users.

    CKEditor provides all features and benefits users and developers expect having on modern web applications. Its amazing performance keep users focused on the things to be done. You will find all common features available on text editors, as well as additional components specially designed for web contents.

    If you think the default features are not enough, CKEditor provides a strong and rich JavaScript API, making it possible to extend it to fit all needs. You can even consider that it has too much features, and removing them is even easier.
    Fully compatible

    One of the strongest features in CKEditor is its almost unlimited compatibility. It's a JavaScript application, so it simply works with all server technologies, just like a simple textarea. In the browser side instead, it has been developed to be compatible with the browsers that dominate the market, namely Internet Explorer, Mozilla Firefox, Google Chrome, Safari and Opera. Even the old Internet Explorer 6 is compatible with.
    Download - http://www.yiiframework.com/extension/ckeditor
    Demo - http://ckeditor.com/demo
  3. NicEdit
    NicEdit is a WYSIWYG editor for websites. Its goal is to be as simple and fast as possible for users of your application. NicEdit is extremely lightweight and can be easily integrated in any site with minimal impact while providing visitors an effective means to express themselves in rich text.
    Download - http://www.yiiframework.com/extension/niceditor
    Demo - http://nicedit.com/demos.php
  4. CLEditor
    CLEditor is an open source jQuery plugin which provides a lightweight, full featured, cross browser, extensible, WYSIWYG HTML editor that can be easily added into any web site.

    In addition to the standard text formatting features found in other WYSIWYG editors, CLEditor also contains rich drop downs for font name, size, style, text color and highlight color. CLEditor allows you to insert images, hyperlinks and horizontal rules.
    Download - http://www.yiiframework.com/extension/cleditor
    Demo - http://premiumsoftware.net/cleditor/
  5. WYMeditor
    EWYMeditor is a wrapper for WYMeditor which is a web-based WYSIWYM (What You See Is What You Mean) XHTML editor (not WYSIWYG).

    WYMeditor's main concept is to leave details of the document's visual layout, and to concentrate on its structure and meaning, while trying to give the user as much comfort as possible (at least as WYSIWYG editors).

    WYMeditor has been created to generate perfectly structured XHTML strict code, to conform to the W3C XHTML specifications and to facilitate further processing by modern applications.

    With WYMeditor, the code can't be contaminated by visual informations like font styles and weights, borders, colors, etc. The end-user defines content meaning, which will determine its aspect by the use of style sheets. The result is easy and quick maintenance of information.

    As the code is compliant to W3C XHTML specifications, you can for example process it using a XSLT (at the client or the server side), giving you a wide range of applications.
    Download - http://www.yiiframework.com/extension/ewymeditor
    Demo - http://wymeditor.no.de/wymeditor/examples/
  6. JMarkItUp
    JMarkItUp is a set of widgets (for Html, Textile, Wiki, Markdown, BBcode, Texy) that encapsulates the markItUp Content Editor (version 1.1.10).

    markItUp! is a content editor plugin based on jQuery. It's not a WYSIWYG editor. Instead, it provides a lightweight, easy-to-use set of buttons, keyboard shortcuts, and other tools to add markup to your content.

    markItUp! is a JavaScript plugin built on the jQuery library. It allows you to turn any textarea into a markup editor. Html, Textile, Wiki Syntax, Markdown, BBcode or even your own Markup system can be easily implemented.

    markItUp! is not meant to be a “Full-Features-Out-of-the-Box”-editor. Instead it is a very lightweight, customizable and flexible engine made to meet the developer's needs in their CMSes, blogs, forums or websites. markItUp! is not a WYSIWYG editor, and it never will be.
    Download - http://www.yiiframework.com/extension/jmarkitup
    Demo - http://markitup.jaysalvat.com/examples/