How to render custom html in tabs block

Remove _prepareForm() function from your Tab block and add constructor as shown below

class Company_Module_Block_Adminhtml_CustomSettings_Edit_Tab_Settings extends Mage_Adminhtml_Block_Widget_Form
{

    public function __construct()
    {
        $this->setTemplate('MODULE_NAME/customsettings/view.phtml');
    }

}

Create a view.phtml file at design/adminhtml/default/default/template/MODULE_NAME/customsettings

Create custom WordPress form and handle submission?

<?php

/**
 * Plugin Name: Custom Form
 * Plugin URI: http://http://tahiryasin.wordpress.com/
 * Description: Creates a custom form through shortcode and handles the submit event.
 * Version: 1.0
 * Author: Tahir Yasin
 * Author URI: http://tahiryasin.wordpress.com/about/
 * License: GPL2
 */

class CustomForm
{

    public function __construct()
    {
        add_action('init', array($this, 'init'));
        add_shortcode('custom_form', array($this, 'shortcode'));
    }

    public function init()
    {
        if (!empty($_POST['nonce_custom_form']))
        {
            if (!wp_verify_nonce($_POST['nonce_custom_form'], 'handle_custom_form'))
            {
                die('You are not authorized to perform this action.');
            } else
            {
                $error = null;
                if (empty($_POST['name']))
                {
                    $error = new WP_Error('empty_error', __('Please enter name.', 'tahiryasin'));
                    wp_die($error->get_error_message(), __('CustomForm Error', 'tahiryasin'));
                }
                else
                    die('Its safe to do further processing on submitted data.');
            }
        }
    }

    function shortcode($atts)
    {
        return "<form method='post' action=''>
    <input name='name' type='text' value='' />
    " . wp_nonce_field('handle_custom_form', 'nonce_custom_form') . "
        <input type='submit' value='Submit'/>
    </form>";
    }

}

$CustomForm = new CustomForm();
?>

Get custom attribute value in Magento

Simplest way:

echo $_product->getAttributeText('custom_attribute_code');

Problem:

You will get a fetal error if the attribute is not already registered.

Fatal error: Call to a member function getSource() on a non-object in D:\..\app\code\core\Mage\Catalog\Model\Product.php on line 1389

Solution:

$attribute = $_product->getResource()->getAttribute('custom_attribute_code');
if ($attribute)
{
	echo $attribute_value = $attribute ->getFrontend()->getValue($_product);
}

This code will first check if the attribute code exists and gets its value if its there.

Multi Image Upload

Multi Image Upload adds a meta box to upload multiple images for posts and pages. You can enable it for custom post types also.

