public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $chrono_key = $request->getStr('chronoKey');
     if ($request->isDialogFormPost()) {
         $table = new PhabricatorFeedStoryNotification();
         queryfx($table->establishConnection('w'), 'UPDATE %T SET hasViewed = 1 ' . 'WHERE userPHID = %s AND hasViewed = 0 and chronologicalKey <= %s', $table->getTableName(), $viewer->getPHID(), $chrono_key);
         PhabricatorUserCache::clearCache(PhabricatorUserNotificationCountCacheType::KEY_COUNT, $viewer->getPHID());
         return id(new AphrontReloadResponse())->setURI('/notification/');
     }
     $dialog = new AphrontDialogView();
     $dialog->setUser($viewer);
     $dialog->addCancelButton('/notification/');
     if ($chrono_key) {
         $dialog->setTitle(pht('Really mark all notifications as read?'));
         $dialog->addHiddenInput('chronoKey', $chrono_key);
         $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
         if ($is_serious) {
             $dialog->appendChild(pht('All unread notifications will be marked as read. You can not ' . 'undo this action.'));
         } else {
             $dialog->appendChild(pht("You can't ignore your problems forever, you know."));
         }
         $dialog->addSubmitButton(pht('Mark All Read'));
     } else {
         $dialog->setTitle(pht('No notifications to mark as read.'));
         $dialog->appendChild(pht('You have no unread notifications.'));
     }
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 public function markUpToDate(ConpherenceThread $conpherence, ConpherenceTransaction $xaction)
 {
     if (!$this->isUpToDate($conpherence)) {
         $this->setParticipationStatus(ConpherenceParticipationStatus::UP_TO_DATE);
         $this->setBehindTransactionPHID($xaction->getPHID());
         $this->setSeenMessageCount($conpherence->getMessageCount());
         $this->save();
         PhabricatorUserCache::clearCache(PhabricatorUserMessageCountCacheType::KEY_COUNT, $this->getParticipantPHID());
     }
     return $this;
 }
 public static function updateObjectNotificationViews(PhabricatorUser $user, $object_phid)
 {
     if (PhabricatorEnv::isReadOnly()) {
         return;
     }
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $notification_table = new PhabricatorFeedStoryNotification();
     $conn = $notification_table->establishConnection('w');
     queryfx($conn, 'UPDATE %T
    SET hasViewed = 1
    WHERE userPHID = %s
      AND primaryObjectPHID = %s
      AND hasViewed = 0', $notification_table->getTableName(), $user->getPHID(), $object_phid);
     unset($unguarded);
     $count_key = PhabricatorUserNotificationCountCacheType::KEY_COUNT;
     PhabricatorUserCache::clearCache($count_key, $user->getPHID());
     $user->clearCacheData($count_key);
 }
<?php

$table = new PhabricatorUserPreferences();
$conn_w = $table->establishConnection('w');
// Convert "Mail Format", "Re Prefix" and "Vary Subjects" mail settings to
// string constants to avoid weird stuff where we store "true" and "false" as
// strings in the database.
// Each of these keys will be converted to the first value if present and
// truthy, or the second value if present and falsey.
$remap = array('html-emails' => array('html', 'text'), 're-prefix' => array('re', 'none'), 'vary-subject' => array('vary', 'static'));
foreach (new LiskMigrationIterator($table) as $row) {
    $dict = $row->getPreferences();
    $should_update = false;
    foreach ($remap as $key => $value) {
        if (isset($dict[$key])) {
            if ($dict[$key]) {
                $dict[$key] = $value[0];
            } else {
                $dict[$key] = $value[1];
            }
            $should_update = true;
        }
    }
    if (!$should_update) {
        continue;
    }
    queryfx($conn_w, 'UPDATE %T SET preferences = %s WHERE id = %d', $table->getTableName(), phutil_json_encode($dict), $row->getID());
}
$prefs_key = PhabricatorUserPreferencesCacheType::KEY_PREFERENCES;
PhabricatorUserCache::clearCacheForAllUsers($prefs_key);
示例#5
0
 /**
  * @task cache
  */
 protected function requireCacheData($key)
 {
     if (isset($this->usableCacheData[$key])) {
         return $this->usableCacheData[$key];
     }
     $type = PhabricatorUserCacheType::requireCacheTypeForKey($key);
     if (isset($this->rawCacheData[$key])) {
         $raw_value = $this->rawCacheData[$key];
         $usable_value = $type->getValueFromStorage($raw_value);
         $this->usableCacheData[$key] = $usable_value;
         return $usable_value;
     }
     // By default, we throw if a cache isn't available. This is consistent
     // with the standard `needX()` + `attachX()` + `getX()` interaction.
     if (!$this->allowInlineCacheGeneration) {
         throw new PhabricatorDataNotAttachedException($this);
     }
     $usable_value = $type->getDefaultValue();
     $user_phid = $this->getPHID();
     if ($user_phid) {
         $map = $type->newValueForUsers($key, array($this));
         if (array_key_exists($user_phid, $map)) {
             $raw_value = $map[$user_phid];
             $usable_value = $type->getValueFromStorage($raw_value);
             $this->rawCacheData[$key] = $raw_value;
             PhabricatorUserCache::writeCache($type, $key, $user_phid, $raw_value);
         }
     }
     $this->usableCacheData[$key] = $usable_value;
     return $usable_value;
 }
 private function fillUserCaches(array $users)
 {
     if (!$this->cacheKeys) {
         return;
     }
     $user_map = mpull($users, null, 'getPHID');
     $keys = array_keys($this->cacheKeys);
     $hashes = array();
     foreach ($keys as $key) {
         $hashes[] = PhabricatorHash::digestForIndex($key);
     }
     $types = PhabricatorUserCacheType::getAllCacheTypes();
     // First, pull any available caches. If we wanted to be particularly clever
     // we could do this with JOINs in the main query.
     $cache_table = new PhabricatorUserCache();
     $cache_conn = $cache_table->establishConnection('r');
     $cache_data = queryfx_all($cache_conn, 'SELECT cacheKey, userPHID, cacheData, cacheType FROM %T
     WHERE cacheIndex IN (%Ls) AND userPHID IN (%Ls)', $cache_table->getTableName(), $hashes, 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();
     $cache_data = igroup($cache_data, 'userPHID');
     foreach ($user_map as $user_phid => $user) {
         $raw_rows = idx($cache_data, $user_phid, array());
         $raw_data = ipull($raw_rows, 'cacheData', 'cacheKey');
         foreach ($keys as $key) {
             if (isset($raw_data[$key]) || array_key_exists($key, $raw_data)) {
                 continue;
             }
             $need[$key][$user_phid] = $user;
         }
         $user->attachRawCacheData($raw_data);
     }
     // If we missed any cache values, bulk-construct them now. This is
     // usually much cheaper than generating them on-demand for each user
     // record.
     if (!$need) {
         return;
     }
     $writes = array();
     foreach ($need as $cache_key => $need_users) {
         $type = PhabricatorUserCacheType::getCacheTypeForKey($cache_key);
         if (!$type) {
             continue;
         }
         $data = $type->newValueForUsers($cache_key, $need_users);
         foreach ($data as $user_phid => $raw_value) {
             $data[$user_phid] = $raw_value;
             $writes[] = array('userPHID' => $user_phid, 'key' => $cache_key, 'type' => $type, 'value' => $raw_value);
         }
         foreach ($need_users as $user_phid => $user) {
             if (isset($data[$user_phid]) || array_key_exists($user_phid, $data)) {
                 $user->attachRawCacheData(array($cache_key => $data[$user_phid]));
             }
         }
     }
     PhabricatorUserCache::writeCaches($writes);
 }
 protected function applyFinalEffects(PhabricatorLiskDAO $object, array $xactions)
 {
     $message_count = 0;
     foreach ($xactions as $xaction) {
         switch ($xaction->getTransactionType()) {
             case PhabricatorTransactions::TYPE_COMMENT:
                 $message_count++;
                 break;
         }
     }
     // update everyone's participation status on the last xaction -only-
     $xaction = end($xactions);
     $xaction_phid = $xaction->getPHID();
     $behind = ConpherenceParticipationStatus::BEHIND;
     $up_to_date = ConpherenceParticipationStatus::UP_TO_DATE;
     $participants = $object->getParticipants();
     $user = $this->getActor();
     $time = time();
     foreach ($participants as $phid => $participant) {
         if ($phid != $user->getPHID()) {
             if ($participant->getParticipationStatus() != $behind) {
                 $participant->setBehindTransactionPHID($xaction_phid);
                 $participant->setSeenMessageCount($object->getMessageCount() - $message_count);
             }
             $participant->setParticipationStatus($behind);
             $participant->setDateTouched($time);
         } else {
             $participant->setSeenMessageCount($object->getMessageCount());
             $participant->setBehindTransactionPHID($xaction_phid);
             $participant->setParticipationStatus($up_to_date);
             $participant->setDateTouched($time);
         }
         $participant->save();
     }
     PhabricatorUserCache::clearCaches(PhabricatorUserMessageCountCacheType::KEY_COUNT, array_keys($participants));
     if ($xactions) {
         $data = array('type' => 'message', 'threadPHID' => $object->getPHID(), 'messageID' => last($xactions)->getID(), 'subscribers' => array($object->getPHID()));
         PhabricatorNotificationClient::tryToPostMessage($data);
     }
     return $xactions;
 }
 private function insertNotifications($chrono_key, array $subscribed_phids)
 {
     if (!$this->primaryObjectPHID) {
         throw new Exception(pht('You must call %s if you %s!', 'setPrimaryObjectPHID()', 'setSubscribedPHIDs()'));
     }
     $notif = new PhabricatorFeedStoryNotification();
     $sql = array();
     $conn = $notif->establishConnection('w');
     $will_receive_mail = array_fill_keys($this->mailRecipientPHIDs, true);
     $user_phids = array_unique($subscribed_phids);
     foreach ($user_phids as $user_phid) {
         if (isset($will_receive_mail[$user_phid])) {
             $mark_read = 1;
         } else {
             $mark_read = 0;
         }
         $sql[] = qsprintf($conn, '(%s, %s, %s, %d)', $this->primaryObjectPHID, $user_phid, $chrono_key, $mark_read);
     }
     if ($sql) {
         queryfx($conn, 'INSERT INTO %T ' . '(primaryObjectPHID, userPHID, chronologicalKey, hasViewed) ' . 'VALUES %Q', $notif->getTableName(), implode(', ', $sql));
     }
     PhabricatorUserCache::clearCaches(PhabricatorUserNotificationCountCacheType::KEY_COUNT, $user_phids);
 }
 protected function applyFinalEffects(PhabricatorLiskDAO $object, array $xactions)
 {
     $user_phid = $object->getUserPHID();
     if ($user_phid) {
         PhabricatorUserCache::clearCache(PhabricatorUserPreferencesCacheType::KEY_PREFERENCES, $user_phid);
     } else {
         PhabricatorUserCache::clearCacheForAllUsers(PhabricatorUserPreferencesCacheType::KEY_PREFERENCES);
     }
     return $xactions;
 }
 private function purgeUserCache()
 {
     $table = new PhabricatorUserCache();
     $conn_w = $table->establishConnection('w');
     queryfx($conn_w, 'TRUNCATE TABLE %T', $table->getTableName());
 }