From 9eec61775c77daeb3e9b8c8a6f1b0a6fd1970cf3 Mon Sep 17 00:00:00 2001 From: Shadez Date: Sun, 19 Dec 2010 22:28:00 +0800 Subject: [PATCH] [422] Properly display achievement date (Character feed feature). Thanks to Vasago for a constant reminder about this issue :) --- includes/classes/class.achievements.php | 47 +++++++--- includes/classes/class.characters.php | 116 ++++++++++++++++++------ includes/revision_nr.php | 2 +- 3 files changed, 125 insertions(+), 40 deletions(-) diff --git a/includes/classes/class.achievements.php b/includes/classes/class.achievements.php index 0282f2c5e..d27bf08e8 100644 --- a/includes/classes/class.achievements.php +++ b/includes/classes/class.achievements.php @@ -3,7 +3,7 @@ /** * @package World of Warcraft Armory * @version Release Candidate 1 - * @revision 410 + * @revision 422 * @copyright (c) 2009-2010 Shadez * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @@ -35,39 +35,46 @@ * @category Achievements class * @access public **/ - public $guid; + public $guid = 0; /** * Character achievement points * @category Achievements class * @access public **/ - public $pts; + public $pts = 0; /** * Achievement ID * @category Achievements class * @access public **/ - public $achId; + public $achId = -1; /** * Character achievements count * @category Achievements class * @access private **/ - private $m_count; + private $m_count = 0; + + private $b_isInitialized = false; private $db = null; /** - * Assign $armory variable + * Class constructor, assigns $armory instance. + * @category Achievements class + * @access public + * @param Armory $armory + * @return bool **/ public function Achievements($armory) { if(!is_object($armory)) { die('Fatal Error: armory must be instance of Armory class!'); } $this->armory = $armory; + return true; } /** @@ -75,6 +82,7 @@ public function Achievements($armory) { * @category Achievements class * @access public * @param int $player_guid + * @param ArmoryDatabaseHandler $db * @param bool $check = true * @return bool **/ @@ -96,6 +104,7 @@ public function InitAchievements($player_guid, $db, $check = true) { $this->guid = $player_guid; self::CalculateAchievementPoints(); self::CountCharacterAchievements(); + $this->b_isInitialized = true; return true; } @@ -106,6 +115,10 @@ public function InitAchievements($player_guid, $db, $check = true) { * @return int **/ public function GetAchievementPoints() { + if(!$this->b_isInitialized) { + $this->armory->Log()->writeError('%s : unexpected method call: class was not initialized.', __METHOD__); + return false; + } return $this->pts; } @@ -116,6 +129,10 @@ public function GetAchievementPoints() { * @return int **/ public function GetAchievementsCount() { + if(!$this->b_isInitialized) { + $this->armory->Log()->writeError('%s : unexpected method call: class was not initialized.', __METHOD__); + return false; + } return $this->m_count; } @@ -132,7 +149,7 @@ public function CalculateAchievementPoints() { } $achievement_ids = $this->db->select("SELECT `achievement` FROM `character_achievement` WHERE `guid`=%d", $this->guid); if(!$achievement_ids) { - $this->armory->Log()->writeError('%s : unable to find any completed achievement for player %d', __METHOD__, $this->guid); + $this->armory->Log()->writeError('%s : unable to find any completed achievements for player %d', __METHOD__, $this->guid); return false; } $ids = array(); @@ -172,7 +189,7 @@ public function GetSummaryAchievementData($category) { } $achievement_data = array('categoryId' => $category); $categories = 0; - // 3.3.5a + // 4.0.1 switch($category) { case ACHIEVEMENTS_CATEGORY_GENERAL: $categories = 92; @@ -273,7 +290,7 @@ public function GetLastAchievements() { } $achievements = $this->db->select("SELECT `achievement`, `date` FROM `character_achievement` WHERE `guid`=%d ORDER BY `date` DESC LIMIT 5", $this->guid); if(!$achievements) { - $this->armory->Log()->writeError('%s : unable to get data from character_achievement (player %d does not have achievements?)', __METHOD__, $this->guid); + $this->armory->Log()->writeError('%s : unable to get data from character_achievement (player %d does not have any completed achievement?)', __METHOD__, $this->guid); return false; } $aCount = count($achievements); @@ -288,9 +305,10 @@ public function GetLastAchievements() { * @category Achievements class * @access public * @param int $achId = 0 + * @param bool $returnStamp = false * @return string **/ - public function GetAchievementDate($achId = 0) { + public function GetAchievementDate($achId = 0, $returnStamp = false) { if($achId == 0) { $achId = $this->achId; } @@ -303,6 +321,9 @@ public function GetAchievementDate($achId = 0) { $this->armory->Log()->writeError('%s : unable to find completion date for achievement %d, player %d', __METHOD__, $achId, $this->guid); return false; } + if($returnStamp) { + return $achievement_date; + } return date('d/m/Y', $achievement_date); // Hack (Can't find the reason why achievement date is not displaying. Working on it.) } @@ -414,7 +435,7 @@ public function IsAchievementCompleted($achId) { * @return bool **/ public function IsAchievementExists($achId) { - return $this->armory->aDB->selectCell("SELECT 1 FROM `ARMORYDBPREFIX_achievement` WHERE `id`=%d LIMIT 1", $achId); + return (bool) $this->armory->aDB->selectCell("SELECT 1 FROM `ARMORYDBPREFIX_achievement` WHERE `id`=%d LIMIT 1", $achId); } /** @@ -453,14 +474,14 @@ public function LoadAchievementPage($page_id, $faction) { unset($return_data['completed'][$this->achId]['data']['titleReward']); } if($page_id == ACHIEVEMENTS_CATEGORY_FEATS) { - // Feats of Strength have no achievement points + // Feats of Strength has no achievement points unset($return_data['completed'][$this->achId]['data']['points']); } $return_data['completed'][$this->achId]['data']['dateCompleted'] = self::GetAchievementDate(); $return_data['completed'][$this->achId]['display'] = 1; $parent_used = false; if($parentId > 0 && self::IsAchievementCompleted($parentId)) { - $j=0; + $j = 0; $fullPoints = 0; $return_data['completed'][$this->achId]['achievement_tree'] = array(); while($parentId != 0) { diff --git a/includes/classes/class.characters.php b/includes/classes/class.characters.php index 0741d8361..6ef8d2cb9 100644 --- a/includes/classes/class.characters.php +++ b/includes/classes/class.characters.php @@ -3,7 +3,7 @@ /** * @package World of Warcraft Armory * @version Release Candidate 1 - * @revision 420 + * @revision 422 * @copyright (c) 2009-2010 Shadez * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @@ -248,6 +248,11 @@ **/ private $m_server = null; + /** + * Character feed data + **/ + private $feed_data = array(); + public function Characters($armory) { if(!is_object($armory)) { die('Fatal Error: armory must be instance of Armory class!'); @@ -423,10 +428,15 @@ public function BuildCharacter($name, $realmId = 1, $full = true, $initialBuild if(defined('load_achievements_class') && class_exists('Achievements')) { $this->m_achievementMgr = new Achievements($this->armory); $this->m_achievementMgr->InitAchievements($this->guid, $this->db, true); + if($full) { + // Load Feed data + $this->LoadFeedData(); + // Character feed feature requires Achievements class! + } } // Everything correct if($initialBuild == true) { - $this->armory->Log()->writeLog('%s : all correct, player %s (race: %d, class: %d, level: %d) loaded, class has been initialized.', __METHOD__, $name, $this->race, $this->class, $this->level); + $this->armory->Log()->writeLog('%s : all correct, player %s (GUID: %d, race: %d, class: %d, level: %d) loaded, class has been initialized.', __METHOD__, $name, $this->guid, $this->race, $this->class, $this->level); } return true; } @@ -2541,6 +2551,30 @@ public function GetCharacterArenaTeamInfo($check = false) { } } + /** + * Loads character feed data from DB + * @category Characters class + * @access private + * @return bool + **/ + private function LoadFeedData() { + if($this->feed_data) { + return true; + } + $this->feed_data = $this->db->select("SELECT * FROM `character_feed_log` WHERE `guid` = %d AND `date` > 0 ORDER BY `date` DESC", $this->GetGUID()); + if(!$this->feed_data) { + $this->armory->Log()->writeLog('%s : unable to load feed data for character %s (GUID: %d).', __METHOD__, $this->GetName(), $this->GetGUID()); + return false; + } + $count = count($this->feed_data); + for($i = 0; $i < $count; $i++) { + if($this->feed_data[$i]['type'] == TYPE_ACHIEVEMENT_FEED) { + $this->feed_data[$i]['date'] = $this->GetAchievementMgr()->GetAchievementDate($this->feed_data[$i]['data'], true); + } + } + return true; + } + /** * Returns info about last character activity. Requires MaNGOS/Trinity core patch (tools/character_feed)! * bool $full used only in character-feed.php @@ -2555,14 +2589,15 @@ public function GetCharacterFeed($full = false) { $this->armory->Log()->writeError('%s : player guid not defined', __METHOD__); return false; } - $limit = ($full == true) ? 50 : 10; - $data = $this->db->select("SELECT * FROM `character_feed_log` WHERE `guid`=%d ORDER BY `date` DESC LIMIT %d", $this->guid, $limit); - if(!$data) { - $this->armory->Log()->writeLog('%s : feed data for player %d (%s) not found!', __METHOD__, $this->guid, $this->name); + if(!$this->feed_data) { + // Must be loaded from Character::BuildCharacter() return false; } - $feed_data = array(); + $limit = ($full == true) ? 50 : 10; + $currently_added = 0; $i = 0; + $key = 0; + $feed_data = array(); // Strings $feed_strings = $this->armory->aDB->select("SELECT `id`, `string_%s` AS `string` FROM `ARMORYDBPREFIX_string` WHERE `id` IN (13, 14, 15, 16, 17, 18)", $this->armory->GetLocale()); if(!$feed_strings) { @@ -2573,39 +2608,64 @@ public function GetCharacterFeed($full = false) { foreach($feed_strings as $str) { $_strings[$str['id']] = $str['string']; } - foreach($data as $event) { + foreach($this->feed_data as $event) { + if($currently_added == $limit) { + break; + } $event_date = $event['date']; - if(date('d.m.Y') == date('d.m.Y', $event_date)) { + $event_type = $event['type']; + $event_data = $event['data']; + $date_string = date('d.m.Y', $event_date); + if(date('d.m.Y') == $date_string) { $sort = 'today'; + $diff = time() - $event_date; + if($this->armory->GetLocale() == 'ru_ru') { + $periods = array('сек.', 'мин.', 'ч.'); + $ago_str = 'назад'; + } + else { + $periods = array('seconds', 'minutes', 'hours'); + $ago_str = 'ago'; + } + $lengths = array(60, 60, 24); + for($j = 0; $diff >= $lengths[$j]; $j++) { + $diff /= $lengths[$j]; + } + $diff = round($diff); + $date_string = sprintf('%s %s %s', $diff, $periods[$j], $ago_str); } - elseif(date('d.m.Y', $event_date) == date('d.m.Y', strtotime('yesterday'))) { + elseif(date('d.m.Y', strtotime('yesterday')) == $date_string) { $sort = 'yesterday'; } else { $sort = 'earlier'; } - switch($event['type']) { + switch($event_type) { case TYPE_ACHIEVEMENT_FEED: - $send_data = array('achievement' => $event['data'], 'date' => $event_date); + $send_data = array('achievement' => $event_data, 'date' => $event_date); $achievement_info = $this->GetAchievementMgr()->GetAchievementInfo($send_data); - if(!isset($achievement_info['title']) || !$achievement_info['title'] || empty($achievement_info['title'])) { + if(!$achievement_info || !isset($achievement_info['title']) || !$achievement_info['title'] || empty($achievement_info['title'])) { + // Wrong achievement ID or achievement not found in DB. + continue; + } + if(date('d/m/Y', $event_date) != $this->GetAchievementMgr()->GetAchievementDate($event['data'])) { + // Wrong achievement date, skip. Related to Vasago's issue. continue; } if(!isset($achievement_info['points'])) { - $achievement_info['points'] = 0; + $achievement_info['points'] = 0; // Feat of Strength has no points. } $feed_data[$i]['event'] = array( 'type' => 'achievement', - 'date' => date('d.m.Y', $event_date), + 'date' => $date_string, 'time' => date('H:i:s', $event_date), - 'id' => $event['data'], + 'id' => $event_data, 'points' => $achievement_info['points'], 'sort' => $sort ); $achievement_info['desc'] = str_replace("'", "\'", $achievement_info['desc']); $achievement_info['title'] = str_replace("'", "\'", $achievement_info['title']); $tooltip = sprintf('<div class=\"myTable\"\><img src=\"wow-icons/_images/51x51/%s.jpg\" align=\"left\" class=\"ach_tooltip\" /\><strong style=\"color: #fff;\"\>%s (%d)</strong\><br /\>%s', $achievement_info['icon'], $achievement_info['title'], $achievement_info['points'], $achievement_info['desc']); - //$tooltip = sprintf('
%s (%d)
%s', $achievement_info['icon'], $achievement_info['title'], $achievement_info['points'], $achievement_info['desc']); if($achievement_info['categoryId'] == 81) { // Feats of strenght $feed_data[$i]['title'] = sprintf('%s [%s].', $_strings[14], $achievement_info['title']); @@ -2619,13 +2679,13 @@ public function GetCharacterFeed($full = false) { $feed_data[$i]['tooltip'] = $tooltip; break; case TYPE_ITEM_FEED: - $item = $this->armory->wDB->selectRow("SELECT `displayid`, `InventoryType`, `name`, `Quality` FROM `item_template` WHERE `entry`=%d LIMIT 1", $event['data']); + $item = $this->armory->wDB->selectRow("SELECT `displayid`, `InventoryType`, `name`, `Quality` FROM `item_template` WHERE `entry`=%d LIMIT 1", $event_data); if(!$item) { continue; } $item_icon = $this->armory->aDB->selectCell("SELECT `icon` FROM `ARMORYDBPREFIX_icons` WHERE `displayid`=%d", $item['displayid']); // Is item equipped? - if($this->IsItemEquipped($event['data'])) { + if($this->IsItemEquipped($event_data)) { $item_slot = $item['InventoryType']; } else { @@ -2633,25 +2693,25 @@ public function GetCharacterFeed($full = false) { } $feed_data[$i]['event'] = array( 'type' => 'loot', - 'date' => date('d.m.Y', $event_date), + 'date' => $date_string, 'time' => date('H:i:s', $event_date), 'icon' => $item_icon, - 'id' => $event['data'], + 'id' => $event_data, 'slot' => $item_slot, 'sort' => $sort ); if($this->armory->GetLocale() != 'en_gb' && $this->armory->GetLocale() != 'en_us') { - $item['name'] = Items::GetItemName($event['data']); + $item['name'] = Items::GetItemName($event_data); } $feed_data[$i]['title'] = sprintf('%s [%s].', $_strings[15], $item['name']); - $feed_data[$i]['desc'] = sprintf('%s [%s].', $_strings[15], $event['data'], $event['data'], $item['Quality'], $item['name']); + $feed_data[$i]['desc'] = sprintf('%s [%s].', $_strings[15], $event_data, $event_data, $item['Quality'], $item['name']); break; case TYPE_BOSS_FEED: // Get criterias $achievement_ids = array(); $dungeonDifficulty = $event['difficulty']; // Search for difficulty_entry_X - $DifficultyEntry = $this->armory->wDB->selectCell("SELECT `entry` FROM `creature_template` WHERE `difficulty_entry_%d` = %d", $event['difficulty'], $event['data']); + $DifficultyEntry = $this->armory->wDB->selectCell("SELECT `entry` FROM `creature_template` WHERE `difficulty_entry_%d` = %d", $event['difficulty'], $event_data); if(!$DifficultyEntry || $DifficultyEntry == 0) { $DifficultyEntry = $event['data']; } @@ -2671,17 +2731,21 @@ public function GetCharacterFeed($full = false) { } $feed_data[$i]['event'] = array( 'type' => 'bosskill', - 'date' => date('d.m.Y', $event_date), + 'date' => $date_string, 'time' => date('H:i:s', $event_date), - 'id' => $event['data'], + 'id' => $event_data, 'points' => 0, 'sort' => $sort ); $feed_data[$i]['title'] = sprintf('%s [%s] %d %s', $_strings[16], $achievement['name'], $event['counter'], $_strings[17]); $feed_data[$i]['desc'] = sprintf('%d %s.', $event['counter'], $achievement['name']); break; + default: + continue; + break; } $i++; + $currently_added++; } return $feed_data; } diff --git a/includes/revision_nr.php b/includes/revision_nr.php index ea4377fb5..077728ab0 100644 --- a/includes/revision_nr.php +++ b/includes/revision_nr.php @@ -1,5 +1,5 @@ \ No newline at end of file