Installation:

  1. Upload plugin to the `/wp-content/plugins/` directory
  2. Activate the plugin through the ‘Plugins’ menu in WordPress
  3. To retrieve linked images [Use miu_get_images()](http://wordpress.org/extend/plugins/multi-image-upload/other_notes/#miu_get_images()) into the loop to get an array of image URLs
  4. Optional

If you need to enable this meta box for your custom post type for example ‘book’. Just edit the multi-image-upload.php as shown below

Replace:

$this->post_types = array('post', 'page');

With:

$this->post_types = array('post', 'page', 'book');

Usage

$images = miu_get_images($post_id); 

//Sample output
Array
(
    [0] => http://www.example.com/image-1.png
    [1] => http://www.example.com/image-2.png
)

?>

Screenshots:

screenshot-1

screenshot-2

screenshot-3

WordPress advanced search filters based on custom fields

<?php
/**
 * Template Name: Search
 *
 * @package WordPress
 * @subpackage Twenty_Eleven
 * @since Twenty Eleven 1.0
 */
get_header();

$fields = array('country', 'state', 'zip', 'min_age', 'max_age');
foreach ($fields as $field)
{
    if ($_REQUEST[$field] != '')
    {
        if ($field == 'min_age')
        {
            $meta_query[] = array(
                'key' => $field,
                'value' => $_REQUEST[$field], // This is OK, WP_Query will sanitize input!
                'compare' => '>=',
            );
        } elseif ($field == 'max_age')
        {
            $meta_query[] = array(
                'key' => $field,
                'value' => $_REQUEST[$field], // This is OK, WP_Query will sanitize input!
                'compare' => '<=',
            );
        }
        else
        // We have something to match, otherwise ignore the field...
            $meta_query[] = array(
                'key' => $field,
                'value' => $_REQUEST[$field], // This is OK, WP_Query will sanitize input!
                'compare' => '=',
            );
    }
}
$args = array(
    'post_type' => 'vendor',
    'category__in' => $_REQUEST['category'],
    'posts_per_page' => -1, // -1 to display all results at once
    'order' => 'ASC',
    'meta_query' => $meta_query,
);
$query = new WP_Query($args);
?>
<div id="primary">
    <div id="content" role="main">
        <?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post();
                ?>
                <div class="post">
                    <?php the_title(); ?>
                </div>
                <?php
            endwhile; //end of the loop
        endif;
        ?>
    </div><!-- #content -->
</div><!-- #primary -->

<div id="secondary" class="widget-area" role="complementary">
    <form method="get">

        <label for="country">Country:</label>
        <input type="text" name="country" value="" />

        <label for="state">State: </label>
        <input type="text" name="state" value="" />

        <label for="zip">Zip: </label>
        <input type="text" name="zip" value="" />

        <label for="min_age">Min Age:</label>
        <input type="text" name="min_age" value="" />


        <label for="max_age">Max Age: </label>
        <input type="text" name="max_age" value="" />

        <label for="category">Category:</label><br />
        Category 1<input type="checkbox" value="5" name="category[]" /><br />
        Category 2<input type="checkbox" value="6" name="category[]" /><br />
        Category 3<input type="checkbox" value="7" name="category[]" /><br />
        Category 4<input type="checkbox" value="8" name="category[]" /><br />
        <input type="submit" value="Search" />
    </form>
</div>

<?php get_footer(); ?>

Keeping your Yii Models Lean – Use Behaviors

Active Record models are fantastic for consolidating “black box” logic and keeping your models self-aware of their business logic, but what do you do when the business rules and object specific operations keep adding up?

Do yourself a favor, and get into the habit of putting those business logic methods into attachable behaviors.

If you’re not familiar with Behaviors at all, you can catch the basics here:
http://www.yiiframework.com/doc/api/1.1/CBehavior
http://www.yiiframework.com/doc/api/1.1/CActiveRecordBehavior

Not only does it make it easier to maintain your code, but it makes it much easier for a team to collaborate within the same area of development. You’ll also end up with a nice library of components which you can reuse.

For example, there is the built in timestamp behavior for updating timestamp fields on CActiveRecord models. See: http://www.yiiframework.com/doc/api/1.1/CTimestampBehavior/

Need to ensure that some special logging happens each time a model is saved? Create a CActiveRecordBehavior for the model that has an afterSave method defined to run your checks and fire off the required logs/emails/what have you. You can use the same behavior for multiple models, so that if the logic needs to change, you can easily do so by changing just the behavior and not touch your core models.

Even if the logical process only applies to the one model, it’s worth putting it into a behavior just so that you can adjust the business end of it without modifying the core model.

For example, if you have a ‘Blog’ model that requires approval before it can be publicly visible, it makes sense to put the ‘approve’ method, right on the model so that you can access it consistently from multiple controller actions/etc. But even better, is to make that approve method a behavior that is attached to the model, along with the ‘reject’, etc. methods. Then, if you need to regenerate your core model for some reason (yii upgrade perhaps??) you can do so without losing your business logic pieces and conversely, if you need to update the approval process in some way, you can do so without the potential of breaking your blog model or have one person developing the approval process while another person works on the validation routines, etc. without conflict.

This is especially important when you have very complex rules that need to be applied to a model consistently regardless of where it is accessed from, so it’s a good habit to get into early.

One of the rules of thumb for this is, if you find yourself adding extra properties to the model to track information related to some business process, it’s a good bet you should be making that a behavior.

Originally posted at: http://danaluther.blogspot.com/2011/08/keeping-your-yii-models-lean-use.html

Ajax based Yii login form

/protected/view/site/login.php

<?php
/* @var $this SiteController */
/* @var $model LoginForm */
/* @var $form CActiveForm  */

$this->pageTitle = Yii::app()->name . ' - Login';
$this->breadcrumbs = array(
    'Login',
);
?>

<h1>Login</h1>

<p>Please fill out the following form with your login credentials:</p>

<div class="form">
    <?php
    $form = $this->beginWidget('CActiveForm', array(
        'id' => 'login-form',
        'enableClientValidation' => true,
        'clientOptions' => array(
            'validateOnSubmit' => true,
            'afterValidate' => 'js:function(form, data, hasError) {
                if (!hasError){ 
                    str = $("#login-form").serialize() + "&ajax=login-form";

                    $.ajax({
                        type: "POST",
                        url: "' . Yii::app()->createUrl('site/login') . '",
                        data: str,
                        dataType: "json",
                        beforeSend : function() {
                            $("#login").attr("disabled",true);
                        },
                        success: function(data, status) {
                            if(data.authenticated)
                            {
                                window.location = data.redirectUrl;
                            }
                            else
                            {
                                $.each(data, function(key, value) {
                                    var div = "#"+key+"_em_";
                                    $(div).text(value);
                                    $(div).show();
                                });
                                $("#login").attr("disabled",false);
                            }
                        },
                    });
                    return false;
                }
            }',
        ),
    ));
    ?>

    <p class="note">Fields with <span class="required">*</span> are required.</p>

    <div class="row">
        <?php echo $form->labelEx($model, 'username'); ?>
        <?php echo $form->textField($model, 'username'); ?>
        <?php echo $form->error($model, 'username'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model, 'password'); ?>
        <?php echo $form->passwordField($model, 'password'); ?>
        <?php echo $form->error($model, 'password'); ?>
    </div>

    <div class="row rememberMe">
        <?php echo $form->checkBox($model, 'rememberMe'); ?>
        <?php echo $form->label($model, 'rememberMe'); ?>
        <?php echo $form->error($model, 'rememberMe'); ?>
    </div>

    <div class="row buttons">
        <?php echo CHtml::submitButton('Login', array('id' => 'login')); ?>
    </div>

    <?php $this->endWidget(); ?>
