Changeset View
Changeset View
Standalone View
Standalone View
src/applications/people/query/PhabricatorPeopleQuery.php
| Show First 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | final class PhabricatorPeopleQuery | ||||
| } | } | ||||
| public function needProfile($need) { | public function needProfile($need) { | ||||
| $this->needProfile = $need; | $this->needProfile = $need; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function needProfileImage($need) { | public function needProfileImage($need) { | ||||
| $this->needProfileImage = $need; | $cache_key = PhabricatorUserProfileImageCacheType::KEY_URI; | ||||
| if ($need) { | |||||
| $this->cacheKeys[$cache_key] = true; | |||||
| } else { | |||||
| unset($this->cacheKeys[$cache_key]); | |||||
| } | |||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function needAvailability($need) { | public function needAvailability($need) { | ||||
| $this->needAvailability = $need; | $this->needAvailability = $need; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | if ($this->needBadges) { | ||||
| foreach ($users as $user) { | foreach ($users as $user) { | ||||
| $user_awards = idx($awards, $user->getPHID(), array()); | $user_awards = idx($awards, $user->getPHID(), array()); | ||||
| $badge_phids = mpull($user_awards, 'getBadgePHID'); | $badge_phids = mpull($user_awards, 'getBadgePHID'); | ||||
| $user->attachBadgePHIDs($badge_phids); | $user->attachBadgePHIDs($badge_phids); | ||||
| } | } | ||||
| } | } | ||||
| if ($this->needProfileImage) { | |||||
| $rebuild = array(); | |||||
| foreach ($users as $user) { | |||||
| $image_uri = $user->getProfileImageCache(); | |||||
| if ($image_uri) { | |||||
| // This user has a valid cache, so we don't need to fetch any | |||||
| // data or rebuild anything. | |||||
| $user->attachProfileImageURI($image_uri); | |||||
| continue; | |||||
| } | |||||
| // This user's cache is invalid or missing, so we're going to rebuild | |||||
| // it. | |||||
| $rebuild[] = $user; | |||||
| } | |||||
| if ($rebuild) { | |||||
| $file_phids = mpull($rebuild, 'getProfileImagePHID'); | |||||
| $file_phids = array_filter($file_phids); | |||||
| if ($file_phids) { | |||||
| // NOTE: We're using the omnipotent user here because older profile | |||||
| // images do not have the 'profile' flag, so they may not be visible | |||||
| // to the executing viewer. At some point, we could migrate to add | |||||
| // this flag and then use the real viewer, or just use the real | |||||
| // viewer after enough time has passed to limit the impact of old | |||||
| // data. The consequence of missing here is that we cache a default | |||||
| // image when a real image exists. | |||||
| $files = id(new PhabricatorFileQuery()) | |||||
| ->setParentQuery($this) | |||||
| ->setViewer(PhabricatorUser::getOmnipotentUser()) | |||||
| ->withPHIDs($file_phids) | |||||
| ->execute(); | |||||
| $files = mpull($files, null, 'getPHID'); | |||||
| } else { | |||||
| $files = array(); | |||||
| } | |||||
| foreach ($rebuild as $user) { | |||||
| $image_phid = $user->getProfileImagePHID(); | |||||
| if (isset($files[$image_phid])) { | |||||
| $image_uri = $files[$image_phid]->getBestURI(); | |||||
| } else { | |||||
| $image_uri = PhabricatorUser::getDefaultProfileImageURI(); | |||||
| } | |||||
| $user->writeProfileImageCache($image_uri); | |||||
| $user->attachProfileImageURI($image_uri); | |||||
| } | |||||
| } | |||||
| } | |||||
| if ($this->needAvailability) { | if ($this->needAvailability) { | ||||
| $rebuild = array(); | $rebuild = array(); | ||||
| foreach ($users as $user) { | foreach ($users as $user) { | ||||
| $cache = $user->getAvailabilityCache(); | $cache = $user->getAvailabilityCache(); | ||||
| if ($cache !== null) { | if ($cache !== null) { | ||||
| $user->attachAvailability($cache); | $user->attachAvailability($cache); | ||||
| } else { | } else { | ||||
| $rebuild[] = $user; | $rebuild[] = $user; | ||||
| ▲ Show 20 Lines • Show All 258 Lines • ▼ Show 20 Lines | private function fillUserCaches(array $users) { | ||||
| $user_map = mpull($users, null, 'getPHID'); | $user_map = mpull($users, null, 'getPHID'); | ||||
| $keys = array_keys($this->cacheKeys); | $keys = array_keys($this->cacheKeys); | ||||
| $hashes = array(); | $hashes = array(); | ||||
| foreach ($keys as $key) { | foreach ($keys as $key) { | ||||
| $hashes[] = PhabricatorHash::digestForIndex($key); | $hashes[] = PhabricatorHash::digestForIndex($key); | ||||
| } | } | ||||
| $types = PhabricatorUserCacheType::getAllCacheTypes(); | |||||
| // First, pull any available caches. If we wanted to be particularly clever | // First, pull any available caches. If we wanted to be particularly clever | ||||
| // we could do this with JOINs in the main query. | // we could do this with JOINs in the main query. | ||||
| $cache_table = new PhabricatorUserCache(); | $cache_table = new PhabricatorUserCache(); | ||||
| $cache_conn = $cache_table->establishConnection('r'); | $cache_conn = $cache_table->establishConnection('r'); | ||||
| $cache_data = queryfx_all( | $cache_data = queryfx_all( | ||||
| $cache_conn, | $cache_conn, | ||||
| 'SELECT cacheKey, userPHID, cacheData FROM %T | 'SELECT cacheKey, userPHID, cacheData, cacheType FROM %T | ||||
| WHERE cacheIndex IN (%Ls) AND userPHID IN (%Ls)', | WHERE cacheIndex IN (%Ls) AND userPHID IN (%Ls)', | ||||
| $cache_table->getTableName(), | $cache_table->getTableName(), | ||||
| $hashes, | $hashes, | ||||
| array_keys($user_map)); | array_keys($user_map)); | ||||
| $skip_validation = array(); | |||||
| // After we read caches from the database, discard any which have data that | |||||
| // invalid or out of date. This allows cache types to implement TTLs or | |||||
| // versions instead of or in addition to explicit cache clears. | |||||
| foreach ($cache_data as $row_key => $row) { | |||||
| $cache_type = $row['cacheType']; | |||||
| if (isset($skip_validation[$cache_type])) { | |||||
| continue; | |||||
| } | |||||
| if (empty($types[$cache_type])) { | |||||
| unset($cache_data[$row_key]); | |||||
| continue; | |||||
| } | |||||
| $type = $types[$cache_type]; | |||||
| if (!$type->shouldValidateRawCacheData()) { | |||||
| $skip_validation[$cache_type] = true; | |||||
| continue; | |||||
| } | |||||
| $user = $user_map[$row['userPHID']]; | |||||
| $raw_data = $row['cacheData']; | |||||
| if (!$type->isRawCacheDataValid($user, $row['cacheKey'], $raw_data)) { | |||||
| unset($cache_data[$row_key]); | |||||
| continue; | |||||
| } | |||||
| } | |||||
| $need = array(); | $need = array(); | ||||
| $cache_data = igroup($cache_data, 'userPHID'); | $cache_data = igroup($cache_data, 'userPHID'); | ||||
| foreach ($user_map as $user_phid => $user) { | foreach ($user_map as $user_phid => $user) { | ||||
| $raw_rows = idx($cache_data, $user_phid, array()); | $raw_rows = idx($cache_data, $user_phid, array()); | ||||
| $raw_data = ipull($raw_rows, 'cacheData', 'cacheKey'); | $raw_data = ipull($raw_rows, 'cacheData', 'cacheKey'); | ||||
| foreach ($keys as $key) { | foreach ($keys as $key) { | ||||
| ▲ Show 20 Lines • Show All 50 Lines • Show Last 20 Lines | |||||