private:koding:hostcms:modules:shop:useful:comments_pagination:controller
<?php
 
defined('HOSTCMS') || exit('HostCMS: access denied.');
 
/**
* Контроллер для вывода комментариев.
* 
* @author Maxim Zasorin, KAD Systems (©) 2018
* @date 13-02-2018
*/
class Shop_Item_Comment_Controller extends Core_Controller
{
	protected $_allowedProperties = array(
		'offset',
		'limit'
	);
 
	public function __construct(Shop_Item_Model $oShopItem)
	{
		parent::__construct(
			$oShopItem->showXmlComments(FALSE)
		);
 
		$this->offset = 0;
		$this->limit = 2;
	}
 
	public function show()
	{
		Core_Event::notify(get_class($this) . '.onBeforeRedeclaredShow', $this);
 
		$this->addEntity(
			$this->getCommentsXml()
		);
 
		parent::show();
	}
 
	/**
	 * Возвращает информацию о количестве и оценках комментариев на основе все добавленных к товару комментариев.
	 */
	public function getCommentsAggregationXml()
	{
		$sCountAll = 'COUNT(*)';
		$sCountGrades = 'SUM(
			IF (comments.grade > 0,
				1,
				0
			)
		)';
		$sSumGrades = 'SUM(
			IF (comments.grade > 0,
				comments.grade,
				0
			)
		)';
 
		$oCoreQueryBuilder = Core_QueryBuilder::select()
			->select(array(Core_QueryBuilder::expression($sCountAll), 'count'))
			->select(array(Core_QueryBuilder::expression($sCountGrades), 'grade_count'))
			->select(array(Core_QueryBuilder::expression($sSumGrades), 'grade_sum'))
			->from('comments')
			->join('comment_shop_items', 'comment_shop_items.comment_id', '=', 'comments.id', array(
				array('AND' => array('comment_shop_items.shop_item_id', '=', $this->getEntity()->id))
			))
			->where('comments.parent_id', '=', 0)
			->where('comments.active', '=', 1)
			->where('comments.deleted', '=', 0);
 
		$aResult = $oCoreQueryBuilder->execute()->asAssoc()->current();
 
		// Данные для расчета
		$commentsCount = $aResult['count'];
		$gradeSum = $aResult['grade_sum'];
		$gradeCount = $aResult['grade_count'];
 
		// Средняя оценка
		$avgGrade = $gradeCount > 0
			? $gradeSum / $gradeCount
			: 0;
 
		$fractionalPart = $avgGrade - floor($avgGrade);
		$avgGrade = floor($avgGrade);
 
		if ($fractionalPart >= 0.25 && $fractionalPart < 0.75)
		{
			$avgGrade += 0.5;
		}
		elseif ($fractionalPart >= 0.75)
		{
			$avgGrade += 1;
		}
 
		$oAggregationXml = Core::factory('Core_Xml_Entity')
			->name('comments_aggregation')
			->addEntity(
				Core::factory('Core_Xml_Entity')
					->name('count')
					->value($commentsCount)
			)
			->addEntity(
				Core::factory('Core_Xml_Entity')
					->name('grade_sum')
					->value($gradeSum)
			)
			->addEntity(
				Core::factory('Core_Xml_Entity')
					->name('grade_count')
					->value($gradeCount)
			)
			->addEntity(
				Core::factory('Core_Xml_Entity')
					->name('average_grade')
					->value($avgGrade)
			);
 
		return $oAggregationXml;
	}
 
	/**
	 * Возвращает список комментариев для вывода.
	 */
	public function getCommentsXml()
	{
		// Получаем список комментариев первого уровня
		$oComments = $this->getEntity()->Comments;
		$oComments->getTableColums();
		$oComments->queryBuilder()
			->sqlCalcFoundRows()
			->where('comments.active', '=', 1)
			->where('comments.parent_id', '=', 0)
			->orderBy('comments.datetime', 'DESC')
			->offset($this->offset)
			->limit($this->limit);
 
		$aoComments = $oComments->findAll();
 
		// Получаем общее количество родительских комментариев
		$result = Core_QueryBuilder::select(array('FOUND_ROWS()', 'count'))->execute()->asAssoc()->current();
		$total = $result['count'];
 
		$aoParentComments = array();
		$aCommentIds = array();
		foreach ($aoComments as $oComment)
		{
			$aoParentComments[$oComment->id] = $oComment;
			$aCommentIds[] = $oComment->id;
		}
 
		$oCommentsXml = Core::factory('Core_Xml_Entity')
			->name('comments')
			->addEntity(
				Core::factory('Core_Xml_Entity')
					->name('offset')
					->value($this->offset)
			)->addEntity(
				Core::factory('Core_Xml_Entity')
					->name('limit')
					->value($this->limit)
			)->addEntity(
				Core::factory('Core_Xml_Entity')
					->name('total')
					->value($total)
			);
 
		// Получаем список дочерних комментариев
		if ($aCommentIds)
		{
			$oChildComments = Core_Entity::factory('Comment');
			$oChildComments->queryBuilder()
				->where('comments.active', '=', 1)
				->where('comments.parent_id', 'IN', $aCommentIds)
				->orderBy('comments.datetime', 'DESC');
			$aoChildComments = $oChildComments->findAll();
 
			foreach ($aoChildComments as $oChildComment)
			{
				$aoParentComments[$oChildComment->parent_id]
					->addEntity(
						$oChildComment
					);
			}
 
			$oCommentsXml->addEntities(
				$aoParentComments
			);
		}
 
		return $oCommentsXml;
	}
}
private/koding/hostcms/modules/shop/useful/comments_pagination/controller.txt · Last modified: 27.08.18 в 14:37 by maximzasorin_gmail.com