1<?php 2// search/st_author.php -- HotCRP helper class for searching for papers 3// Copyright (c) 2006-2018 Eddie Kohler; see LICENSE. 4 5class Author_SearchTerm extends SearchTerm { 6 private $csm; 7 private $regex; 8 9 function __construct($countexpr, $contacts, $match, $quoted) { 10 parent::__construct("au"); 11 $this->csm = new ContactCountMatcher($countexpr, $contacts); 12 if (!$contacts && $match) 13 $this->regex = Text::star_text_pregexes($match, $quoted); 14 } 15 static function parse($word, SearchWord $sword, PaperSearch $srch) { 16 $count = ">0"; 17 if (preg_match('/\A(.*?)(?::|\A|(?=[^\d]))((?:[=!<>]=?|≠|≤|≥|)\d+)\z/s', $word, $m)) { 18 $word = $m[1]; 19 $count = $m[2]; 20 } 21 $cids = null; 22 if ($sword->kwexplicit && !$sword->quoted) { 23 if ($word === "any") 24 $word = null; 25 else if ($word === "none" && $count === ">0") { 26 $word = null; 27 $count = "=0"; 28 } else if (trim($word) !== "") 29 $cids = $srch->matching_special_contacts($word, false, false); 30 } 31 return new Author_SearchTerm($count, $cids, $word, $sword->quoted); 32 } 33 function trivial_rights(Contact $user, PaperSearch $srch) { 34 return $this->csm->has_sole_contact($user->contactId) 35 && !$this->csm->test(0); 36 } 37 function sqlexpr(SearchQueryInfo $sqi) { 38 if ($this->csm->has_contacts() && !$this->csm->test(0)) { 39 return "exists (select * from PaperConflict where PaperConflict.paperId=Paper.paperId and " . $this->csm->contact_match_sql("contactId") . " and conflictType>=" . CONFLICT_AUTHOR . ")"; 40 } else if ($this->csm->has_contacts()) { 41 $sqi->add_allConflictType_column(); 42 return "true"; 43 } else { 44 $sqi->add_column("authorInformation", "Paper.authorInformation"); 45 return $this->csm->test(0) ? "true" : "Paper.authorInformation!=''"; 46 } 47 } 48 function exec(PaperInfo $row, PaperSearch $srch) { 49 $n = 0; 50 $can_view = $srch->user->allow_view_authors($row); 51 if ($this->csm->has_contacts()) { 52 foreach ($this->csm->contact_set() as $cid) { 53 if (($cid === $srch->cid || $can_view) 54 && $row->has_author($cid)) 55 ++$n; 56 } 57 } else if ($can_view) { 58 foreach ($row->author_list() as $au) { 59 if ($this->regex) { 60 $text = $au->name_email_aff_text(); 61 if (!Text::match_pregexes($this->regex, $text, 62 UnicodeHelper::deaccent($text))) 63 continue; 64 } 65 ++$n; 66 } 67 } 68 return $this->csm->test($n); 69 } 70 function extract_metadata($top, PaperSearch $srch) { 71 parent::extract_metadata($top, $srch); 72 if ($this->regex) 73 $srch->regex["au"][] = $this->regex; 74 } 75} 76 77class AuthorMatch_SearchTerm extends SearchTerm { 78 private $field; 79 private $matcher; 80 81 function __construct($type, $matcher) { 82 parent::__construct($type); 83 $this->field = TextMatch_SearchTerm::$map[substr($type, 0, 2)]; 84 $this->matcher = $matcher; 85 } 86 static function parse($word, SearchWord $sword) { 87 $type = $sword->kwdef->name; 88 if ($word === "any" && $sword->kwexplicit && !$sword->quoted) 89 return new TextMatch_SearchTerm(substr($type, 0, 2), true, false); 90 if (($matcher = AuthorMatcher::make_string_guess($word))) 91 return new AuthorMatch_SearchTerm($type, $matcher); 92 else 93 return new False_SearchTerm; 94 } 95 96 function sqlexpr(SearchQueryInfo $sqi) { 97 $sqi->add_column($this->field, "Paper.{$this->field}"); 98 return "Paper.{$this->field}!=''"; 99 } 100 function exec(PaperInfo $row, PaperSearch $srch) { 101 $field = $this->field; 102 if ($row->$field === "" 103 || !$srch->user->allow_view_authors($row)) 104 return false; 105 if (!$row->field_match_pregexes($this->matcher->general_pregexes(), $field)) 106 return false; 107 $l = $this->type === "aumatch" ? $row->author_list() : $row->collaborator_list(); 108 foreach ($l as $au) 109 if ($this->matcher->test($au, true)) 110 return true; 111 return false; 112 } 113 function extract_metadata($top, PaperSearch $srch) { 114 parent::extract_metadata($top, $srch); 115 $srch->regex[substr($this->type, 0, 2)][] = $this->matcher->general_pregexes(); 116 } 117} 118