From ea828a88dc40f5764c93ebbcf34a0f97b49699f2 Mon Sep 17 00:00:00 2001 From: coderkun Date: Thu, 15 May 2014 18:17:51 +0200 Subject: [PATCH] store the total amount of achievable XPs for a Questgroup in the database instead of calculating it every time (Issue #281) --- configs/AppConfig.inc | 2 +- controllers/QuestgroupsController.inc | 10 +- controllers/SeminariesController.inc | 44 ++- locale/de_DE/LC_MESSAGES/The Legend of Z.mo | Bin 14279 -> 14327 bytes locale/de_DE/LC_MESSAGES/The Legend of Z.po | 38 +-- models/QuestgroupsModel.inc | 311 +++++++++----------- models/SeminariesModel.inc | 6 +- views/html/questgroups/questgroup.tpl | 4 +- views/html/seminaries/calculatexps.tpl | 0 views/html/seminaries/seminary.tpl | 5 +- 10 files changed, 211 insertions(+), 209 deletions(-) create mode 100644 views/html/seminaries/calculatexps.tpl diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc index e06e0ec5..8291a1f1 100644 --- a/configs/AppConfig.inc +++ b/configs/AppConfig.inc @@ -208,7 +208,7 @@ array('^users/([^/]+)/(edit|delete)/?$', 'users/$2/$1', true), array('^users/(?!(index|login|register|logout|manage|create|edit|delete))/?', 'users/user/$1', true), array('^seminaries/([^/]+)/(edit|delete)/?$', 'seminaries/$2/$1', true), - array('^seminaries/(?!(index|create|edit|delete))/?', 'seminaries/seminary/$1', true), + array('^seminaries/(?!(index|create|edit|delete|calculatexps))/?', 'seminaries/seminary/$1', true), array('^questgroups/([^/]+)/(create)/?$', 'questgroups/$2/$1', true), array('^questgroups/([^/]+)/([^/]+)/?$', 'questgroups/questgroup/$1/$2', true), array('^quests/([^/]+)/?$', 'quests/index/$1', true), diff --git a/controllers/QuestgroupsController.inc b/controllers/QuestgroupsController.inc index 8eb03d38..43402ce1 100644 --- a/controllers/QuestgroupsController.inc +++ b/controllers/QuestgroupsController.inc @@ -113,10 +113,8 @@ } } - // Get cumulated data - $data = $this->Questgroups->getCumulatedDataForQuestgroup($group['id'], $character['id']); - $group['xps'] = $data['xps']; - $group['character_xps'] = $data['character_xps']; + // Get Character XPs + $group['character_xps'] = $this->Questgroups->getAchievedXPsForQuestgroup($group['id'], $character['id']); // Attach related Questgroups $group['relatedQuestgroups'] = array(); @@ -125,6 +123,7 @@ if($this->Questgroups->hasCharacterEnteredQuestgroup($relatedQuestgroup['id'], $character['id'])) { $group['relatedQuestgroups'][] = $this->Questgroups->getQuestgroupById($relatedQuestgroup['id']); } + } } } @@ -133,9 +132,6 @@ // Get texts $questgroupTexts = $this->Questgroups->getQuestgroupTexts($questgroup['id']); - // Get Character XPs - $questgroup['character_xps'] = $this->Questgroups->getAchievedXPsForQuestgroup($questgroup['id'], $character['id']); - // Media $picture = null; if(!is_null($questgroup['questgroupspicture_id'])) diff --git a/controllers/SeminariesController.inc b/controllers/SeminariesController.inc index c4e72dd6..0c392a87 100644 --- a/controllers/SeminariesController.inc +++ b/controllers/SeminariesController.inc @@ -35,7 +35,8 @@ 'seminary' => array('admin', 'moderator', 'user'), 'create' => array('admin', 'moderator'), 'edit' => array('admin', 'moderator', 'user'), - 'delete' => array('admin', 'moderator', 'user') + 'delete' => array('admin', 'moderator', 'user'), + 'calculatexps' => array('admin', 'moderator', 'user') ); /** * User seminary permissions @@ -45,7 +46,8 @@ public $seminaryPermissions = array( 'seminary' => array('admin', 'moderator', 'user', 'guest'), 'edit' => array('admin'), - 'delete' => array('admin') + 'delete' => array('admin'), + 'calculatexps' => array('admin', 'moderator') ); @@ -134,10 +136,8 @@ $questgroup['text'] = \hhu\z\Utils::shortenString($text, 100, 120).' …'; } - // Get cumulated data - $data = $this->Questgroups->getCumulatedDataForQuestgroup($questgroup['id'], $character['id']); - $questgroup['xps'] = $data['xps']; - $questgroup['character_xps'] = $data['character_xps']; + // Get Character XPs + $questgroup['character_xps'] = $this->Questgroups->getAchievedXPsForQuestgroup($questgroup['id'], $character['id']); // Get Media $questgroup['picture'] = null; @@ -264,6 +264,38 @@ $this->set('seminary', $seminary); } + + /** + * Action: calculatexps. + * + * (Re-) Calculate the amount of achievable XPs for a Seminary. + * + * @throws IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function calculatexps($seminaryUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Questgrouphierarchy and Questgroups + $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyOfSeminary($seminary['id']); + foreach($questgroupshierarchy as &$hierarchy) + { + // Get Questgroups + $hierarchy['questgroups'] = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id']); + foreach($hierarchy['questgroups'] as &$questgroup) + { + // Calculate achievable XPs + $this->Questgroups->calculateXPsForQuestgroup($questgroup['id']); + } + } + + + // Redirect to Questgroup + $this->redirect($this->linker->link(array('seminary', $seminary['url']), 1)); + } + } ?> diff --git a/locale/de_DE/LC_MESSAGES/The Legend of Z.mo b/locale/de_DE/LC_MESSAGES/The Legend of Z.mo index 19c4f36173fce5b3104977ac904fdcd6a1021878..82b2b8be1d027b7777ac4a74855e11a0d68db122 100644 GIT binary patch delta 4361 zcmYk;3shBA9>?*G@(=S!1?N+W5L;;Uqm(N>LFJo^?UI;>QgWY%P|LQFc!CA zJnliYZ^Z~~L;jgl{9%Zo`I z2nJB~d(eY_MqV+G;2&^_y}tp~e-o;ogSyZ7<{Sm3@<(eJ%TY?>P`i+YT6rF(;BEH) zRMeJKpjJ2!wZa-ys-Hn^>GReG)C3M;I-bU0GKCHbnrT-?RfGPhJ-iE*feEPhW}rH* z!Emg_&y)4u_#uHX7AY zF>2+L?fvPfiOfW8K`m1cP!}woRgI`fw5JvCX zYY%GW0o0xkK_8Ar4fGdVuSUIJk0jUZwa?p7{hzV*UxE~rfhg{(g9PLlm{ipLJX8vA z#$H&6SvVW@-m6G9&34p^-p5Qlj>^RMw%&=fs(m&p17lDN4349q0Vbj{QI0x{b5JRK z3f15xREFwN8CZ)Na1&~v9jFPnpcc}KYTu6P?+a8We?YbG#DQS~K@;T`OdRSnOGKqM z8#SQ<)Bqz<1CGa=a0(8@Ivj=vaTG@IZR!5q=*Rh}_S;YsdB@s{(fa;RQcwoY*asI- z16@X?GCa-gpbx4(6qU-!sFl>94;NxKZp7Yr9F^irsNaLjs59Z^+fyd;FoW^Ua0)%K z6!o1iv@S#K?K;#z&8QT=YwsUMP2?qdipumd|$e+xC^w^4^^KWdlx(YRc4^R{SAFAVvsFiov=bbr$ zH&X9`+JbSYiA_gMbRKGA!6g)w!u6;<-i3PcDC*RHf_m{Hs-u`b?q`~Y%0R%@Z$~|! zfLhQ)_IWibbI+pst3$oF)vX6j3kA*SBx>NV?F+x6I`VJ=BQe$53zfng^x++-voQnN zR`aNJB`Q<2#(Monk}>XcWYI$DJ~8%?Mc>_@%V zj_U9{M&MP{#3ORteiN|^hb|5Eymx@sQs$s90cA`OE|%@7J&`Bc384n?kE46Q7SjoFdL(= zKkCK7sD>jj4vSG+azDmn6>6XbsP=WJiM(cAXP-Bqwx9*|-Y2L`oefgZ1inFiua__% z2L#;uG#o>HCGyXF!Jh)`G04r-c+^B^U;>rrQ56Kb3{u@CM=Z9(vJ3QGM| zYri}<1LKiwnJK6rrsvRyJ28}E)QV1F7XE-bR6Pc}TQ$gfAL{pG0ctB&px)bvOekpf zQBaBxp}yaf$U!wfqyD3mMLIYRW`wm0wURZcl{cW;??s)BL)Zz=qRz-U)I>c)+>GVm zP1J9}Bz^zY6x47jk_5BG);~oJ@DnP9QS6WOVmC}dO(cNY%L402d%pG+Qc2w$iqgHYNwYO*N^KX&g7xNigB<2urITz#8Bi^Ib>U8tuc;Bb=`)iw1>`5BFky|B1G11dLegk(C&l1OpHH0pm zhNnX%jvtOB_BxwA>0z%qt)BF5wbaKDZxW9Y?1O1{u6S|+TPPhPw0*j!6Ap1e6|U1R zq3q12+~iD3NY7tI=^pz;BoWWpdNUp*ju5MfUBq9BCC;{l^wh1C>WSBh3SufzP1F!O zoi7tIBi^Re;&{C&881-M^&zo?7)AVpxOOdc3cZaM+j{~{jx zU40qlKic{pe4Lm^Y$9}|i--@L&%B9&?UeQr`oAAteGnAP=( z=(y4cD@x~9JUFM!H?gRyaaBrlq(6}F3k)p?NoOt&iViV delta 4315 zcmYk-4RpN2DF$!~Ry$3dk9HVeO4QH_hh9?*kkJn);reQnmhw88x+u#gL!!_6vYi#`tY9d}bQ-8Vq ziN-=?ZDtTQ!C@G~_+|`+EE=9c4P4%E!u`!~FG2Oc4%N?lYG-`&H3g;ewDlq?rB_kAkjV11@)T^1S*Z5Ds4W?YTH$ci z3df^TJqfj?&s&$HCa?{Y@l$kKQ8-IMGi}7Edf^7t9(F}#pcm@72T&c4$8aphh83dT zD?zj^Q5|NWR+fY6s5@%qeQf&x z)Iwi%z_cNOI zydC;52Q|<`w*DCE`PoQv%|?5_8r6S|t)Fu!Cqf#2lNzz2FN39?gHBdHo z#azt9V$8)iu@|1U?H%~G0@Meh-k*<}$V%&a)IzpmyuSaB?2TH~Ky|1ToSYQOYj!z zWvGc9M9!xWmaxi%?rR*w!ba7BU$%ffsCjuAltt#zGnz;bPQ` zOHqfY3^mXe)N^}KsXc(oSS@Pclc@L3peFh&YQ@oQLnh#^Fn**^?;mG>b^nJHCp4p< zX;20(;X!One)(cdE$URCM}5baQ4@NCtlWuhmt3+6uLr@}miI#Uaf^KD9y zb80G3@7FjK7}Ffb3=HEWse??+#Cxm`Y66>3Dcp$50(zz(~Am4d+BEh0V~1?NMi=0NGYkWSxS_)a%Gx zO%-Z^Cr}Ic3$+DNY04z~-;P2!4M9|jx}Z*ZA5=#U>THytR#1j|t_s!RL5#qYsEMD( zX#5?Ua_H(&_nUMGZLJ5juncVY|GzVZ7#ezD6!u3A^bl%*ai|ndv-KsY4mMy@+>9FV zeT>09sD8dcWvmW0fy<~&)T1)fk^|>x<#$lfY0pOvxOo`0@)wbFWR_WXqYlka=)p^< zt&8Xwnm{7zz7I9=Ow?h{LrrujYMjwXQp}8wcn9h;-Rn@urciGiItPupi~1PkpV`Kr z96X20P-<3aCAVQb^#WTjLQQZaYVRkZ2AYO9<6Kngx1cg!V|A`jP^wcqg??}{P(Mh6 z(1%k|D=0&)=q*gePf&;H9O^JN>Krl+^}A7s+Je!j=ZaAidKs1BQslFB%vuT@NV6aH zpV6Pl_L~-@MdqVkoPgTH$*2zIqRvDqHo^+j+1QGj=t*pj|6o^)?Gl6FQ5`*xO5IGfP{n0DsFGN*rPQmgsBi zZ{Z`vSHyfGjo3x#dYsVd8AdE|*T<$ueM5;8Vb;3GW0O4lC>0PBi7jqeTyn(6l=i!+ zap~SYl>UE}yF=oVy04>YDAAv2Yj3}fRm5!K5V4xj#iw9CZ7A_$j6I3>-R*J7VJqCD zamk4@sO#h0Ogu}l59Vvv6Q3SjPw60`?b9`!c$KJDh3iO&hU`qBywx2UpPc;~rF-oi zkwnb2^$&0_ae!DwR1!}RbKM>B$!#`LDkWADV~B@|NyJp*UH9+!l!*5zedPMRt^Erq z>8c?%5xs~V#IJII?7w$z>KO}Tp+jmwD$qU72G_ysZQfAvL_yV?47oJ>4Tyh%h7 z{fN)qi{6Cb+mv<^`Y%`4JH#gqrO=;g@FDRT;a5{-cJt?=Dyv&>j|>EE^<@Qfva`|y x!9XCo-#rdb->query( - 'SELECT questgroups.id, questgroups_questgroupshierarchy.questgroupshierarchy_id, questgroups_questgroupshierarchy.pos, questgroups.title, questgroups.url, questgroups.questgroupspicture_id '. + 'SELECT questgroups.id, questgroups_questgroupshierarchy.questgroupshierarchy_id, questgroups_questgroupshierarchy.pos, questgroups.title, questgroups.url, questgroups.questgroupspicture_id, questgroups.achievable_xps '. 'FROM questgroups_questgroupshierarchy '. 'INNER JOIN questgroups ON questgroups.id = questgroups_questgroupshierarchy.questgroup_id '. 'WHERE questgroups_questgroupshierarchy.questgroupshierarchy_id = ? AND questgroups_questgroupshierarchy.parent_questgroup_id IS NULL '. @@ -73,7 +73,7 @@ else { $questgroups = $this->db->query( - 'SELECT questgroups.id, questgroups_questgroupshierarchy.questgroupshierarchy_id, questgroups_questgroupshierarchy.pos, questgroups.title, questgroups.url, questgroups.questgroupspicture_id '. + 'SELECT questgroups.id, questgroups_questgroupshierarchy.questgroupshierarchy_id, questgroups_questgroupshierarchy.pos, questgroups.title, questgroups.url, questgroups.questgroupspicture_id, questgroups.achievable_xps '. 'FROM questgroups_questgroupshierarchy '. 'INNER JOIN questgroups ON questgroups.id = questgroups_questgroupshierarchy.questgroup_id '. 'WHERE questgroups_questgroupshierarchy.questgroupshierarchy_id = ? AND questgroups_questgroupshierarchy.parent_questgroup_id = ? '. @@ -98,7 +98,7 @@ public function getQuestgroupsForSeminary($seminaryId) { return $this->db->query( - 'SELECT id, title, url '. + 'SELECT id, title, url, achievable_xps '. 'FROM questgroups '. 'WHERE seminary_id = ? '. 'ORDER BY title ASC', @@ -118,7 +118,7 @@ public function getQuestgroupById($questgroupId) { $data = $this->db->query( - 'SELECT id, title, url, questgroupspicture_id '. + 'SELECT id, title, url, questgroupspicture_id, achievable_xps '. 'FROM questgroups '. 'WHERE questgroups.id = ?', 'i', @@ -144,7 +144,7 @@ public function getQuestgroupByUrl($seminaryId, $questgroupUrl) { $data = $this->db->query( - 'SELECT id, title, url, questgroupspicture_id '. + 'SELECT id, title, url, questgroupspicture_id, achievable_xps '. 'FROM questgroups '. 'WHERE seminary_id = ? AND url = ?', 'is', @@ -428,113 +428,6 @@ /** - * Calculate cumulated data for a Questgroup, its - * sub-Questgroups and all its Quests. - * - * @param int $questgroupId ID of Questgroup - * @param int $characterId ID of Character - * @param array $calculatedQuests IDs of already calculated Quests - * @return array Cumulated data for Questgroup - */ - public function getCumulatedDataForQuestgroup($questgroupId, $characterId=null, &$calculatedQuests=array()) - { - // Cumulated data - $data = array( - 'xps' => 0, - 'character_xps' => 0 - ); - - // Current Questgroup - $questgroup = $this->getQuestgroupById($questgroupId); - - // Quests of current Questgroup - $quest = $this->Quests->getFirstQuestOfQuestgroup($questgroup['id']); - if(!is_null($quest)) - { - $questData = $this->getCumulatedDataForQuest($quest, $characterId, $calculatedQuests); - $data['xps'] += $questData['xps']; - $data['character_xps'] += $questData['character_xps']; - } - - // XPs of child Questgroups - $questgroupHierarchy = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); - if(!empty($questgroupHierarchy)) - { - $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($questgroupHierarchy['id']); - foreach($childQuestgroupshierarchy as &$hierarchy) - { - $questgroups = $this->getQuestgroupsForHierarchy($hierarchy['id'], $questgroup['id']); - foreach($questgroups as &$questgroup) - { - $childData = $this->getCumulatedDataForQuestgroup($questgroup['id'], $characterId, $calculatedQuests); - $data['xps'] += $childData['xps']; - $data['character_xps'] += $childData['character_xps']; - } - } - } - - - // Return cumulated data - return $data; - } - - - /** - * Calculate cumulated data of the given Quest, its following - * Quests and its related Questgroups. - * - * @param array $quest Quest data - * @param int $characterId ID of Character - * @param array $calculatedQuests IDs of already calculated Quests - * @return array Cumulated data for Quest - */ - public function getCumulatedDataForQuest($quest, $characterId=null, &$calculatedQuests=array()) - { - // Cumulated data - $data = array( - 'xps' => $quest['xps'], - 'character_xps' => (!is_null($characterId) && $this->Quests->hasCharacterSolvedQuest($quest['id'], $characterId)) ? $quest['xps'] : 0 - ); - - // Related Questgroups - $relatedQuestgroups = $this->getRelatedQuestsgroupsOfQuest($quest['id']); - foreach($relatedQuestgroups as &$relatedQuestgroup) - { - $relatedData = $this->getCumulatedDataForQuestgroup($relatedQuestgroup['id'], $characterId, $calculatedQuests); - $data['xps'] += $relatedData['xps']; - $data['character_xps'] += $relatedData['character_xps']; - } - - // Next Quests - $nextQuests = $this->Quests->getNextQuests($quest['id']); - $allNextData = array( - 'xps' => array(0), - 'character_xps' => array(0), - ); - foreach($nextQuests as &$nextQuest) - { - if(!array_key_exists($nextQuest['id'], $calculatedQuests)) - { - $nextData = $this->getCumulatedDataForQuest($nextQuest, $characterId, $calculatedQuests); - $calculatedQuests[$nextQuest['id']] = array( - 'xps' => $nextData['xps'], - 'character_xps' => $nextData['character_xps'] - ); - } - - $allNextData['xps'][] = $calculatedQuests[$nextQuest['id']]['xps']; - $allNextData['character_xps'][] = $calculatedQuests[$nextQuest['id']]['character_xps']; - } - $data['xps'] += max($allNextData['xps']); - $data['character_xps'] += max($allNextData['character_xps']); - - - // Return cumulated data - return $data; - } - - - /** * Summarize XPs of all Quests for a Questgroup and its * sub-Questgroups solved by a Character. * @@ -544,75 +437,29 @@ */ public function getAchievedXPsForQuestgroup($questgroupId, $characterId) { - // Sum of XPs - $xps = 0; + // Questgroup + $xps = $this->_getAchievedXPsForQuestgroup($questgroupId, $characterId); - // Current Questgroup - $questgroup = $this->getQuestgroupById($questgroupId); - - // Quests of current Questgroup - $quest = $this->Quests->getFirstQuestOfQuestgroup($questgroup['id']); - if(!is_null($quest)) { - $xps += $this->getAchievedXPsForQuest($quest, $characterId); + // Related Questgroups + foreach($this->getRelatedQuestsgroupsOfQuestgroup($questgroupId) as $relatedQuestgroup) { + $xps += $this->getAchievedXPsForQuestgroup($relatedQuestgroup['id'], $characterId); } // XPs of child Questgroups - $questgroupHierarchy = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); - if(empty($questgroupHierarchy)) { - return $xps; - } - $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($questgroupHierarchy['id']); - foreach($childQuestgroupshierarchy as &$hierarchy) + $questgroupHierarchy = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroupId); + if(!empty($questgroupHierarchy)) { - $questgroups = $this->getQuestgroupsForHierarchy($hierarchy['id'], $questgroup['id']); - foreach($questgroups as &$questgroup) { - $xps += $this->getAchievedXPsForQuestgroup($questgroup['id'], $characterId); - } - } - - - // Return summarized XPs - return $xps; - } - - - /** - * Summarize XPs of the given Quest, its following Quests and - * its related Questgroups solved by a Character. - * - * @param int $quest Quest to summarize XPs for - * @param int $characterId ID of Character - * @return int Sum of XPs - */ - public function getAchievedXPsForQuest($quest, $characterId) - { - $xps = 0; - - // XPs for the given Quest - if($this->Quests->hasCharacterSolvedQuest($quest['id'], $characterId)) - { - $xps += $quest['xps']; - - // Next Quests - $nextQuests = $this->Quests->getNextQuests($quest['id']); - foreach($nextQuests as &$nextQuest) + $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($questgroupHierarchy['id']); + foreach($childQuestgroupshierarchy as &$hierarchy) { - if($this->Quests->hasCharacterEnteredQuest($nextQuest['id'], $characterId)) - { - $xps += $this->getAchievedXPsForQuest($nextQuest, $characterId); - break; + $childQuestgroups = $this->getQuestgroupsForHierarchy($hierarchy['id'], $questgroupId); + foreach($childQuestgroups as &$childQuestgroup) { + $xps += $this->getAchievedXPsForQuestgroup($childQuestgroup['id'], $characterId); } } } - // Related Questgroups - $relatedQuestgroups = $this->getRelatedQuestsgroupsOfQuest($quest['id']); - foreach($relatedQuestgroups as &$relatedQuestgroup) { - $xps += $this->getAchievedXPsForQuestgroup($relatedQuestgroup['id'], $characterId); - } - - // Return summarized XPs return $xps; } @@ -766,6 +613,130 @@ ); } + + /** + * Calculate the total amount of achievable XPs for a + * Questgroup, its sub-Questgroups, related Questgroups etc. and + * store this value in the database. + * + * @param int $questgroupId ID of Questgroup + * @param array $calculatedQuests Already calculated Quests + * @return int Sum of calculated XPs + */ + public function calculateXPsForQuestgroup($questgroupId, &$calculatedQuests=array()) + { + $xps = 0; + + // Quests + $quest = $this->Quests->getFirstQuestOfQuestgroup($questgroupId); + if(!is_null($quest)) { + $xps = $this->_calculateXPsForQuestgroup($quest); + } + + // Child Questgroups + $questgroupHierarchy = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroupId); + if(!empty($questgroupHierarchy)) + { + $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($questgroupHierarchy['id']); + foreach($childQuestgroupshierarchy as &$hierarchy) + { + $questgroups = $this->getQuestgroupsForHierarchy($hierarchy['id'], $questgroupId); + foreach($questgroups as &$questgroup) { + $xps += $this->calculateXPsForQuestgroup($questgroup['id'], $calculatedQuests); + } + } + } + + // Save XPs + $this->setXPsForQuestgroup($questgroupId, $xps); + + + return $xps; + } + + + + + /** + * Get the sum of XPs of Quests for a Questgroup solved by a + * Character. + * + * @param int $questgroupId ID of Questgroup + * @param int $characterId ID of Character + * @return int Sum of XPs of Quests + */ + private function _getAchievedXPsForQuestgroup($questgroupId, $characterId) + { + $data = $this->db->query( + 'SELECT COALESCE(SUM(quests.xps),0) AS xps '. + 'FROM quests '. + 'INNER JOIN quests_characters ON quests_characters.quest_id = quests.id AND quests_characters.character_id = ? AND quests_characters.status = ? '. + 'WHERE quests.questgroup_id = ?', + 'iii', + $characterId, + \hhu\z\models\QuestsModel::QUEST_STATUS_SOLVED, + $questgroupId + ); + if(!empty($data)) { + return $data[0]['xps']; + } + } + + + /* + * Calculate the total amount of achievable XPs for a Quest and + * its following Quests by choosing the path with the highest + * amount of XPs. + * + * @param int $quest Quest data + * @param array $calculatedQuests Already calculated Quests + * @return int Sum of calculated XPs + */ + private function _calculateXPsForQuestgroup($quest, &$calculatedQuests=array()) + { + $xps = $quest['xps']; + + // Related Questgroups + $relatedQuestgroups = $this->getRelatedQuestsgroupsOfQuest($quest['id']); + foreach($relatedQuestgroups as &$relatedQuestgroup) { + $xps += $this->calculateXPsForQuestgroup($relatedQuestgroup['id'], $calculatedQuests); + } + + // Next Quests + $nextQuests = $this->Quests->getNextQuests($quest['id']); + $allNextXPs = array(0); + foreach($nextQuests as &$nextQuest) + { + if(!array_key_exists($nextQuest['id'], $calculatedQuests)) { + $calculatedQuests[$nextQuest['id']] = $this->_calculateXPsForQuestgroup($nextQuest, $calculatedQuests); + } + $allNextXPs[] = $calculatedQuests[$nextQuest['id']]; + } + $xps += max($allNextXPs); + + + return $xps; + } + + + /** + * Set achievable XPs for a Questgroup. + * + * @param int $questgroupId ID of Questgroup + * @param int $xps XPs to set + */ + private function setXPsForQuestgroup($questgroupId, $xps) + { + $this->db->query( + 'UPDATE questgroups '. + 'SET achievable_xps = ? '. + 'WHERE id = ?', + 'ii', + $xps, + $questgroupId + ); + } + } ?> diff --git a/models/SeminariesModel.inc b/models/SeminariesModel.inc index 494aadc3..e31cdce7 100644 --- a/models/SeminariesModel.inc +++ b/models/SeminariesModel.inc @@ -122,10 +122,8 @@ { // Get Questgroups $questgroups = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id']); - foreach($questgroups as &$questgroup) - { - $data = $this->Questgroups->getCumulatedDataForQuestgroup($questgroup['id']); - $xps += $data['xps']; + foreach($questgroups as &$questgroup) { + $xps += $questgroup['achievable_xps']; } } diff --git a/views/html/questgroups/questgroup.tpl b/views/html/questgroups/questgroup.tpl index aadc169e..d296deef 100644 --- a/views/html/questgroups/questgroup.tpl +++ b/views/html/questgroups/questgroup.tpl @@ -36,9 +36,9 @@

Fortschritt:

- +
-

/ XP

+

/ XP

diff --git a/views/html/seminaries/calculatexps.tpl b/views/html/seminaries/calculatexps.tpl new file mode 100644 index 00000000..e69de29b diff --git a/views/html/seminaries/seminary.tpl b/views/html/seminaries/seminary.tpl index f85af665..5b757e34 100644 --- a/views/html/seminaries/seminary.tpl +++ b/views/html/seminaries/seminary.tpl @@ -9,6 +9,7 @@
  • 0) : ?>
  • + 0) : ?>
  • @@ -25,9 +26,9 @@

    - +
    -

    / XP

    +

    / XP