Posting this as an answer, since comments just don't have the space.
It is not an answer for your actual question, but an answer none the less.
In my opinion you are approaching the problem the wrong way.
My question still stands. Why not use core functionality? What does you review module give that core do not have?
The sync? Easy enough to sync into magento's core review system, and I give some examples at the end of my ramblings.
One golden rule, when doing modules, is to enhance, not replace. If there is core functionality that closely matches your planned solution, extend it, don't replace it. Core is stable, use it :) You will end up writing a lot less code, and have a more stable module in the end. Don't re-invent the wheel. It is round, and it works well :)
Magento is a complex application, and adding 3rd party solutions (for existing functionality) needlessly adds to that complexity. This is true for any complex application, not just magento.
You state that you cannot use magento's core review functionality, as you need to sync with an external system, but it looks to me (from the code snippet given) that you are pulling in all the reviews, into the magento database, into a custom table. How you do this is not known, but I assume it is done via a cron/periodic sync. So in the end, you have just duplicated what core already has, since you are not displaying the reviews from the external system directly onto the page. You are saving it in magento db first. (which is the right way, your implementation is not quite right ;) )
Looking at your code, I can already see an inherit issue. You are using product SKU's (textual data) as a means to find the data that you need to display. You are also incorrectly calling this the $product_id
(which by the name of the variable, suggests a numeric value) In magento the product_id
(or entity_id
really) is the key value of the magento product, and you should not make matters confusing by calling a SKU field the product_id
field.
Your table, should in fact not even have the SKU as part of it's structure, but a foreign key value, referencing back to the main product_entity table in magento, ideally set with 'ON DELETE CASCADE'
Using the SKU in a textual match will cause you heaps of issues down the line. What do you do if your client decides to rename all their product sku's? (this can happen, and I have seen it happen multiple times)
But enough of that, and lets get back to the issue in not using core review system, and your sync issue.
How you get the data from the external system (API, direct db connect etc) is beyond the scope of this example, and should be the only code/module you should really need to write. (the connector to/from that system)
In my example I went with a cron based solution, thus the external review system reviews will be pulled in every x minutes)
The code is of the top of my head, thus can be incomplete, or have mistakes, it serves purely as an example of how to do it using core review system.
I also gather the only link between that system and your products is the SKU (hence why you used it as your custom review table lookup key field)
class MyModule_ExternalReviewSystem_Model_Cron {
public function importReviews($schedule){
$externalReviews = CODE TO CONNECT TO EXTERNAL SYSTEM,
AND PULL IN REVIEWS AS AN ARRAY/COLLECTION/DB
ROW ITERATOR HERE.
foreach ($externalReviews as $key => $review) {
$productId = $product->getIdBySku($externalReviews['sku']);
if ($productId) {
$data = array('nickname'=>$externalReviews['name'],
'detail'=>$externalReviews['review'],
'title'=>$externalReviews['subject']);
$review = Mage::getModel('review/review')->setData($data);
$review->setEntityId($review->getEntityIdByCode(Mage_Review_Model_Review::ENTITY_PRODUCT_CODE))
->setEntityPkValue($productId)
->setStatusId(Mage_Review_Model_Review::STATUS_APPROVED)
->setCustomerId(null)
->setStoreId(Mage::app()->getStore()->getId())
->setStores(array(Mage::app()->getStore()->getId()))
->save();
} else {
mage::log("Could not import {$externalReviews['sku']} - not found in local db")
}
}
}
}
Done, now your external system review is inside magento's review system, and magento core will take care of all the rest.
To sync back from core review system is really easier. All you need to do is create an observer which listens to the review model save event, and sync that data back on a save. Thus you would listen to the event review_save_after
, which gets passed the entire review object, from which you can get all the product details, the review data etc.
Using core functionality results in less code, less complexity, less errors, and way way less work for yourself. Not to mention time and money saved for your client :)
Hope this helps.
Your concept is slightly lacking. The query should be at least moved outside of the template into Block
class.
Then in the same class you can add something like this to solve your pagination issue:
protected function _beforeToHtml()
{
$blockName = $this->getToolbarBlockName();
if (!$blockName) {
$blockName = 'product_list_toolbar';
$this->setToolbarBlockName($blockName);
$this->getLayout()->createBlock(
$this->_defaultToolbarBlock,
$blockName,
array(
'show_toolbar' => $this->getData('show_toolbar'),
'list_mode' => $this->getData('list_mode'),
'_current_limit' => $this->getData('limit')
))
->setChild(
$blockName . '_pager',
$this->getLayout()->createBlock('page/html_pager', $blockName . '_pager')
);
}
return parent::_beforeToHtml();
}
Unless you make fun of reinventing the wheel you can also use this extension to create a listing of all products of your store along with couple of other useful listings:
https://github.com/tim-bezhashvyly/CustomListing
Best Answer
So this
main_table
section is added in the abstract collectionMage_Core_Model_Resource_Db_Collection_Abstract
.Sadly throughout magento it is assumed that the main table with have the alias
main_table
so I would say when dealing with a magento collection it would be tough/fruitless to change this. If you want to see how bad it gets simply grep for main_table :(If you change this function to set the alias to
your_alias
then you will get and error as there is a filter added on store_id with the main_table alias so you do not get very far.But if you are building your own sql then you can simply pass in the alais and table to the from function of the select.