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 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 Nd8v7ug$=f_0|4@O&iViV delta 4315 zcmeyKe>}hbo)F7a1_lO(8w?B#G7Jn1ci0#hR2dl<=J0|<85j(N7#KJh7#IwN7#KJi z7#OUed>0`G25trh245it25|-khDad>25klghC(3*1|9|mhPgrv415d>46C5(cM35u zure?(91>z+5Mp3pI3dKqz{|i;&v09afkBFaf#IbP1A_brfq{Wnlz~B!fq_9$6vB5FWnkcEU|#TXdsB|t$h25~8qI7EYt zI4Ecs7%ashA>by?zyMMgAr3LPP@I8*g@J*gTpXgW2C8owRNrPOeLx&y;aPEr1MflU zmr!%Qh%?lK6W1?sNSrWBKzzt80kKG30^$%|35d_EBp?PkN0~HUGfH)*p0ulw~ z5)g;CL-o&unzsz9evJggzReQ#5CeBZ4Ll|RNsJeu8eU64g8HKbB(DEUKzyz!35jzx zNd^W5P_B@KI5Zl{&ya+u@05fj&ec%)Ly{2l&qMjI>LnrB>pN5clodoliAxG1t}F!! zLLDgv1{DSd23sjeu1Jz%U;wG>kb5fq@}L7NWmb7UH3~P$AH2+KqGit-E$N}&AjEDy=wX;8XU9ulW5@(_#W$U}m7Ayj;oJj5Y~KgxCeB1^1!)o+&~c z`au!mV=g5KEv&@AaDb74K}HFp|E@Ab{IN1L|G!a&gur)Y28J^X3=GUFkbHVU1(K>? zt3dMc4;6^R_*Efssi+FchWe_IkZ@In6s@7EkP@?06_Td{(7@)5PN#*`fx?T<9fc0vSAUvi9G5DeyB*bn)6d!Pz0szVHVr4Gra|I{HNAgBT1 zD{DaH%`_k(;-vwRkI;aGT$TpJymF|z9w>i-2G~LM3|loIE<6oYa2smSdkqF~ef<|o zvuHwskXsXy?bJ0PX~RR4fk6q>0D;mqnvjs1uL;SH+cY5_yr&6q@Hb6J6mV*RLb9HL zK}`#iIt{hJE@Cj#f~0aEEr>z&T9C9cO$*}FMNoCyv>*na(SjtZ`&y6?cnUU{f#I_j z0|N&m1H(V4Ji87gYI$`a9@EufVBiPke-j-@P`T(p;xbSNVo|gX#DaVsNDwwb`O~2W ztkQv`;*B~WpD-}&f|_#_YR)AcNQm9hfjIDo4kRT0=|Dn8OqYS79#oIp=|WPwvo54y ziPMGnyjd4gvdx0h2X!Hd=7lcAr{8rUQOBwWae$~EL|#D;;&6REh>xB0AP!B^gV>X; z2Wh&s=`qxU+i)A98t&*pnnv&SAgP;IAL3F`eMr8x)rS;J;ZV9!9}<+S^&vjoqz?(H z9r}1A`$01H%qO1_mnz28LILkRVkxg80P32%7q#{755+12c^vX{f>oVo{S31A_(w z14FkFBW)@Tgz=^|r@k5(8%Dw!k3ki_)L z7!pNHCJ60`7nBw?hlnefL&_0N zD6MA>F~`^(5>>Y5kdo04DxP4@z`*9iz`&4Y4)IYT)Sx8W44|H46axc82dEzg zk@o^qVW8Fnn8m=bgMoqJIs*fPAC$j>fq@~Ofq~%)0|P@ZsDsDAz;FO6m&*W2Jt+(f z4AUpCBhfng^D14A_f149|8G0p%f4+9t&7|u=pC@5^W7StJmjxB&RtYctcI09lo zaT5ar!yX0(hSQ*)G)Qc-sZcHF=0nmu*$fQK6^sn6OpUY+3=Isp0{nG@Qp+-nGxPIw fT@p)DtrUz53{7+mOm$)EHm_Fddb->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