Yii model sorting - 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'),
));

Related

How to do Sorting in CActiveDataProvider in YII?

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)

Expression Engine Module tables and datasort

I am currently working on a custom module add-on and I wanted to be able to use sorting and filtering on the a table in my control panel admin. I am using the EE table class and form helper. I'm trying to follow the documentation here for setting it up, but when I call try to call the '_datasource' method in my class I get this error
Fatal error: Call to undefined method Content_publish::_datasource() in /home/public_html/system/expressionengine/libraries/EE_Table.php on line 162
I have a feeling it's a scoping issue, but in the table class '$this->EE->table->datasource()' method you are supposed to just pass a string value with the name of your datasource function which is what I'm doing.
I don't seem to be the only one with this issue. There are more details and code examples on this EE Discussion forum thread
The documentation is not really clear. I also tried looking at EE's own comments module to see if i could figure it out, but no luck. Anyone have experience with this?
Here is the method I'm calling:
$data = $this->EE->table->datasource('_datasource');
And this is my function in my class:
function _datasource()
{
// ....
// $query comes from DB result set code above.
// I have omitted it here for brevity
$datarows = array();
foreach ($query->result_array() as $key => $row)
{
$datarows[] = array(
'entry_id' => $row['entry_id'],
'date' => date('Y-m-d',$row['entry_date']),
'author' => $row['screen_name'],
'payment' => $payment_amount,
'status' => $status,
'title' => $edit_href.$row['title']."</a>"
);
}
return $datarows;
}
Your datasource callback function must be on your Module_mcp class (looking at your forum thread you are trying to use it on a plugin which would explain the error).
If you want to put the datasource method on a different class, then just add this line right before you call datasource() to trick the table library into using the correct class:
// ensure table callbacks use this class rather than our MCP file
$this->EE->_mcp_reference =& $this;
$data = $this->EE->table->datasource('_datasource');
The table and form_validation libraries are the only two which use the special _mcp_reference variable, so I can't see any side effects to changing it, and have successfully done this in at least two modules.
On a side note, if you want a good example of how to use the built in tablesorter, take a look at system/expressionengine/controllers/cp/members.php. The documentation is pretty bad, but the source code always tells the truth :)
I've been having issues too and have a mixed solution of generate() and datasource working. Here it is here:
In my mcp file:
public function index()
{
$this->EE->cp->set_variable('cp_page_title', lang('my_module_name'));
$data = $this->EE->table->datasource('_datasource');
return $this->EE->load->view('index', $data, TRUE);
}
public function _datasource()
{
$headers = array(
'name' => array('header' => 'Name'),
'color' => array('header' => 'Color'),
'size' => array('header' => 'Size')
);
$rows = array(
array('name' => 'Fred', 'color' => 'Blue', 'size' => 'Small'),
array('name' => 'Mary', 'color' => 'Red', 'size' => 'Large'),
array('name' => 'John', 'color' => 'Green', 'size' => 'Medium'),
);
return array(
'rows' => $rows,
'headers' => $headers
);
}
In my index view file:
$this->table->set_columns($headers);
$this->table->set_data($rows);
echo $this->table->generate();
Seems to be working at the moment and I've not tried pagination yet, but sorting works.

How do I use setPage() in an non-EAV model in Magento for pagination/limiting?