</div><!-- form -->

actionlogin in protected/controllers/SiteController.php

     /**
     * Displays the login page
     */
    public function actionLogin()
    {
        $model = new LoginForm;

        // if it is ajax validation request
        if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form')
        {
            $errors = CActiveForm::validate($model);
            if ($errors != '[]')
            {
                echo $errors;
                Yii::app()->end();
            }
        }

        // collect user input data
        if (isset($_POST['LoginForm']))
        {
            $model->attributes = $_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if ($model->validate() && $model->login())
            {
                if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form')
                {
                    echo CJSON::encode(array(
                        'authenticated' => true,
                        'redirectUrl' => Yii::app()->user->returnUrl,
                        "param" => "Any additional param"
                    ));
                    Yii::app()->end();
                }
                $this->redirect(Yii::app()->user->returnUrl);
            }
        }
        // display the login form
        $this->render('login', array('model' => $model));
    }

How to save multiple related models in yii [Complete Solution]

Table Structure:

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

CREATE TABLE IF NOT EXISTS `children` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `father_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `father_id` (`father_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

ALTER TABLE `children`
  ADD CONSTRAINT `children_ibfk_1` FOREIGN KEY (`father_id`) REFERENCES `fathers` (`id`) ON DELETE CASCADE;


Father Model:

/**
 * This is the model class for table "fathers".
 *
 * The followings are the available columns in table 'fathers':
 * @property integer $id
 * @property string $name
 *
 * The followings are the available model relations:
 * @property Children[] $childrens
 */
class Father extends CActiveRecord
{

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Father the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'fathers';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('name', 'required'),
            array('name', 'length', 'max' => 255),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, name', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'children' => array(self::HAS_MANY, 'Child', 'father_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'name' => 'Name',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);
        $criteria->compare('name', $this->name, true);

        return new CActiveDataProvider($this, array(
                    'criteria' => $criteria,
                ));
    }

    public function behaviors()
    {
        return array('ESaveRelatedBehavior' => array(
                'class' => 'application.components.ESaveRelatedBehavior')
        );
    }

}

Child Model:


<?php

/**
 * This is the model class for table "children".
 *
 * The followings are the available columns in table 'children':
 * @property integer $id
 * @property integer $father_id
 * @property string $name
 * @property integer $age
 *
 * The followings are the available model relations:
 * @property Fathers $father
 */
