/app/protected/modules/gamification/models/GamePoint.php
PHP | 358 lines | 228 code | 23 blank | 107 comment | 14 complexity | 88f263f2e1a3aa7c22f123ade81ddcfc MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, GPL-2.0, LGPL-3.0, LGPL-2.1, BSD-2-Clause
- <?php
- /*********************************************************************************
- * Zurmo is a customer relationship management program developed by
- * Zurmo, Inc. Copyright (C) 2015 Zurmo Inc.
- *
- * Zurmo is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Affero General Public License version 3 as published by the
- * Free Software Foundation with the addition of the following permission added
- * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
- * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
- * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
- *
- * Zurmo is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Affero General Public License along with
- * this program; if not, see http://www.gnu.org/licenses or write to the Free
- * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- *
- * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
- * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
- *
- * The interactive user interfaces in original and modified versions
- * of this program must display Appropriate Legal Notices, as required under
- * Section 5 of the GNU Affero General Public License version 3.
- *
- * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
- * these Appropriate Legal Notices must retain the display of the Zurmo
- * logo and Zurmo copyright notice. If the display of the logo is not reasonably
- * feasible for technical reasons, the Appropriate Legal Notices must display the words
- * "Copyright Zurmo Inc. 2015. All rights reserved".
- ********************************************************************************/
- /**
- * Model for game points.
- */
- class GamePoint extends Item
- {
- /**
- * @var String
- */
- const TYPE_USER_ADOPTION = 'UserAdoption';
- /**
- * @var String
- */
- const TYPE_SALES = 'Sales';
- /**
- * @var String
- */
- const TYPE_NEW_BUSINESS = 'NewBusiness';
- /**
- * @var String
- */
- const TYPE_ACCOUNT_MANAGEMENT = 'AccountManagement';
- /**
- * @var String
- */
- const TYPE_COMMUNICATION = 'Communication';
- /**
- * @var String
- */
- const TYPE_TIME_MANAGEMENT = 'TimeManagement';
- protected $isAudited = false;
- public function __toString()
- {
- if (trim($this->type) == '')
- {
- return Zurmo::t('Core', '(Unnamed)');
- }
- return $this->type;
- }
- public function __set($attributeName, $value)
- {
- if ($attributeName == 'value')
- {
- $this->replaceValue($value);
- }
- else
- {
- parent::__set($attributeName, $value);
- }
- }
- /**
- * Given a point type and Item (Either User or Person), try to find an existing model. If the model does
- * not exist, create it and populate the Item and type. @return The found or created model.
- * @param string $type
- * @param Item $person
- */
- public static function resolveToGetByTypeAndPerson($type, Item $person)
- {
- assert('is_string($type)');
- assert('$person->id > 0');
- assert('$person instanceof Contact || $person instanceof User');
- $searchAttributeData = array();
- $searchAttributeData['clauses'] = array(
- 1 => array(
- 'attributeName' => 'type',
- 'operatorType' => 'equals',
- 'value' => $type,
- ),
- 2 => array(
- 'attributeName' => 'person',
- 'relatedAttributeName' => 'id',
- 'operatorType' => 'equals',
- 'value' => $person->getClassId('Item'),
- ),
- );
- $searchAttributeData['structure'] = '1 and 2';
- $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('GamePoint');
- $where = RedBeanModelDataProvider::makeWhere('GamePoint', $searchAttributeData, $joinTablesAdapter);
- $models = self::getSubset($joinTablesAdapter, null, 2, $where, null);
- if (count($models) > 1)
- {
- $logContent = 'Duplicate Game Point for Person: ' . $person->id . ' with type ' . $type;
- GamificationUtil::logAndNotifyOnDuplicateGameModel($logContent);
- return $models[0];
- }
- if (count($models) == 0)
- {
- $gamePoint = new GamePoint();
- $gamePoint->type = $type;
- $gamePoint->person = $person;
- return $gamePoint;
- }
- return $models[0];
- }
- /**
- * Given a Item (Either User or Person), Try to find an existing models and index the returning array by
- * point type.
- * @param Item $person
- */
- public static function getAllByPersonIndexedByType(Item $person)
- {
- assert('$person->id > 0');
- assert('$person instanceof Contact || $person instanceof User');
- $searchAttributeData = array();
- $searchAttributeData['clauses'] = array(
- 1 => array(
- 'attributeName' => 'person',
- 'relatedAttributeName' => 'id',
- 'operatorType' => 'equals',
- 'value' => $person->getClassId('Item'),
- ),
- );
- $searchAttributeData['structure'] = '1';
- $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('GamePoint');
- $where = RedBeanModelDataProvider::makeWhere('GamePoint', $searchAttributeData, $joinTablesAdapter);
- $models = self::getSubset($joinTablesAdapter, null, null, $where, null);
- $indexedModels = array();
- foreach ($models as $gamePoint)
- {
- $indexedModels[$gamePoint->type] = $gamePoint;
- }
- return $indexedModels;
- }
- public static function getModuleClassName()
- {
- return 'GamificationModule';
- }
- public static function canSaveMetadata()
- {
- return false;
- }
- public static function getDefaultMetadata()
- {
- $metadata = parent::getDefaultMetadata();
- $metadata[__CLASS__] = array(
- 'members' => array(
- 'type',
- 'value',
- ),
- 'relations' => array(
- 'person' => array(static::HAS_ONE, 'Item', static::NOT_OWNED,
- static::LINK_TYPE_SPECIFIC, 'person'),
- 'transactions' => array(static::HAS_MANY, 'GamePointTransaction', static::OWNED),
- ),
- 'rules' => array(
- array('type', 'required'),
- array('type', 'type', 'type' => 'string'),
- array('type', 'length', 'min' => 1, 'max' => 64),
- array('value', 'type', 'type' => 'integer'),
- array('value', 'numerical', 'min' => 1),
- array('value', 'required'),
- array('person', 'required'),
- ),
- 'elements' => array(
- 'person' => 'Person',
- ),
- 'defaultSortAttribute' => 'type',
- 'noAudit' => array(
- 'type',
- 'value',
- 'person',
- 'transactions'
- ),
- );
- return $metadata;
- }
- public static function isTypeDeletable()
- {
- return true;
- }
- /**
- * Add specified value.
- * @param $value
- * @param bool $createTransaction
- */
- public function addValue($value, $createTransaction = true)
- {
- assert('is_int($value)');
- assert('is_bool($createTransaction)');
- $this->unrestrictedSet('value', $this->value + $value);
- if ($createTransaction)
- {
- $gamePointTransaction = new GamePointTransaction();
- $gamePointTransaction->value = $value;
- $this->transactions->add($gamePointTransaction);
- }
- }
- /**
- * Replace value with specified value.
- * @param int $value
- */
- public function replaceValue($value)
- {
- assert('is_int($value)');
- $oldValue = $this->value;
- $this->unrestrictedSet('value', $value);
- $gamePointTransaction = new GamePointTransaction();
- $gamePointTransaction->value = $value - $oldValue;
- $this->transactions->add($gamePointTransaction);
- }
- /**
- * Given a user and a number, determine if a user's existing total points exceeds the specified number.
- * If so, return true, otherwise return false.
- * @param User $user
- * @param Integer $points
- */
- public static function doesUserExceedPointsByLevelType(User $user, $points, $levelType)
- {
- assert('$user->id > 0');
- assert('is_int($points)');
- assert('is_string($levelType) && $levelType != null');
- $data = self::getSummationPointsDataByLevelTypeAndUser($user, $levelType);
- if ($data != null && $data['sum'] > $points)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- /**
- * @param User $user
- * @param string $levelType
- * @return array
- */
- public static function getSummationPointsDataByLevelTypeAndUser(User $user, $levelType)
- {
- assert('$user->id > 0');
- assert('is_string($levelType) && $levelType != null');
- $wherePart = static::getPointTypeWherePartByLevelType($levelType);
- $sql = "select sum(value) sum from gamepoint where " . $wherePart . " person_item_id = " .
- $user->getClassId('Item') . " group by person_item_id";
- return ZurmoRedBean::getRow($sql);
- }
- /**
- * Performance function to grab all summation data by type for a given user.
- * @param User $user
- * @return array of summation points indexed by the level type
- */
- public static function getSummationPointsDataByUserIndexedByLevelType(User $user)
- {
- assert('$user->id > 0');
- $sql = "select type, sum(value) sum from gamepoint where person_item_id = " .
- $user->getClassId('Item') . " group by type";
- $rows = ZurmoRedBean::getAll($sql);
- $indexedData = array();
- foreach ($rows as $row)
- {
- $indexedData[$row['type']] = $row['sum'];
- }
- return $indexedData;
- }
- /**
- * Given a level type, get the corresponding where sql part to filter by point type if applicable. Level types
- * match point types for now, so if the level type is not valid then it will thrown an exception.
- * @param string $levelType
- * @throws NotSupportedException
- */
- protected static function getPointTypeWherePartByLevelType($levelType)
- {
- assert('is_string($levelType) && $levelType != null');
- if (!in_array($levelType, array(GameLevel::TYPE_GENERAL,
- GameLevel::TYPE_SALES,
- GameLevel::TYPE_NEW_BUSINESS,
- GameLevel::TYPE_ACCOUNT_MANAGEMENT,
- GameLevel::TYPE_TIME_MANAGEMENT,
- GameLevel::TYPE_COMMUNICATION)))
- {
- throw new NotSupportedException();
- }
- if ($levelType == GameLevel::TYPE_GENERAL)
- {
- return null;
- }
- else
- {
- $pointType = $levelType;
- return " type = '" . $pointType . "' and ";
- }
- }
- /**
- * Returns the display name for the model class.
- * @param null | string $language
- * @return dynamic label name based on module.
- */
- protected static function getLabel($language = null)
- {
- return Zurmo::t('GamificationModule', 'Game Point', array(), null, $language);
- }
- /**
- * Returns the display name for plural of the model class.
- * @param null | string $language
- * @return dynamic label name based on module.
- */
- protected static function getPluralLabel($language = null)
- {
- return Zurmo::t('GamificationModule', 'Game Points', array(), null, $language);
- }
- }
- ?>