protected function getValueFromRequest(AphrontRequest $request, $key)
 {
     $list = $this->getListFromRequest($request, $key);
     $phids = array();
     $slugs = array();
     $project_type = PhabricatorProjectProjectPHIDType::TYPECONST;
     foreach ($list as $item) {
         $type = phid_get_type($item);
         if ($type == $project_type) {
             $phids[] = $item;
         } else {
             if (PhabricatorTypeaheadDatasource::isFunctionToken($item)) {
                 // If this is a function, pass it through unchanged; we'll evaluate
                 // it later.
                 $phids[] = $item;
             } else {
                 $slugs[] = $item;
             }
         }
     }
     if ($slugs) {
         $projects = id(new PhabricatorProjectQuery())->setViewer($this->requireViewer())->withSlugs($slugs)->execute();
         foreach ($projects as $project) {
             $phids[] = $project->getPHID();
         }
         $phids = array_unique($phids);
     }
     return $phids;
 }
 protected function getUsersFromRequest(AphrontRequest $request, $key, array $allow_types = array())
 {
     $list = $this->getListFromRequest($request, $key);
     $phids = array();
     $names = array();
     $allow_types = array_fuse($allow_types);
     $user_type = PhabricatorPeopleUserPHIDType::TYPECONST;
     foreach ($list as $item) {
         $type = phid_get_type($item);
         if ($type == $user_type) {
             $phids[] = $item;
         } else {
             if (isset($allow_types[$type])) {
                 $phids[] = $item;
             } else {
                 if (PhabricatorTypeaheadDatasource::isFunctionToken($item)) {
                     // If this is a function, pass it through unchanged; we'll evaluate
                     // it later.
                     $phids[] = $item;
                 } else {
                     $names[] = $item;
                 }
             }
         }
     }
     if ($names) {
         $users = id(new PhabricatorPeopleQuery())->setViewer($this->getViewer())->withUsernames($names)->execute();
         foreach ($users as $user) {
             $phids[] = $user->getPHID();
         }
         $phids = array_unique($phids);
     }
     return $phids;
 }
 protected function canEvaluateFunction($function)
 {
     if (!$this->getViewer()->getPHID()) {
         return false;
     }
     return parent::canEvaluateFunction($function);
 }
 protected function buildQueryFromParameters(array $map)
 {
     $query = $this->newQuery();
     if (strlen($map['name'])) {
         $tokens = PhabricatorTypeaheadDatasource::tokenizeString($map['name']);
         $query->withNameTokens($tokens);
     }
     if ($map['memberPHIDs']) {
         $query->withMemberPHIDs($map['memberPHIDs']);
     }
     if ($map['watcherPHIDs']) {
         $query->withWatcherPHIDs($map['watcherPHIDs']);
     }
     if ($map['status']) {
         $status = idx($this->getStatusValues(), $map['status']);
         if ($status) {
             $query->withStatus($status);
         }
     }
     if ($map['icons']) {
         $query->withIcons($map['icons']);
     }
     if ($map['colors']) {
         $query->withColors($map['colors']);
     }
     return $query;
 }
 public function updateDatasourceTokens()
 {
     $table = self::TABLE_DATASOURCE_TOKEN;
     $conn_w = $this->establishConnection('w');
     $id = $this->getID();
     $slugs = queryfx_all($conn_w, 'SELECT * FROM %T WHERE projectPHID = %s', id(new PhabricatorProjectSlug())->getTableName(), $this->getPHID());
     $all_strings = ipull($slugs, 'slug');
     $all_strings[] = $this->getName();
     $all_strings = implode(' ', $all_strings);
     $tokens = PhabricatorTypeaheadDatasource::tokenizeString($all_strings);
     $sql = array();
     foreach ($tokens as $token) {
         $sql[] = qsprintf($conn_w, '(%d, %s)', $id, $token);
     }
     $this->openTransaction();
     queryfx($conn_w, 'DELETE FROM %T WHERE projectID = %d', $table, $id);
     foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
         queryfx($conn_w, 'INSERT INTO %T (projectID, token) VALUES %Q', $table, $chunk);
     }
     $this->saveTransaction();
 }
 /**
  * Populate the nametoken table, which used to fetch typeahead results. When
  * a user types "linc", we want to match "Abraham Lincoln" from on-demand
  * typeahead sources. To do this, we need a separate table of name fragments.
  */
 public function updateNameTokens()
 {
     $table = self::NAMETOKEN_TABLE;
     $conn_w = $this->establishConnection('w');
     $tokens = PhabricatorTypeaheadDatasource::tokenizeString($this->getUserName() . ' ' . $this->getRealName() . ' ' . GetPinyin($this->getRealName()));
     $sql = array();
     foreach ($tokens as $token) {
         $sql[] = qsprintf($conn_w, '(%d, %s)', $this->getID(), $token);
     }
     queryfx($conn_w, 'DELETE FROM %T WHERE userID = %d', $table, $this->getID());
     if ($sql) {
         queryfx($conn_w, 'INSERT INTO %T (userID, token) VALUES %Q', $table, implode(', ', $sql));
     }
 }
 private function loadHandles()
 {
     if ($this->handles === null) {
         $viewer = $this->getUser();
         if (!$viewer) {
             throw new Exception(pht('Call %s before rendering tokenizers. ' . 'Use %s on %s to do this easily.', 'setUser()', 'appendControl()', 'AphrontFormView'));
         }
         $values = nonempty($this->getValue(), array());
         $phids = array();
         foreach ($values as $value) {
             if (!PhabricatorTypeaheadDatasource::isFunctionToken($value)) {
                 $phids[] = $value;
             }
         }
         $this->handles = $viewer->loadHandles($phids);
     }
     return $this->handles;
 }
 protected function getDatasourceTemplate(PhabricatorTypeaheadDatasource $datasource)
 {
     return array('markup' => new AphrontTokenizerTemplateView(), 'uri' => $datasource->getDatasourceURI(), 'placeholder' => $datasource->getPlaceholderText(), 'browseURI' => $datasource->getBrowseURI());
 }
 public function renderFunctionTokens($function, array $argv_list)
 {
     foreach ($this->getUsableDatasources() as $source) {
         if ($source->canEvaluateFunction($function)) {
             return $source->renderFunctionTokens($function, $argv_list);
         }
     }
     return parent::renderFunctionTokens($function, $argv_list);
 }
 private function buildJoinClause($conn_r)
 {
     $joins = array();
     if (!$this->needMembers !== null) {
         $joins[] = qsprintf($conn_r, 'LEFT JOIN %T vm ON vm.src = p.phid AND vm.type = %d AND vm.dst = %s', PhabricatorEdgeConfig::TABLE_NAME_EDGE, PhabricatorEdgeConfig::TYPE_PROJ_MEMBER, $this->getViewer()->getPHID());
     }
     if ($this->memberPHIDs !== null) {
         $joins[] = qsprintf($conn_r, 'JOIN %T e ON e.src = p.phid AND e.type = %d', PhabricatorEdgeConfig::TABLE_NAME_EDGE, PhabricatorEdgeConfig::TYPE_PROJ_MEMBER);
     }
     if ($this->slugs !== null) {
         $joins[] = qsprintf($conn_r, 'JOIN %T slug on slug.projectPHID = p.phid', id(new PhabricatorProjectSlug())->getTableName());
     }
     if ($this->datasourceQuery !== null) {
         $tokens = PhabricatorTypeaheadDatasource::tokenizeString($this->datasourceQuery);
         if (!$tokens) {
             throw new PhabricatorEmptyQueryException();
         }
         $likes = array();
         foreach ($tokens as $token) {
             $likes[] = qsprintf($conn_r, 'token.token LIKE %>', $token);
         }
         $joins[] = qsprintf($conn_r, 'JOIN %T token ON token.projectID = p.id AND (%Q)', PhabricatorProject::TABLE_DATASOURCE_TOKEN, '(' . implode(') OR (', $likes) . ')');
     }
     $joins[] = $this->buildApplicationSearchJoinClause($conn_r);
     return implode(' ', $joins);
 }
 private function assertTokenization($input, $expect)
 {
     $this->assertEqual($expect, PhabricatorTypeaheadDatasource::tokenizeString($input), pht('Tokenization of "%s"', $input));
 }