Sunday, May 5, 2013

ExtJS: Add font family custom drop down in toolbar

ExtJS has some command to make it easy. ExtJS has some font names, but if you want more font then you
shoud make your own component. The following component override the existing font names with some
font name you provide, such I provide extra font name "Candara" here.
Some command in ExtJS HtmlEditor:
this.execCmd('InsertHTML','    ');
this.execCmd('InsertText','\t');

this.execCmd('useCSS'true);

this.execCmd('styleWithCSS'false);


doc this.getDoc();

doc.queryCommandValue('FontName');
doc.queryCommandState('bold');

doc.queryCommandState('italic');

doc.queryCommandState('underline');

doc.queryCommandState('justifyleft');

doc.queryCommandState('justifycenter');

doc.queryCommandState('insertorderedlist');

doc.queryCommandState('insertunorderedlist');


this.insertAtCursor('<hr/>');



doc.selection.createRange();

r.collapse(true); r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;'); this.deferFocus();


Ext.form.HtmlEditor.Font = Ext.extend(Ext.util.Observable, {
    init: function(cmp){
        this.cmp = cmp;
        this.cmp.on('render', this.onRender, this);
    },
    // private
    onRender: function(){
        var cmp = this.cmp;
        var fonts = function(){
            var fnts = [];
            Ext.each(cmp.fontFamilies, function(itm){
                fnts.push([itm.toLowerCase(),itm]);
            });
            fnts.push(["candara", "Candara"]);
            return fnts;
        }();
        var btn = this.cmp.getToolbar().addItem({
            xtype: 'combo',
            displayField: 'display',
            valueField: 'value',
            name: 'fontfamily',
            forceSelection: true,
            selectOnFocus: true,
            selected: "Candara",
            editable: false,
            mode: 'local',
            triggerAction: 'all',
            width: 80,
            emptyText: 'Font',
            tpl: '<tpl for="."><div class="x-combo-list-item" style="font-family:{value};">{display}</div></tpl>',
            store: {
                xtype: 'arraystore',
                autoDestroy: true,
                fields: ['value','display'],
                data: fonts
            },
            listeners: {
                'select': function(combo,rec){
                    cmp.relayCmd('FontName', rec.get('value'));
                },
                scope: cmp
            }
        });
    }
});

ExtJS: add button to htmleditor

I am using ExtJS and I have a htmleditor in my form. I would like to add a custom button to that element (for example after all other buttons like alignments, font weights, ...). This button should basically insert a standard template in the htmlfield. Being this template html, the behaviour of the button should be like this
  • Switch to HTML mode (like when pressing Source button)
  • Insert something
  • Switch back to WYSIWYG mode (like when pressing the Source button again)


Ext.ns('Ext.ux.form.HtmlEditor');

Ext.ux.form.HtmlEditor.HR = Ext.extend(Ext.util.Observable, {
    init: function(cmp){
        this.cmp = cmp;
        this.cmp.on('render', this.onRender, this);
    },
    onRender: function(){
        this.cmp.getToolbar().addButton([{
            iconCls: 'x-edit-custom', //your iconCls here
            handler: function(){
                this.cmp.insertAtCursor('<hr>');
            },
            scope: this,
            tooltip: 'horizontal ruler',
            overflowText: 'horizontal ruler'
        }]);
    }
});

var w = new Ext.Window({
    width: 550,
    layout: 'fit',
    items: [{
        xtype: 'htmleditor',
        plugins: [new Ext.ux.form.HtmlEditor.HR()]
    }]
});
w.show();

But I really recommend you to see the project HtmlEditor.Plugins at google code. There you can find a lot more about adding custom buttons, for instance, how to enable/disable the buttons when something is selected, put separators, etc.
https://docs.google.com/file/d/0B5nZNPW48dpFb0hJVmpVUEphZGc/edit?usp=sharing

Saturday, May 4, 2013

Yii Examples of Using CDbCriteria