I need to get $collection->setPage(0, 10); to work on my non-EAV model and it doesn't work. I've tried and $matches->getSelect()->setPage(0, 10); and it doesn't help.
The setPage() method only works for EAV based collection in Magento because it is defined in Mage_Eav_Model_Entity_Collection_Abstract class...
public function setPage($pageNum, $pageSize)
{
$this->setCurPage($pageNum)
->setPageSize($pageSize);
return $this;
}
As you can see, its a nice shorthand utility that is available to EAV based collections. For your non EAV based collection you can create your own version of this in your collection class or use the more verbose syntax for setting the page number and size in your client code when initialising the collection:
$collection->setCurPage($pageNum)
->setPageSize($pageSize)
;
public function updateIndex()
{
$productsCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect(array('name', 'image', 'url_key', 'price', 'visibility'));
$productsCollection->setPageSize(100);
$pages = $productsCollection->getLastPageNumber();
$currentPage = 1;
do {
$productsCollection->setCurPage($currentPage);
$productsCollection->load();
foreach ($productsCollection as $_product) {
$insertData = array(
'entity_id' => $_product->getId(),
'title' => $_product->getName(),
'image' => $_product->getImage(),
'url' => $_product->getUrlKey(),
'price' => $_product->getFinalPrice(),
);
$this->_getWriteAdapter()->insertOnDuplicate(
$this->getTable('atwix_sonar/suggestions'),
$insertData,
array('title', 'image', 'url', 'price')
);
}
$currentPage++;
//clear collection and free memory
$productsCollection->clear();
} while ($currentPage <= $pages);
}
See this complete example, it illustrates exactly how to use magento collection pager functions.
Source : http://www.atwix.com/magento/working-with-large-collections/

yii sort by a custom attribute

In my Vacation model Vac I have this function
public function getVacCount(){
this function returns how many days there are in one vacation.
and I want to add a custom column to the cgridview like this:
<?php
$this->widget('zii.widgets.grid.CGridView', array(
...
array(
'name' => 'count',
'value' => '$data->getVacPeriod()'
),
...
),
));
?>
it works fine.
but I don't know how can I sort upon this custom attribute.
I tried to use CSort but it does not work. any idea?
To use CSort for sorting, you'll need to convert your vacation function into a SQL query and then stash the results in a public variable in your model.
CSort only works with SQL statements/functions, as underneath it's using ORDER BY to do all the sorting.
More info (and demo code) available here
Here's a sample of how I'm doing it on a site of mine:
$criteria->select = array(
"*",
new CDbExpression("IF(survey.RequestDate, survey.RequestDate, SurveyCompleteDate) AS SurveyDate")
);
This then allows me to do this type of filter:
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort'=>array(
'attributes'=>array(
'SurveyDate' => array(
'asc' => 'SurveyDate',
'desc' => 'SurveyDate DESC',
),
'*',
),
),
);
Note: you'll also need a public variable defined in your model to hold the results of the CDbExpression that you're doing. Mine is called SurveyDate.

CakePHP model validation with array

I want to use CakePHP's core validation for lists in my model:
var $validate = array(
'selectBox' => array(
'allowedChoice' => array(
'rule' => array('inList', $listToCheck),
'message' => 'Enter something in listToCheck.'
)
)
);
However, the $listToCheck array is the same array that's used in the view, to populate a selectbox. Where do I put this function?
public function getList() {
return array('hi'=>'Hello','bi'=>'Goodbye','si'=>'Salutations');
}
Already in my controller, in one of the actions I'm setting it for the view, like:
public function actionForForm() {
$options = $this->getList();
$this->set('options', $options);
}
So, I don't want to have to copy the getList() function...where can I put it so the Model can call it to populate its $listToCheck array?
Thanks for your help.
Considering that it's data, you should store the list of valid choices in the model.
class MyModel extends AppModel {
var $fieldAbcChoices = array('a' => 'The A', 'b' => 'The B', 'c' => 'The C');
}
You can get that variable in the Controller simply like this:
$this->set('fieldAbcs', $this->MyModel->fieldAbcChoices);
Unfortunately you can't simply use that variable in the rule declaration for the inList rule, since rules are declared as instance variables and those can only be initialized statically (no variables allowed). The best way around that is to set the variable in the Constructor:
var $validate = array(
'fieldAbc' => array(
'allowedChoice' => array(
'rule' => array('inList', array()),
'message' => 'Enter something in listToCheck.'
)
)
);
function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->validate['fieldAbc']['allowedChoice']['rule'][1] = array_keys($this->fieldAbcChoices);
}
If you're not comfortable overriding the Constructor, you could also do this in a beforeValidate() callback.
Also note that you shouldn't name your field 'selectBox'. :)

Resources