Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F932085
ConpherenceThreadQuery.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
ConpherenceThreadQuery.php
View Options
<?php
final
class
ConpherenceThreadQuery
extends
PhabricatorCursorPagedPolicyAwareQuery
{
const
TRANSACTION_LIMIT
=
100
;
private
$phids
;
private
$ids
;
private
$participantPHIDs
;
private
$needParticipants
;
private
$needTransactions
;
private
$afterTransactionID
;
private
$beforeTransactionID
;
private
$transactionLimit
;
private
$fulltext
;
private
$needProfileImage
;
public
function
needParticipants
(
$need
)
{
$this
->
needParticipants
=
$need
;
return
$this
;
}
public
function
needProfileImage
(
$need
)
{
$this
->
needProfileImage
=
$need
;
return
$this
;
}
public
function
needTransactions
(
$need_transactions
)
{
$this
->
needTransactions
=
$need_transactions
;
return
$this
;
}
public
function
withIDs
(
array
$ids
)
{
$this
->
ids
=
$ids
;
return
$this
;
}
public
function
withPHIDs
(
array
$phids
)
{
$this
->
phids
=
$phids
;
return
$this
;
}
public
function
withParticipantPHIDs
(
array
$phids
)
{
$this
->
participantPHIDs
=
$phids
;
return
$this
;
}
public
function
setAfterTransactionID
(
$id
)
{
$this
->
afterTransactionID
=
$id
;
return
$this
;
}
public
function
setBeforeTransactionID
(
$id
)
{
$this
->
beforeTransactionID
=
$id
;
return
$this
;
}
public
function
setTransactionLimit
(
$transaction_limit
)
{
$this
->
transactionLimit
=
$transaction_limit
;
return
$this
;
}
public
function
getTransactionLimit
()
{
return
$this
->
transactionLimit
;
}
public
function
withFulltext
(
$query
)
{
$this
->
fulltext
=
$query
;
return
$this
;
}
public
function
withTitleNgrams
(
$ngrams
)
{
return
$this
->
withNgramsConstraint
(
id
(
new
ConpherenceThreadTitleNgrams
()),
$ngrams
);
}
protected
function
loadPage
()
{
$table
=
new
ConpherenceThread
();
$conn_r
=
$table
->
establishConnection
(
'r'
);
$data
=
queryfx_all
(
$conn_r
,
'SELECT thread.* FROM %T thread %Q %Q %Q %Q %Q'
,
$table
->
getTableName
(),
$this
->
buildJoinClause
(
$conn_r
),
$this
->
buildWhereClause
(
$conn_r
),
$this
->
buildGroupClause
(
$conn_r
),
$this
->
buildOrderClause
(
$conn_r
),
$this
->
buildLimitClause
(
$conn_r
));
$conpherences
=
$table
->
loadAllFromArray
(
$data
);
if
(
$conpherences
)
{
$conpherences
=
mpull
(
$conpherences
,
null
,
'getPHID'
);
$this
->
loadParticipantsAndInitHandles
(
$conpherences
);
if
(
$this
->
needParticipants
)
{
$this
->
loadCoreHandles
(
$conpherences
,
'getParticipantPHIDs'
);
}
if
(
$this
->
needTransactions
)
{
$this
->
loadTransactionsAndHandles
(
$conpherences
);
}
if
(
$this
->
needProfileImage
)
{
$default
=
null
;
$file_phids
=
mpull
(
$conpherences
,
'getProfileImagePHID'
);
$file_phids
=
array_filter
(
$file_phids
);
if
(
$file_phids
)
{
$files
=
id
(
new
PhabricatorFileQuery
())
->
setParentQuery
(
$this
)
->
setViewer
(
$this
->
getViewer
())
->
withPHIDs
(
$file_phids
)
->
execute
();
$files
=
mpull
(
$files
,
null
,
'getPHID'
);
}
else
{
$files
=
array
();
}
foreach
(
$conpherences
as
$conpherence
)
{
$file
=
idx
(
$files
,
$conpherence
->
getProfileImagePHID
());
if
(!
$file
)
{
if
(!
$default
)
{
$default
=
PhabricatorFile
::
loadBuiltin
(
$this
->
getViewer
(),
'conpherence.png'
);
}
$file
=
$default
;
}
$conpherence
->
attachProfileImageFile
(
$file
);
}
}
}
return
$conpherences
;
}
protected
function
buildGroupClause
(
AphrontDatabaseConnection
$conn_r
)
{
if
(
$this
->
participantPHIDs
!==
null
||
phutil_nonempty_string
(
$this
->
fulltext
))
{
return
qsprintf
(
$conn_r
,
'GROUP BY thread.id'
);
}
else
{
return
$this
->
buildApplicationSearchGroupClause
(
$conn_r
);
}
}
protected
function
buildJoinClauseParts
(
AphrontDatabaseConnection
$conn
)
{
$joins
=
parent
::
buildJoinClauseParts
(
$conn
);
if
(
$this
->
participantPHIDs
!==
null
)
{
$joins
[]
=
qsprintf
(
$conn
,
'JOIN %T p ON p.conpherencePHID = thread.phid'
,
id
(
new
ConpherenceParticipant
())->
getTableName
());
}
if
(
phutil_nonempty_string
(
$this
->
fulltext
))
{
$joins
[]
=
qsprintf
(
$conn
,
'JOIN %T idx ON idx.threadPHID = thread.phid'
,
id
(
new
ConpherenceIndex
())->
getTableName
());
}
// See note in buildWhereClauseParts() about this optimization.
$viewer
=
$this
->
getViewer
();
if
(!
$viewer
->
isOmnipotent
()
&&
$viewer
->
isLoggedIn
())
{
$joins
[]
=
qsprintf
(
$conn
,
'LEFT JOIN %T vp ON vp.conpherencePHID = thread.phid
AND vp.participantPHID = %s'
,
id
(
new
ConpherenceParticipant
())->
getTableName
(),
$viewer
->
getPHID
());
}
return
$joins
;
}
protected
function
buildWhereClauseParts
(
AphrontDatabaseConnection
$conn
)
{
$where
=
parent
::
buildWhereClauseParts
(
$conn
);
// Optimize policy filtering of private rooms. If we are not looking for
// particular rooms by ID or PHID, we can just skip over any rooms with
// "View Policy: Room Participants" if the viewer isn't a participant: we
// know they won't be able to see the room.
// This avoids overheating browse/search queries, since it's common for
// a large number of rooms to be private and have this view policy.
$viewer
=
$this
->
getViewer
();
$can_optimize
=
!
$viewer
->
isOmnipotent
()
&&
(
$this
->
ids
===
null
)
&&
(
$this
->
phids
===
null
);
if
(
$can_optimize
)
{
$members_policy
=
id
(
new
ConpherenceThreadMembersPolicyRule
())
->
getObjectPolicyFullKey
();
$policies
=
array
(
$members_policy
,
PhabricatorPolicies
::
POLICY_USER
,
PhabricatorPolicies
::
POLICY_ADMIN
,
PhabricatorPolicies
::
POLICY_NOONE
,
);
if
(
$viewer
->
isLoggedIn
())
{
$where
[]
=
qsprintf
(
$conn
,
'thread.viewPolicy NOT IN (%Ls) OR vp.participantPHID = %s'
,
$policies
,
$viewer
->
getPHID
());
}
else
{
$where
[]
=
qsprintf
(
$conn
,
'thread.viewPolicy NOT IN (%Ls)'
,
$policies
);
}
}
if
(
$this
->
ids
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'thread.id IN (%Ld)'
,
$this
->
ids
);
}
if
(
$this
->
phids
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'thread.phid IN (%Ls)'
,
$this
->
phids
);
}
if
(
$this
->
participantPHIDs
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'p.participantPHID IN (%Ls)'
,
$this
->
participantPHIDs
);
}
if
(
phutil_nonempty_string
(
$this
->
fulltext
))
{
$where
[]
=
qsprintf
(
$conn
,
'MATCH(idx.corpus) AGAINST (%s IN BOOLEAN MODE)'
,
$this
->
fulltext
);
}
return
$where
;
}
private
function
loadParticipantsAndInitHandles
(
array
$conpherences
)
{
$participants
=
id
(
new
ConpherenceParticipant
())
->
loadAllWhere
(
'conpherencePHID IN (%Ls)'
,
array_keys
(
$conpherences
));
$map
=
mgroup
(
$participants
,
'getConpherencePHID'
);
foreach
(
$conpherences
as
$current_conpherence
)
{
$conpherence_phid
=
$current_conpherence
->
getPHID
();
$conpherence_participants
=
idx
(
$map
,
$conpherence_phid
,
array
());
$conpherence_participants
=
mpull
(
$conpherence_participants
,
null
,
'getParticipantPHID'
);
$current_conpherence
->
attachParticipants
(
$conpherence_participants
);
$current_conpherence
->
attachHandles
(
array
());
}
return
$this
;
}
private
function
loadCoreHandles
(
array
$conpherences
,
$method
)
{
$handle_phids
=
array
();
foreach
(
$conpherences
as
$conpherence
)
{
$handle_phids
[
$conpherence
->
getPHID
()]
=
$conpherence
->
$method
();
}
$flat_phids
=
array_mergev
(
$handle_phids
);
$viewer
=
$this
->
getViewer
();
$handles
=
$viewer
->
loadHandles
(
$flat_phids
);
$handles
=
iterator_to_array
(
$handles
);
foreach
(
$handle_phids
as
$conpherence_phid
=>
$phids
)
{
$conpherence
=
$conpherences
[
$conpherence_phid
];
$conpherence
->
attachHandles
(
$conpherence
->
getHandles
()
+
array_select_keys
(
$handles
,
$phids
));
}
return
$this
;
}
private
function
loadTransactionsAndHandles
(
array
$conpherences
)
{
// NOTE: This is older code which has been modernized to the minimum
// standard required by T13266. It probably isn't the best available
// approach to the problems it solves.
$limit
=
$this
->
getTransactionLimit
();
if
(
$limit
)
{
// fetch an extra for "show older" scenarios
$limit
=
$limit
+
1
;
}
else
{
$limit
=
0xFFFF
;
}
$pager
=
id
(
new
AphrontCursorPagerView
())
->
setPageSize
(
$limit
);
// We have to flip these for the underlying query class. The semantics of
// paging are tricky business.
if
(
$this
->
afterTransactionID
)
{
$pager
->
setBeforeID
(
$this
->
afterTransactionID
);
}
else
if
(
$this
->
beforeTransactionID
)
{
$pager
->
setAfterID
(
$this
->
beforeTransactionID
);
}
$transactions
=
id
(
new
ConpherenceTransactionQuery
())
->
setViewer
(
$this
->
getViewer
())
->
withObjectPHIDs
(
array_keys
(
$conpherences
))
->
needHandles
(
true
)
->
executeWithCursorPager
(
$pager
);
$transactions
=
mgroup
(
$transactions
,
'getObjectPHID'
);
foreach
(
$conpherences
as
$phid
=>
$conpherence
)
{
$current_transactions
=
idx
(
$transactions
,
$phid
,
array
());
$handles
=
array
();
foreach
(
$current_transactions
as
$transaction
)
{
$handles
+=
$transaction
->
getHandles
();
}
$conpherence
->
attachHandles
(
$conpherence
->
getHandles
()
+
$handles
);
$conpherence
->
attachTransactions
(
$current_transactions
);
}
return
$this
;
}
public
function
getQueryApplicationClass
()
{
return
PhabricatorConpherenceApplication
::
class
;
}
protected
function
getPrimaryTableAlias
()
{
return
'thread'
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Mon, Jun 16, 8:19 PM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
220604
Default Alt Text
ConpherenceThreadQuery.php (9 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment