How to do Sorting in CActiveDataProvider in YII? - sorting

I write this but it doesn't do any effect in views.
$dataProvider=new CActiveDataProvider('Example', array(
'sort'=>array(
'defaultOrder'=>'title ASC',
)
));
Is any changes in view needed ?

Example Code:
$criteria=new CDbCriteria;
$criteria->compare('display_order',$this->display_order);
$sort = new CSort();
$sort->defaultOrder=array('display_order' => CSort::SORT_DESC);
return new CActiveDataProvider($this, array(
'pagination'=>array(
'pageSize'=>10,
),
'sort'=>$sort,
'criteria'=>$criteria,
));

Try this..
'defaultOrder'=>array('title'=>CSort::SORT_ASC)

Related

How to exclude a rule from a rule set

I have a question about picking validation rules.
I stick my validation rules in the model like so
public $validate = array(
'sentence_fields'=> array(
'select_chapter' => array(
'field'=>'select_chapter',
'label'=>'Select chapter',
'rules'=>'required|integer'
),
'source_sentence' => array(
'field'=>'source_sentence',
'label'=>'Source',
'rules'=>'trim|required|max_length[500]'
),
'translated_sentence' => array(
'field'=>'translated_sentence',
'label'=>'Translation',
'rules'=>'trim|required|max_length[500]'
),
'translated_translation' => array(
'field'=>'translated_translation[]',
'label'=>'Select another translation',
'rules'=>'trim|max_length[500]'
)
)
);
Then call it in the controller like so
$validate = $this->sentence_model->validate['sentence_fields'];
$this->form_validation->set_rules($validate);
That was for the create method, but I have an update method which doesn't require the select_chapter set of rules.
Is there a simple way to call this rule set (sentence_fields), but exclude select_chapter for my update method?
Thanks.
If you want to exclude select_chapter for my update method.Just use array's unset() method like this..
$validate = $this->sentence_model->validate['sentence_fields'];
unset($validate['sentence_fields']['select_chapter ']);//unsets your array
$this->form_validation->set_rules($validate);
As the above method works, I would recommend making it a function to allow better readability and ease of use. To do so have a look at the following
public $validate = array(
'sentence_fields'=> array(
'select_chapter' => array(
'field'=>'select_chapter',
'label'=>'Select chapter',
'rules'=>'required|integer'
),
'source_sentence' => array(
'field'=>'source_sentence',
'label'=>'Source',
'rules'=>'trim|required|max_length[500]'
),
'translated_sentence' => array(
'field'=>'translated_sentence',
'label'=>'Translation',
'rules'=>'trim|required|max_length[500]'
),
'translated_translation' => array(
'field'=>'translated_translation[]',
'label'=>'Select another translation',
'rules'=>'trim|max_length[500]'
)
)
);
public function formValidationRules($validation, $unset = array()) {
if($unset) {
return $this->unsetValidation($unset);
} else {
return $this->validate[$validation];
}
}
private function ($unset) {
$validations = $this->validate[$validation];
foreach($unset as $key)
{
unset($validations[$key]);
}
return $validations;
}
This way you can do your validation as follow:
$validate = $this->sentence_model->formValidationRules('sentence_fields', ['select_chapter']);
$this->form_validation->set_rules($validate);

Yii model sorting

How can I sort by PK in this case?
$model=new SupportTicket('search');
I can do that using search method inside the model, but I have to do that with object.
Sure I can rewrite standard method using DbCriteria, but probably easy way exists?
On 'search()' method, you can put:
$criteria=new CDbCriteria;
$criteria->order = 'id ASC';
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
I always use the find methods provided by CActiveRecord:
$model = SupportTicket::model()->findAll(array('order'=>'PK'));
You can use sort in your in search() model:
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort' => array('defaultOrder' => 'id DESC'),
));

magento - add customer name to order grid in magento 1.7.0.2

I'm trying to add a new column for Customer Name in the Sales Order Grid located here:
App/code/local/Mage/Adminhtml/Block/Sales/Order/Grid.php
I want add Customer Name like Name in Manage Customers.
I have added the following code:
protected function _getCollectionClass()
{
return 'sales/order_grid_collection';
}
protected function _prepareCollection()
{
$collection = Mage::getResourceModel($this->_getCollectionClass());
/*junpeng add start*/
$collection->getSelect()
->join(
'customer_entity',
'main_table.customer_id = customer_entity.entity_id', array('email' => 'email'));
$collection->getSelect()->join(
'customer_entity_varchar',
'main_table.entity_id = customer_entity_varchar.entity_id', array('name' => 'value')
);
/*junpeng add end*/
$this->setCollection($collection);
return parent::_prepareCollection();
}
protected function _prepareColumns()
{
$this->addColumn('name', array(
'header' => Mage::helper('sales')->__('Customer Name'),
'index' => 'name',
));
$this->addColumn('email', array(
'header' => Mage::helper('Sales')->__('Customer Email'),
'index' => 'email',
'type' => 'text',
));
}
Customer Email is OK,but add Customer Name does not work it!
Can someone please help me solve this problem?
You can't get customer name in just one line code join. Firstname and Lastname are different attributes and you will need to join them with your original collection and then concatenate them to display as Fullname.
So basically, Replace
$collection->getSelect()->join(
'customer_entity_varchar',
'main_table.entity_id = customer_entity_varchar.entity_id', array('name' => 'value')
);
with this code
$fn = Mage::getModel('eav/entity_attribute')->loadByCode('1', 'firstname');
$ln = Mage::getModel('eav/entity_attribute')->loadByCode('1', 'lastname');
$collection->getSelect()
->join(array('ce1' => 'customer_entity_varchar'), 'ce1.entity_id=main_table.customer_id', array('firstname' => 'value'))
->where('ce1.attribute_id='.$fn->getAttributeId())
->join(array('ce2' => 'customer_entity_varchar'), 'ce2.entity_id=main_table.customer_id', array('lastname' => 'value'))
->where('ce2.attribute_id='.$ln->getAttributeId())
->columns(new Zend_Db_Expr("CONCAT(`ce1`.`value`, ' ',`ce2`.`value`) AS customer_name"));
And replace your addColumn('name', code in _prepareColumns method where you are getting the customer name, with this:
$this->addColumn('customer_name', array(
'header' => Mage::helper('sales')->__('Customer Name'),
'index' => 'customer_name',
'filter_name' => 'customer_name'
));
There is a free magento extension for this:
http://www.magentocommerce.com/magento-connect/enhanced-admin-grids-editor.html
It's currently alpha, but I have tested it and it works perfectly on 1.6 and 1.7!
I inspire my answer from Kalpesh
so you should replace this code
$collection->getSelect()->join(
'customer_entity_varchar',
'main_table.entity_id = customer_entity_varchar.entity_id', array('name' => 'value')
);
with these lines
$customerTable = Mage::getResourceSingleton('customer/customer')->getEntityTable();
$firstnameAttribute=Mage::getResourceSingleton('customer/customer')->getAttribute('firstname');
$firstnameAttributeTable = $firstnameAttribute->getBackend()->getTable();
$lastnameAttribute=Mage::getResourceSingleton('customer/customer')->getAttribute('lastname');
$lastnameAttributeTable = $lastnameAttribute->getBackend()->getTable();
$collection->getSelect()
->join( array('customer_varchar1'=>$firstnameAttributeTable),'main_table.customer_id =customer_varchar1.entity_id and customer_varchar1.attribute_id='.$firstnameAttribute->getId(),
array('customer_varchar1.value'))
->join( array('customer_varchar2'=>$lastnameAttributeTable),'main_table.customer_id =customer_varchar2.entity_id and customer_varchar2.attribute_id='.$lastnameAttribute->getId(),
array('customer name'=>'CONCAT(customer_varchar2.value ," " ,customer_varchar1.value)'));

WooCommerce Custom Loop to get all product from one specific category

I try to find the code (short code) in the woo comm plugin that made the list of all the product from one category, to be able to modify it... no luck after 1 hours, still no find.
So i start coding it myself (reinventing the wheel) and here what i try to get
get me all the product from category ID="151" and be able to output the name, the permalink etc etc...
this is the code now, that return everything.... way too much ! and i don't know how to filter it
{
$args = array(
'post_type' => 'product',
'posts_per_page' => 99
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
//echo get_title()."<br/>";
var_dump($loop);
endwhile;
}
here is the code i have found, and modify to my needs
function get_me_list_of($atts, $content = null)
{
$args = array( 'post_type' => 'product', 'posts_per_page' => 10, 'product_cat' => $atts[0], 'orderby' => 'rand' );
$loop = new WP_Query( $args );
echo '<h1 class="upp">Style '.$atts[0].'</h1>';
echo "<ul class='mylisting'>";
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
echo '<li>'.get_the_post_thumbnail($loop->post->ID, 'thumbnail').'</li>';
endwhile;
echo "</ul>";
wp_reset_query();
}
?>
The [product_category] shortcode defined in /woocommerce/includes/class-wc-shortcodes.php is a great starting place for this, particularly as Woocommerce is constantly evolving!
The guts of it is just a standard WP_Query with some extra code added on to do pagination, setting sort orders from the Woocommerce settings and some checking to see if the products are marked as visible or not.
So if you strip out the shortcode related code and wanted a function that just got visible products from a category with a specific slug, it would look like this:
function getCategoryProducts($category_slug) {
// Default Woocommerce ordering args
$ordering_args = WC()->query->get_catalog_ordering_args();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'orderby' => $ordering_args['orderby'],
'order' => $ordering_args['order'],
'posts_per_page' => '12',
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array('catalog', 'visible'),
'compare' => 'IN'
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => array( esc_attr( $category_slug ) ),
'field' => 'slug',
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
$products = new WP_Query($args);
woocommerce_reset_loop();
wp_reset_postdata();
return $products;
}
Pass in the slug and you'll get back a standard wordpress posts collection using the same ordering that you've configured in your Woocommerce settings.
I had similar problem as I wanted to get "Fabrics" product for a "Custom Page", here is the code I used.
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'product_cat' => 'fabrics'
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
woocommerce_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
Using the above code means you get the default inline styles, classes and other necessary tags.

filter and CActiveDataProvider in CGridView

I have these code in index action of controller:
public function actionIndex()
{
$cid = #$_GET['cid'];
$country = Country::model()->findByPk($cid);
if($cid)
$dataProvider=new CActiveDataProvider('City', array(
'criteria'=>array(
'condition'=>'ci_co_id ='.$cid,
),
));
else
$dataProvider=new CActiveDataProvider('City');
$this->render('index',array(
'dataProvider'=>$dataProvider,
'country' => $country
));
}
and these in view/index.php file:
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'city-grid',
'dataProvider'=>$dataProvider,
'filter' => $dataProvider,
'columns'=>array(
array(
'name' => ' ',
'value' => '$row + 1',
),
'ci_name',
'ci_pcode',
array(
'class'=>'CButtonColumn',
),
)
));
?>
but Yii gives me this error:
CActiveDataProvider and its behaviors do not have a method or closure named "getValidators".
What is the problem?
The filter has to be a class that extends CModel. However, you don't seem to be doing any actual filtering, so you can just comment the filter line of your CGridView out.
As a side note, you have major security hole in your criteria. You are leaving yourself wide open to an SQL injection attack.
Specify your criteria as follows to let the database handler properly escape the input:
'criteria'=>array(
'condition'=>'ci_co_id =:cid',
'params'=>array(':cid'=>$cid),
),

Resources