Файл: library/XenForo/Model/UserGroupPromotion.php
Строк: 398
<?php
/**
* Model for user group promotions.
*/
class XenForo_Model_UserGroupPromotion extends XenForo_Model
{
const FETCH_USER_NAME = 0x01;
const FETCH_PROMOTION_TITLE = 0x02;
/**
* Gets a promotion by its ID.
*
* @param integer $id
*
* @return array|false
*/
public function getPromotionById($id)
{
return $this->_getDb()->fetchRow('
SELECT *
FROM xf_user_group_promotion
WHERE promotion_id = ?
', $id);
}
/**
* Gets promotions matching the specified conditions.
*
* @param array $conditions
*
* @return array [promotion id] => info
*/
public function getPromotions(array $conditions = array())
{
$sqlConditions = array();
if (isset($conditions['active']))
{
$sqlConditions[] = 'promotion.active = ' . ($conditions['active'] ? 1 : 0);
}
if (isset($conditions['adminQuickSearch']))
{
$sqlConditions[] = 'promotion.title LIKE ' .
XenForo_Db::quoteLike($conditions['adminQuickSearch'], 'lr', $this->_getDb());
}
$whereClause = $this->getConditionsForClause($sqlConditions);
return $this->fetchAllKeyed('
SELECT promotion.*
FROM xf_user_group_promotion AS promotion
WHERE ' . $whereClause . '
ORDER BY promotion.title
', 'promotion_id');
}
/**
* Gets promotion states for all promotions for the specified user. If there is no
* existing promotion state, nothing will be returned.
*
* @param $userId
*
* @return array [promotion id] => state
*/
public function getPromotionStatesByUserId($userId)
{
$results = $this->_getDb()->query('
SELECT promotion_id, promotion_state
FROM xf_user_group_promotion_log
WHERE user_id = ?
', $userId);
$output = array();
while ($result = $results->fetch())
{
$output[$result['promotion_id']] = $result['promotion_state'];
}
return $output;
}
/**
* Gets promotion states for all promotions for the specified users. If there is no
* existing promotion state, nothing will be returned.
*
* @param array $userIds
*
* @return array [user id][promotion id] => state
*/
public function getPromotionStatesByUserIds(array $userIds)
{
if (!$userIds)
{
return array();
}
$db = $this->_getDb();
$results = $db->query('
SELECT user_id, promotion_id, promotion_state
FROM xf_user_group_promotion_log
WHERE user_id IN (' . $db->quote($userIds) . ')
');
$output = array();
while ($result = $results->fetch())
{
$output[$result['user_id']][$result['promotion_id']] = $result['promotion_state'];
}
return $output;
}
/**
* Gets promotion log entries matching the specified criteria.
*
* @param array $conditions
* @param array $fetchOptions
*
* @return array [] => entry
*/
public function getPromotionLogEntries(array $conditions = array(), array $fetchOptions = array())
{
$whereClause = $this->preparePromotionLogEntryConditions($conditions, $fetchOptions);
$joinOptions = $this->preparePromotionLogEntryFetchOptions($fetchOptions);
$limitOptions = $this->prepareLimitFetchOptions($fetchOptions);
return $this->_getDb()->fetchAll($this->limitQueryResults(
'
SELECT log.*
' . $joinOptions['selectFields'] . '
FROM xf_user_group_promotion_log AS log
' . $joinOptions['joinTables'] . '
WHERE ' . $whereClause . '
ORDER BY log.promotion_date DESC
', $limitOptions['limit'], $limitOptions['offset']
));
}
/**
* Counts promotion log entries matching the specified criteria.
*
* @param array $conditions
*
* @return integer
*/
public function countPromotionLogEntries(array $conditions = array())
{
$fetchOptions = array();
$whereClause = $this->preparePromotionLogEntryConditions($conditions, $fetchOptions);
$joinOptions = $this->preparePromotionLogEntryFetchOptions($fetchOptions);
return $this->_getDb()->fetchOne('
SELECT COUNT(*)
FROM xf_user_group_promotion_log AS log
' . $joinOptions['joinTables'] . '
WHERE ' . $whereClause
);
}
/**
* Gets the specified promotion log entry.
*
* @param int $promotionId
* @param int $userId
*
* @return array|false
*/
public function getPromotionLogEntry($promotionId, $userId)
{
return $this->_getDb()->fetchRow('
SELECT *
FROM xf_user_group_promotion_log
WHERE promotion_id = ?
AND user_id = ?
', array($promotionId, $userId));
}
/**
* Prepares a set of conditions to select promotion log entries against.
*
* @param array $conditions List of conditions.
* @param array $fetchOptions The fetch options that have been provided. May be edited if criteria requires.
*
* @return string Criteria as SQL for where clause
*/
public function preparePromotionLogEntryConditions(array $conditions, array &$fetchOptions)
{
$db = $this->_getDb();
$sqlConditions = array();
if (!empty($conditions['user_id']))
{
$sqlConditions[] = 'log.user_id = ' . $db->quote($conditions['user_id']);
}
if (!empty($conditions['promotion_id']))
{
$sqlConditions[] = 'log.promotion_id = ' . $db->quote($conditions['promotion_id']);
}
return $this->getConditionsForClause($sqlConditions);
}
/**
* Prepares join-related fetch options.
*
* @param array $fetchOptions
*
* @return array Containing 'selectFields' and 'joinTables' keys.
*/
public function preparePromotionLogEntryFetchOptions(array $fetchOptions)
{
$selectFields = '';
$joinTables = '';
if (!empty($fetchOptions['join']))
{
if ($fetchOptions['join'] & self::FETCH_USER_NAME)
{
$selectFields .= ',
user.username';
$joinTables .= '
INNER JOIN xf_user AS user ON (log.user_id = user.user_id)';
}
if ($fetchOptions['join'] & self::FETCH_PROMOTION_TITLE)
{
$selectFields .= ',
promotion.title';
$joinTables .= '
INNER JOIN xf_user_group_promotion AS promotion ON (log.promotion_id = promotion.promotion_id)';
}
}
return array(
'selectFields' => $selectFields,
'joinTables' => $joinTables
);
}
public function updatePromotionsForUser(array $user, array $promotionStates = null, array $promotions = null)
{
$changes = 0;
if ($promotions === null)
{
$promotions = $this->getPromotions(array(
'active' => 1
));
}
if (!$promotions)
{
return 0;
}
if ($promotionStates === null)
{
$promotionStates = $this->getPromotionStatesByUserId($user['user_id']);
}
foreach ($promotions AS $promotionId => $promotion)
{
if (isset($promotionStates[$promotionId]))
{
$skip = false;
switch ($promotionStates[$promotionId])
{
case 'manual': // has it, don't take it away
case 'disabled': // never give it
$skip = true;
}
if ($skip)
{
continue;
}
$hasPromotion = true;
}
else
{
$hasPromotion = false;
}
if (XenForo_Helper_Criteria::userMatchesCriteria($promotion['user_criteria'], false, $user))
{
if (!$hasPromotion)
{
$this->promoteUser($promotion, $user['user_id']);
$changes++;
}
}
else if ($hasPromotion)
{
$this->demoteUser($promotion, $user['user_id']);
$changes++;
}
}
return $changes;
}
/**
* Gives a user the specified promotion.
*
* @param array $promotion
* @param integer $userId
* @param string $state Type of promotion (automatic, manual); this affects automatic demotion
*/
public function promoteUser(array $promotion, $userId, $state = 'automatic')
{
$db = $this->_getDb();
XenForo_Db::beginTransaction($db);
$this->_getUserModel()->addUserGroupChange(
$userId, "ugPromotion$promotion[promotion_id]", $promotion['extra_user_group_ids']
);
$this->insertPromotionLogEntry($promotion['promotion_id'], $userId, $state);
XenForo_Db::commit($db);
}
/**
* Demotes a user (removes them from the promotion).
*
* @param array $promotion
* @param integer $userId
* @param boolean $disablePromotion If true, the user will never be given the promotion automatically
*/
public function demoteUser(array $promotion, $userId, $disablePromotion = false)
{
$db = $this->_getDb();
XenForo_Db::beginTransaction($db);
$promotionId = $promotion['promotion_id'];
$this->_getUserModel()->removeUserGroupChange($userId, "ugPromotion$promotionId");
if ($disablePromotion)
{
$this->insertPromotionLogEntry($promotionId, $userId, 'disabled');
}
else
{
// allow it to be re-added
$db->delete('xf_user_group_promotion_log',
'promotion_id = ' . $db->quote($promotionId) . ' AND user_id = ' . $db->quote($userId)
);
}
XenForo_Db::commit($db);
}
/**
* Inserts a promotion log entry.
*
* @param integer $promotionId
* @param integer $userId
* @param string $state Values: automatic, manual, disabled
*/
public function insertPromotionLogEntry($promotionId, $userId, $state = 'automatic')
{
$this->_getDb()->query('
INSERT INTO xf_user_group_promotion_log
(promotion_id, user_id, promotion_date, promotion_state)
VALUES
(?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
promotion_date = VALUES(promotion_date),
promotion_state = VALUES(promotion_state)
', array($promotionId, $userId, XenForo_Application::$time, $state));
}
/**
* @return XenForo_Model_User
*/
protected function _getUserModel()
{
return $this->getModelFromCache('XenForo_Model_User');
}
}