PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/andreustimm/zurmo
PHP | 307 lines | 161 code | 25 blank | 121 comment | 8 complexity | 589a929608e62f53e8574f65828adc6f MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, 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) 2015 Zurmo Inc.
  5. *
  6. * Zurmo is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero 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 Affero General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Affero 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 27 North Wacker Drive
  24. * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
  25. *
  26. * The interactive user interfaces in original and modified versions
  27. * of this program must display Appropriate Legal Notices, as required under
  28. * Section 5 of the GNU Affero General Public License version 3.
  29. *
  30. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  31. * these Appropriate Legal Notices must retain the display of the Zurmo
  32. * logo and Zurmo copyright notice. If the display of the logo is not reasonably
  33. * feasible for technical reasons, the Appropriate Legal Notices must display the words
  34. * "Copyright Zurmo Inc. 2015. All rights reserved".
  35. ********************************************************************************/
  36. /**
  37. * Base class defining rules for gamification behavior.
  38. */
  39. class GamificationRules
  40. {
  41. /**
  42. * Score category used for when a model is created
  43. * @var string
  44. */
  45. const SCORE_CATEGORY_CREATE_MODEL = 'CreateModel';
  46. /**
  47. * Score category used for when a model is updated
  48. * @var string
  49. */
  50. const SCORE_CATEGORY_UPDATE_MODEL = 'UpdateModel';
  51. /**
  52. * Score category used for when a user logs into the system.
  53. * @var string
  54. */
  55. const SCORE_CATEGORY_LOGIN_USER = 'LoginUser';
  56. /**
  57. * Score category used for when a user performs a mass edit in a module
  58. * @var string
  59. */
  60. const SCORE_CATEGORY_MASS_EDIT = 'MassEdit';
  61. /**
  62. * Score category used for when a user performs a mass delete in a module
  63. * @var string
  64. */
  65. const SCORE_CATEGORY_MASS_DELETE = 'MassDelete';
  66. /**
  67. * Score category used for when a user searches in a module
  68. * @var string
  69. */
  70. const SCORE_CATEGORY_SEARCH = 'Search';
  71. /**
  72. * Score category used for when a user imports into a module
  73. * @var string
  74. */
  75. const SCORE_CATEGORY_IMPORT = 'Import';
  76. /**
  77. * Score category used for when a user performs a time sensitive action such as completing a task before the
  78. * due date.
  79. * @var string
  80. */
  81. const SCORE_CATEGORY_TIME_SENSITIVE_ACTION = 'TimeSensitiveAction';
  82. /**
  83. * Whether to score when a model is updated or not.
  84. * @var boolean
  85. */
  86. protected $scoreOnUpdate = true;
  87. /**
  88. * Given a model class name attach scoring events to that class. Every model will then invoke the scoring event.
  89. * @param string $modelClassName
  90. */
  91. public function attachScoringEventsByModelClassName($modelClassName)
  92. {
  93. assert('is_string($modelClassName)');
  94. $modelClassName::model()->attachEventHandler('onAfterSave', array($this, 'scoreOnSaveModel'));
  95. }
  96. /**
  97. * Given a event, perform the onSave score logic for a model ($event->sender)
  98. * @param CEvent $event
  99. */
  100. public function scoreOnSaveModel(CEvent $event)
  101. {
  102. $model = $event->sender;
  103. assert('$model instanceof Item');
  104. if (Yii::app()->gameHelper->isScoringModelsOnSaveMuted())
  105. {
  106. return;
  107. }
  108. if ($model->getIsNewModel())
  109. {
  110. $scoreType = static::resolveCreateScoreTypeByModel($model);
  111. $category = static::SCORE_CATEGORY_CREATE_MODEL;
  112. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  113. }
  114. elseif (!$this->scoreOnUpdate)
  115. {
  116. return;
  117. }
  118. else
  119. {
  120. $scoreType = static::resolveUpdateScoreTypeByModel($model);
  121. $category = static::SCORE_CATEGORY_UPDATE_MODEL;
  122. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  123. }
  124. $gameScore->addValue();
  125. $saved = $gameScore->save();
  126. if (!$saved)
  127. {
  128. throw new FailedToSaveModelException();
  129. }
  130. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  131. static::getPointTypeAndValueDataByCategory($category));
  132. }
  133. protected static function resolveCreateScoreTypeByModel($model)
  134. {
  135. return 'Create' . get_class($model);
  136. }
  137. protected static function resolveUpdateScoreTypeByModel($model)
  138. {
  139. return 'Update' . get_class($model);
  140. }
  141. /**
  142. * Given a score type and score category @return the corresponding point type and value as an array indexed
  143. * by the point type.
  144. * @param string $type
  145. * @param string $category
  146. */
  147. public static function getPointTypeAndValueDataByCategory($category)
  148. {
  149. assert('is_string($category)');
  150. $methodName = 'getPointTypesAndValuesFor' . $category;
  151. if (method_exists(get_called_class(), $methodName))
  152. {
  153. return static::$methodName();
  154. }
  155. else
  156. {
  157. throw new NotImplementedException();
  158. }
  159. }
  160. /**
  161. * @return Point type/value data for generically creating a model.
  162. */
  163. public static function getPointTypesAndValuesForCreateModel()
  164. {
  165. return array(GamePoint::TYPE_USER_ADOPTION => 10);
  166. }
  167. /**
  168. * @return Point type/value data for generically updating a model.
  169. */
  170. public static function getPointTypesAndValuesForUpdateModel()
  171. {
  172. return array(GamePoint::TYPE_USER_ADOPTION => 10);
  173. }
  174. /**
  175. * @return Point type/value data for a user logging in.
  176. */
  177. public static function getPointTypesAndValuesForLoginUser()
  178. {
  179. return array(GamePoint::TYPE_USER_ADOPTION => 10);
  180. }
  181. /**
  182. * @return Point type/value data for a user searching in a module.
  183. */
  184. public static function getPointTypesAndValuesForSearch()
  185. {
  186. return array(GamePoint::TYPE_USER_ADOPTION => 5);
  187. }
  188. /**
  189. * @return Point type/value data for a user performing a mass update in a module.
  190. */
  191. public static function getPointTypesAndValuesForMassEdit()
  192. {
  193. return array(GamePoint::TYPE_USER_ADOPTION => 15);
  194. }
  195. /**
  196. * @return Point type/value data for a user importing into a module
  197. */
  198. public static function getPointTypesAndValuesForImport()
  199. {
  200. return array(GamePoint::TYPE_USER_ADOPTION => 25);
  201. }
  202. /**
  203. * @return Point type/value data for a user performing a time-sensitive action
  204. */
  205. public static function getPointTypesAndValuesForTimeSensitiveAction()
  206. {
  207. return array(GamePoint::TYPE_USER_ADOPTION => 10);
  208. }
  209. /**
  210. * @param string $modelClassName
  211. */
  212. public static function scoreOnSearchModels($modelClassName)
  213. {
  214. assert('is_string($modelClassName)');
  215. $scoreType = 'Search' . $modelClassName;
  216. $category = static::SCORE_CATEGORY_SEARCH;
  217. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  218. $gameScore->addValue();
  219. $saved = $gameScore->save();
  220. if (!$saved)
  221. {
  222. throw new FailedToSaveModelException();
  223. }
  224. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  225. static::getPointTypeAndValueDataByCategory($category));
  226. }
  227. /**
  228. * @param string $modelClassName
  229. */
  230. public static function scoreOnMassEditModels($modelClassName)
  231. {
  232. assert('is_string($modelClassName)');
  233. $scoreType = 'MassEdit' . $modelClassName;
  234. $category = static::SCORE_CATEGORY_MASS_EDIT;
  235. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  236. $gameScore->addValue();
  237. $saved = $gameScore->save();
  238. if (!$saved)
  239. {
  240. throw new FailedToSaveModelException();
  241. }
  242. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  243. static::getPointTypeAndValueDataByCategory($category));
  244. }
  245. /**
  246. * @param string $modelClassName(mass delete)
  247. */
  248. public static function scoreOnMassDeleteModels($modelClassName)
  249. {
  250. assert('is_string($modelClassName)');
  251. $scoreType = 'MassDelete' . $modelClassName;
  252. $category = static::SCORE_CATEGORY_MASS_DELETE;
  253. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  254. $gameScore->addValue();
  255. $saved = $gameScore->save();
  256. if (!$saved)
  257. {
  258. throw new FailedToSaveModelException();
  259. }
  260. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  261. static::getPointTypeAndValueDataByCategory($category));
  262. }
  263. /**
  264. * @param string $modelClassName
  265. */
  266. public static function scoreOnImportModels($modelClassName)
  267. {
  268. assert('is_string($modelClassName)');
  269. $scoreType = 'Import' . $modelClassName;
  270. $category = static::SCORE_CATEGORY_IMPORT;
  271. $gameScore = GameScore::resolveToGetByTypeAndPerson($scoreType, Yii::app()->user->userModel);
  272. $gameScore->addValue();
  273. $saved = $gameScore->save();
  274. if (!$saved)
  275. {
  276. throw new FailedToSaveModelException();
  277. }
  278. GamePointUtil::addPointsByPointData(Yii::app()->user->userModel,
  279. static::getPointTypeAndValueDataByCategory($category));
  280. }
  281. }
  282. ?>