PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/app/protected/modules/gamification/rules/GamificationRules.php

https://bitbucket.org/mstowe/zurmo
PHP | 272 lines | 145 code | 23 blank | 104 comment | 7 complexity | 3d934a8f96ce6f6978c69e86aa6d1f05 MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause, LGPL-3.0, LGPL-2.1, BSD-2-Clause
  1. <?php
  2. /*********************************************************************************
  3. * Zurmo is a customer relationship management program developed by
  4. * Zurmo, Inc. Copyright (C) 2012 Zurmo Inc.
  5. *
  6. * Zurmo is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU General Public License version 3 as published by the
  8. * Free Software Foundation with the addition of the following permission added
  9. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  10. * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
  11. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  12. *
  13. * Zurmo is distributed in the hope that it will be useful, but WITHOUT
  14. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  15. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU General Public License along with
  19. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  20. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21. * 02110-1301 USA.
  22. *
  23. * You can contact Zurmo, Inc. with a mailing address at 113 McHenry Road Suite 207,
  24. * Buffalo Grove, IL 60089, USA. or at email address contact@zurmo.com.
  25. ********************************************************************************/
  26. /**
  27. * Base class defining rules for gamification behavior.
  28. */
  29. class GamificationRules
  30. {
  31. /**
  32. * Score category used for when a model is created
  33. * @var string
  34. */
  35. const SCORE_CATEGORY_CREATE_MODEL = 'CreateModel';
  36. /**
  37. * Score category used for when a model is updated
  38. * @var string
  39. */
  40. const SCORE_CATEGORY_UPDATE_MODEL = 'UpdateModel';
  41. /**
  42. * Score category used for when a user logs into the system.
  43. * @var string
  44. */
  45. const SCORE_CATEGORY_LOGIN_USER = 'LoginUser';
  46. /**
  47. * Score category used for when a user performs a mass edit in a module
  48. * @var string
  49. */
  50. const SCORE_CATEGORY_MASS_EDIT = 'MassEdit';
  51. /**
  52. * Score category used for when a user searches in a module
  53. * @var string
  54. */
  55. const SCORE_CATEGORY_SEARCH = 'Search';
  56. /**
  57. * Score category used for when a user imports into a module
  58. * @var string
  59. */
  60. const SCORE_CATEGORY_IMPORT = 'Import';
  61. /**
  62. * Score category used for when a user performs a time sensitive action such as completing a task before the
  63. * due date.
  64. * @var string
  65. */
  66. const SCORE_CATEGORY_TIME_SENSITIVE_ACTION = 'TimeSensitiveAction';
  67. /**
  68. * Whether to score when a model is updated or not.
  69. * @var boolean
  70. */
  71. protected $scoreOnUpdate = true;
  72. /**
  73. * Given a model class name attach scoring events to that class. Every model will then invoke the scoring event.
  74. * @param string $modelClassName
  75. */
  76. public function attachScoringEventsByModelClassName($modelClassName)
  77. {
  78. assert('is_string($modelClassName)');
  79. $modelClassName::model()->attachEventHandler('onAfterSave', array($this, 'scoreOnSaveModel'));
  80. }
  81. /**
  82. * Given a event, perform the onSave score logic for a model ($event->sender)
  83. * @param CEvent $event
  84. */
  85. public function scoreOnSaveModel(CEvent $event)
  86. {
  87. $model = $event->sender;
  88. assert('$model instanceof Item');
  89. if (Yii::app()->gameHelper->isScoringModelsOnSaveMuted())
  90. {
  91. return;
  92. }
  93. if ($model->getIsNewModel())
  94. {
  95. $scoreType = static::resolveCreateScoreTypeByModel($model);
  96. $category = static::SCORE_CATEGORY_CREATE_MODEL;
  97. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  98. }
  99. elseif (!$this->scoreOnUpdate)
  100. {
  101. return;
  102. }
  103. else
  104. {
  105. $scoreType = static::resolveUpdateScoreTypeByModel($model);
  106. $category = static::SCORE_CATEGORY_UPDATE_MODEL;
  107. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  108. }
  109. $gameScore->addValue();
  110. $saved = $gameScore->save();
  111. if (!$saved)
  112. {
  113. throw new FailedToSaveModelException();
  114. }
  115. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  116. static::getPointTypeAndValueDataByCategory($category));
  117. }
  118. protected static function resolveCreateScoreTypeByModel($model)
  119. {
  120. return 'Create' . get_class($model);
  121. }
  122. protected static function resolveUpdateScoreTypeByModel($model)
  123. {
  124. return 'Update' . get_class($model);
  125. }
  126. /**
  127. * Given a score type and score category @return the corresponding point type and value as an array indexed
  128. * by the point type.
  129. * @param string $type
  130. * @param string $category
  131. */
  132. public static function getPointTypeAndValueDataByCategory($category)
  133. {
  134. assert('is_string($category)');
  135. $methodName = 'getPointTypesAndValuesFor' . $category;
  136. if (method_exists(get_called_class(), $methodName))
  137. {
  138. return static::$methodName();
  139. }
  140. else
  141. {
  142. throw new NotImplementedException();
  143. }
  144. }
  145. /**
  146. * @return Point type/value data for generically creating a model.
  147. */
  148. public static function getPointTypesAndValuesForCreateModel()
  149. {
  150. return array(GamePoint::TYPE_USER_ADOPTION => 10);
  151. }
  152. /**
  153. * @return Point type/value data for generically updating a model.
  154. */
  155. public static function getPointTypesAndValuesForUpdateModel()
  156. {
  157. return array(GamePoint::TYPE_USER_ADOPTION => 10);
  158. }
  159. /**
  160. * @return Point type/value data for a user logging in.
  161. */
  162. public static function getPointTypesAndValuesForLoginUser()
  163. {
  164. return array(GamePoint::TYPE_USER_ADOPTION => 10);
  165. }
  166. /**
  167. * @return Point type/value data for a user searching in a module.
  168. */
  169. public static function getPointTypesAndValuesForSearch()
  170. {
  171. return array(GamePoint::TYPE_USER_ADOPTION => 5);
  172. }
  173. /**
  174. * @return Point type/value data for a user performing a mass update in a module.
  175. */
  176. public static function getPointTypesAndValuesForMassEdit()
  177. {
  178. return array(GamePoint::TYPE_USER_ADOPTION => 15);
  179. }
  180. /**
  181. * @return Point type/value data for a user importing into a module
  182. */
  183. public static function getPointTypesAndValuesForImport()
  184. {
  185. return array(GamePoint::TYPE_USER_ADOPTION => 25);
  186. }
  187. /**
  188. * @return Point type/value data for a user performing a time-sensitive action
  189. */
  190. public static function getPointTypesAndValuesForTimeSensitiveAction()
  191. {
  192. return array(GamePoint::TYPE_USER_ADOPTION => 10);
  193. }
  194. /**
  195. * @param string $modelClassName
  196. */
  197. public static function scoreOnSearchModels($modelClassName)
  198. {
  199. assert('is_string($modelClassName)');
  200. $scoreType = 'Search' . $modelClassName;
  201. $category = static::SCORE_CATEGORY_SEARCH;
  202. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  203. $gameScore->addValue();
  204. $saved = $gameScore->save();
  205. if (!$saved)
  206. {
  207. throw new FailedToSaveModelException();
  208. }
  209. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  210. static::getPointTypeAndValueDataByCategory($category));
  211. }
  212. /**
  213. * @param string $modelClassName
  214. */
  215. public static function scoreOnMassEditModels($modelClassName)
  216. {
  217. assert('is_string($modelClassName)');
  218. $scoreType = 'MassEdit' . $modelClassName;
  219. $category = static::SCORE_CATEGORY_MASS_EDIT;
  220. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  221. $gameScore->addValue();
  222. $saved = $gameScore->save();
  223. if (!$saved)
  224. {
  225. throw new FailedToSaveModelException();
  226. }
  227. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  228. static::getPointTypeAndValueDataByCategory($category));
  229. }
  230. /**
  231. * @param string $modelClassName
  232. */
  233. public static function scoreOnImportModels($modelClassName)
  234. {
  235. assert('is_string($modelClassName)');
  236. $scoreType = 'Import' . $modelClassName;
  237. $category = static::SCORE_CATEGORY_IMPORT;
  238. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  239. $gameScore->addValue();
  240. $saved = $gameScore->save();
  241. if (!$saved)
  242. {
  243. throw new FailedToSaveModelException();
  244. }
  245. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  246. static::getPointTypeAndValueDataByCategory($category));
  247. }
  248. }
  249. ?>