class Child extends CActiveRecord
{

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Child the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'children';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('father_id, name, age', 'required'),
            array('father_id, age', 'numerical', 'integerOnly' => true),
            array('name', 'length', 'max' => 255),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, father_id, name, age', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'father' => array(self::BELONGS_TO, 'Father', 'father_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'father_id' => 'Father',
            'name' => 'Name',
            'age' => 'Age',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);
        $criteria->compare('father_id', $this->father_id);
        $criteria->compare('name', $this->name, true);
        $criteria->compare('age', $this->age);

        return new CActiveDataProvider($this, array(
                    'criteria' => $criteria,
                ));
    }

    

}

Father Controller:

<?php

class FatherController extends Controller
{

    /**
     * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
     * using two-column layout. See 'protected/views/layouts/column2.php'.
     */
    public $layout = '//layouts/column2';

    /**
     * @return array action filters
     */
    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
            'postOnly + delete', // we only allow deletion via POST request
        );
    }

    /**
     * Specifies the access control rules.
     * This method is used by the 'accessControl' filter.
     * @return array access control rules
     */
    public function accessRules()
    {
        return array(
            array('allow', // allow all users to perform 'index' and 'view' actions
                'actions' => array('index', 'view'),
                'users' => array('*'),
            ),
            array('allow', // allow authenticated user to perform 'create' and 'update' actions
                'actions' => array('create', 'update', 'loadChildByAjax'),
                'users' => array('@'),
            ),
            array('allow', // allow admin user to perform 'admin' and 'delete' actions
                'actions' => array('admin', 'delete'),
                'users' => array('admin'),
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    /**
     * Displays a particular model.
     * @param integer $id the ID of the model to be displayed
     */
    public function actionView($id)
    {
        $this->render('view', array(
            'model' => $this->loadModel($id),
        ));
    }

    /**
     * Creates a new model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     */
    public function actionCreate()
    {
        $model = new Father;

        // Uncomment the following line if AJAX validation is needed
        $this->performAjaxValidation($model);

        if (isset($_POST['Father']))
        {
            $model->attributes = $_POST['Father'];

            if (isset($_POST['Child']))
            {
                $model->children = $_POST['Child'];
            }
            if ($model->saveWithRelated('children'))
                $this->redirect(array('view', 'id' => $model->id));
            else
                $model->addError('children', 'Error occured while saving children.');
        }

        $this->render('create', array(
            'model' => $model,
        ));
    }

    /**
     * Updates a particular model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id the ID of the model to be updated
     */
    public function actionUpdate($id)
    {
        $model = $this->loadModel($id);

        // Uncomment the following line if AJAX validation is needed
        // $this->performAjaxValidation($model);

        if (isset($_POST['Father']))
        {
            $model->attributes = $_POST['Father'];
            if (isset($_POST['Child']))
            {
                $model->children = $_POST['Child'];
            }
            if ($model->saveWithRelated('children'))
                $this->redirect(array('view', 'id' => $model->id));
            else
                $model->addError('children', 'Error occured while saving children.');
        }

        $this->render('update', array(
            'model' => $model,
        ));
    }

    /**
     * Deletes a particular model.
     * If deletion is successful, the browser will be redirected to the 'admin' page.
     * @param integer $id the ID of the model to be deleted
     */
    public function actionDelete($id)
    {
        $this->loadModel($id)->delete();

        // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
        if (!isset($_GET['ajax']))
            $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
    }

    /**
     * Lists all models.
     */
    public function actionIndex()
    {
        $dataProvider = new CActiveDataProvider('Father');
        $this->render('index', array(
            'dataProvider' => $dataProvider,
        ));
    }

    /**
     * Manages all models.
     */
    public function actionAdmin()
    {
        $model = new Father('search');
        $model->unsetAttributes();  // clear any default values
        if (isset($_GET['Father']))
            $model->attributes = $_GET['Father'];

        $this->render('admin', array(
            'model' => $model,
        ));
    }

    /**
     * Returns the data model based on the primary key given in the GET variable.
     * If the data model is not found, an HTTP exception will be raised.
     * @param integer the ID of the model to be loaded
     */
    public function loadModel($id)
    {
        $model = Father::model()->findByPk($id);
        if ($model === null)
            throw new CHttpException(404, 'The requested page does not exist.');
        return $model;
    }

    /**
     * Performs the AJAX validation.
     * @param CModel the model to be validated
     */
    protected function performAjaxValidation($model)
    {
        if (isset($_POST['ajax']) && $_POST['ajax'] === 'father-form')
        {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
    }

    public function actionLoadChildByAjax($index)
    {
        $model = new Child;
        $this->renderPartial('child/_form', array(
            'model' => $model,
            'index' => $index,
//            'display' => 'block',
        ), false, true);
    }

}

Create Father Form:

<?php
/* @var $this FatherController */
/* @var $model Father */
/* @var $form CActiveForm */
?>

<div class="form">

    <?php
    $form = $this->beginWidget('CActiveForm', array(
        'id' => 'father-form',
        'focus' => array($model, 'name'),
        'enableClientValidation' => true,
        'enableAjaxValidation' => true,
            ));
    ?>

    <p class="note">Fields with <span class="required">*</span> are required.</p>

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

    <div class="row">
        <?php echo $form->labelEx($model, 'name'); ?>
        <?php echo $form->textField($model, 'name', array('size' => 60, 'maxlength' => 255)); ?>
        <?php echo $form->error($model, 'name'); ?>
    </div>

    <?php
    echo CHtml::link('Add Child', '#', array('id' => 'loadChildByAjax'));
    ?>
    <div id="children">
        <?php
        $index = 0;
        foreach ($model->children as $id => $child):
            $this->renderPartial('child/_form', array(
                'model' => $child,
                'index' => $id,
                'display' => 'block'
            ));
            $index++;
        endforeach;
        ?>
    </div>

    <div style="clear:both;"></div>
    <div class="row buttons">
        <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
    </div>

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

</div><!-- form -->

<?php
Yii::app()->clientScript->registerCoreScript('jquery');
Yii::app()->clientScript->registerScript('loadchild', '
var _index = ' . $index . ';
$("#loadChildByAjax").click(function(e){
    e.preventDefault();
    var _url = "' . Yii::app()->controller->createUrl("loadChildByAjax", array("load_for" => $this->action->id)) . '&index="+_index;
    $.ajax({
        url: _url,
        success:function(response){
            $("#children").append(response);
            $("#children .crow").last().animate({
                opacity : 1, 
                left: "+50", 
                height: "toggle"
            });
        }
    });
    _index++;
});
', CClientScript::POS_END);
?>

Child form: views\father\child\_form.php

<div style="margin-bottom: 20px; display: <?php echo!empty($display) ? $display : 'none'; ?>; width:100%; clear:left;" class="crow">

    <div class="row" style="width:200px;float: left;">
        <?php echo CHtml::activeLabelEx($model, '[' . $index . ']name'); ?>
        <?php echo CHtml::activeTextField($model, '[' . $index . ']name', array('size' => 20, 'maxlength' => 255)); ?>
        <?php echo CHtml::error($model, '[' . $index . ']name'); ?>
    </div>

    <div class="row" style="width:200px;float: left;">
        <?php echo CHtml::activeLabelEx($model, '[' . $index . ']age'); ?>
        <?php echo CHtml::activeTextField($model, '[' . $index . ']age'); ?>
        <?php echo CHtml::error($model, '[' . $index . ']age'); ?>
    </div>
    <div class="row" style="width:100px;float: left;">
        <br />
        <?php echo CHtml::link('Delete', '#', array('onclick' => 'deleteChild(this, ' . $index . '); return false;'));
        ?>
    </div>
</div>

<?php
Yii::app()->clientScript->registerScript('deleteChild', "
function deleteChild(elm, index)
{
    element=$(elm).parent().parent();
    /* animate div */
    $(element).animate(
    {
        opacity: 0.25, 
        left: '+=50', 
        height: 'toggle'
    }, 500,
    function() {
        /* remove div */
        $(element).remove();
    });
}", CClientScript::POS_END);

This solution uses esaverelatedbehavior developed by sluderitz for saving related models, you can download it here
http://www.yiiframework.com/extension/esaverelatedbehavior/