Basic Usage
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Products = Product::model()->findAll($Criteria);
OR
//An example using the constructor to populate the properties.
$Criteria = new CDbCriteria(array('condition' => 'price > 30'));
$Products = Product::model()->findAll($Criteria);
Personally, I like to go with the first approach. I think it’s generally easier to read, but that’s just my personal preference.
Adding A Limit
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Criteria->limit = 1;
$Products = Product::model()->findAll($Criteria);
Limit with Offset
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Criteria->limit = 1;
$Criteria->offset = 1;
$Products = Product::model()->findAll($Criteria);
Ordering Results
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Criteria->limit = 1;
$Criteria->offset = 1;
$Criteria->order = "name ASC";
$Products = Product::model()->findAll($Criteria);
Limiting Selected Fields
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Criteria->limit = 1;
$Criteria->offset = 1;
$Criteria->order = "name ASC";
$Criteria->select = "id, name";
$Products = Product::model()->findAll($Criteria);
Example relation with :
$criteria = new CDbCriteria;
/* You can use condition as first parameter and must one conditions,
which will make and conditions with other compare values  */
$criteria->conditions = 'is_user_deleted = 0 OR is_user_deleted = 2'; 
 
$criteria->with = array('groupGroup');
$criteria->together = true; // ADDED THIS
$criteria->compare( 'groupGroup.id', $this->group_id, true ); 
/* true means compare as like '% value %' */
$criteria->compare('first_name',$this->first_name,true);
$criteria->compare('last_name',$this->last_name,true);
$criteria->order = 'first_name ASC';
$criteria->limit = 10;
If two table has same column, then need to modify some code suppose-
1. $criteria->compare($this->getTableAlias().'.deleted','0',true);
Here both this table and 'group' table has same column named 'deleted', but now 
only compare with current tables 'deleted' field. 
And foreign table must be in relations...
public function relations() {
    return array(
         'groupGroup' => array(self::BELONGS_TO, 'Group', 'group_id')
        /* group_id is current models foreign key from 'group' table. */
     );
}

Thursday, May 2, 2013

Strip out html tags using php code


<?php
function strip_html_tags($text)
{
    $text = preg_replace(
        array(
            // Remove invisible content
            '@<head[^>]*?>.*?</head>@siu',
            '@<style[^>]*?>.*?</style>@siu',
            '@<script[^>]*?.*?</script>@siu',
            '@<object[^>]*?.*?</object>@siu',
            '@<embed[^>]*?.*?</embed>@siu',
            '@<noscript[^>]*?.*?</noscript>@siu',
            '@<noembed[^>]*?.*?</noembed>@siu',
            // Add line breaks before and after blocks
            '@</?((address)|(blockquote)|(center)|(del))@iu',
            '@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
            '@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
            '@</?((table)|(th)|(td)|(caption))@iu',
            '@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
            '@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
            '@</?((frameset)|(frame)|(iframe))@iu',
        ), "", $text);
    return strip_tags($text);
}
?>

Wednesday, May 1, 2013

Rollback or Commit with PDO transaction using php and mysql

A transaction should end with either a rollback() or a commit(), (only one of them).
In case you are using MySQL, make sure you are not using MyISAM engine for tables, as it doesn't support transactions. It usually support InnoDB.
Some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction. The implicit COMMIT will prevent you from rolling back any other changes within the transaction boundary.


$dbh = null;
try {
    $dbh = new PDO("mysql:host=HOST_NAME;dbname=DB_NAME", "DB_USER_NAME", "DB_USER_PASSWORD");

    /*** Set the PDO error mode to exception (will throw exception if any error occurred) ***/
    /*** Follow the link for more info: http://php.net/manual/en/pdo.setattribute.php ***/
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_EMPTY_STRING);

    /*** Creating a test table if not exists ***/
    $table = "CREATE TABLE IF NOT EXISTS test_transaction ( " .
        "id MEDIUMINT(8) NOT NULL AUTO_INCREMENT PRIMARY KEY, ".
        "name VARCHAR(25) NOT NULL, designation VARCHAR(25) NULL )";
    $dbh->exec($table);

    /*** Transaction block starting here ***/
    $dbh->beginTransaction();

    /*** Inserting some data ***/
    $dbh->exec("INSERT INTO test_transaction VALUES(NULL, 'Pritom #1', '')");
    $dbh->exec("INSERT INTO test_transaction VALUES(NULL, 'Pritom #2', '')");

    /*** The following query result 2 outputs ***/
    $result = $dbh->query("SELECT * FROM test_transaction");
    echo "<pre>";
    print_r($result->fetchAll());
    echo "</pre>";

    /*** Again inserting some more data ***/
    $dbh->exec("INSERT INTO test_transaction VALUES(NULL, 'Pritom #1', 'Designation #1')");
    $dbh->exec("INSERT INTO test_transaction VALUES(NULL, 'Pritom #2', 'Designation #2')");
    $dbh->exec("INSERT INTO test_transaction VALUES(NULL, 'Pritom #3', 'Designation #3')");

    /*** The following query result 5 outputs ***/
    $result = $dbh->query("SELECT * FROM test_transaction");
    echo "<pre>";
    print_r($result->fetchAll());
    echo "</pre>";

    /*** Throwing an exception to test if transaction really works ***/
    throw new Exception("All data will be erased during this transaction");
}
catch(Exception $ex) {
    $dbh->rollback();

    /*** The following query result 0 outputs as transaction failed ***/
    $result = $dbh->query("SELECT * FROM test_transaction");
    echo "<pre>";
    print_r($result->fetchAll());
    echo "</pre>";

    echo "Exception: ".$ex->getMessage();
    die();
}


Output be as follows:

Array
(
    [0] => Array
        (
            [id] => 29
            [0] => 29
            [name] => Pritom #1
            [1] => Pritom #1
            [designation] => 
            [2] => 
        )

    [1] => Array
        (
            [id] => 30
            [0] => 30
            [name] => Pritom #2
            [1] => Pritom #2
            [designation] => 
            [2] => 
        )

)

Array
(
    [0] => Array
        (
            [id] => 29
            [0] => 29
            [name] => Pritom #1
            [1] => Pritom #1
            [designation] => 
            [2] => 
        )

    [1] => Array
        (
            [id] => 30
            [0] => 30
            [name] => Pritom #2
            [1] => Pritom #2
            [designation] => 
            [2] => 
        )

    [2] => Array
        (
            [id] => 31
            [0] => 31
            [name] => Pritom #1
            [1] => Pritom #1
            [designation] => Designation #1
            [2] => Designation #1
        )

    [3] => Array
        (
            [id] => 32
            [0] => 32
            [name] => Pritom #2
            [1] => Pritom #2
            [designation] => Designation #2
            [2] => Designation #2
        )

    [4] => Array
        (
            [id] => 33
            [0] => 33
            [name] => Pritom #3
            [1] => Pritom #3
            [designation] => Designation #3
            [2] => Designation #3
        )

)

Array
(
)

Exception: All data will be erased during this transaction

Tuesday, April 30, 2013

Get document root path using yii application

dirname(Yii::app()->request->scriptFile)

CGridView a CLinkColumn with sortable header using yii

I have it working with the latest yii (non-stable but might work with the current stable release). (could do with some improvement but it does what I need)

Try this; create a new component under components/SCLinkColumnWithSort.php

<?php
class SCLinkColumnWithSort extends CLinkColumn
{

  public $name;
  public $sortable = true;
  public $filter;

  protected function renderFilterCellContent()
  {
    $this->linkHtmlOptions['class'] = $this->name;
    if($this->filter!==false && $this->grid->filter!==null && strpos($this->name,'.')===false)
    {
      if(is_array($this->filter))
        echo CHtml::activeDropDownList($this->grid->filter, $this->name, $this->filter, array('id'=>false,'prompt'=>''));
      else if($this->filter===null)
        echo CHtml::activeTextField($this->grid->filter, $this->name, array('id'=>false));
      else
        echo $this->filter;
    }
    else
      parent::renderFilterCellContent();
  }

  protected function renderHeaderCellContent()
  {
    if($this->grid->enableSorting && $this->sortable && $this->name!==null)
      echo $this->grid->dataProvider->getSort()->link($this->name,$this->header);
    else
      parent::renderHeaderCellContent();
  }

}
?> 
Use this as following: 

<?php
$this->widget('zii.widgets.grid.CGridView', array(
  'dataProvider' => $dataProvider,
  'columns' => array(
    array(
      'class' => 'SCLinkColumnWithSort',
      'name' => 'column_name_to_sort',
     )
  )
))
?> 
 
Or you can directly use, but upper one used for more customization:
array(
  'name' => 'mobile_number',
  'type' => 'raw',
  'value' => 'CHtml::link($data->mobile_number,$data->contact_id)'
) 
Where mobile_number is filed value in name, in value, mobile_number is for sorting
and contact_id is for making link.