Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F115554806
PhabricatorProjectColumnPositionQuery.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Jun 1, 17:58
Size
6 KB
Mime Type
text/x-php
Expires
Tue, Jun 3, 17:58 (2 d)
Engine
blob
Format
Raw Data
Handle
26498960
Attached To
rPH Phabricator
PhabricatorProjectColumnPositionQuery.php
View Options
<?php
final
class
PhabricatorProjectColumnPositionQuery
extends
PhabricatorCursorPagedPolicyAwareQuery
{
private
$ids
;
private
$boardPHIDs
;
private
$objectPHIDs
;
private
$columns
;
private
$needColumns
;
public
function
withIDs
(
array
$ids
)
{
$this
->
ids
=
$ids
;
return
$this
;
}
public
function
withBoardPHIDs
(
array
$board_phids
)
{
$this
->
boardPHIDs
=
$board_phids
;
return
$this
;
}
public
function
withObjectPHIDs
(
array
$object_phids
)
{
$this
->
objectPHIDs
=
$object_phids
;
return
$this
;
}
/**
* Find objects in specific columns.
*
* NOTE: Using this method activates logic which constructs virtual
* column positions for objects not in any column, if you pass a default
* column. Normally these results are not returned.
*
* @param list<PhabricatorProjectColumn> Columns to look for objects in.
* @return this
*/
public
function
withColumns
(
array
$columns
)
{
assert_instances_of
(
$columns
,
'PhabricatorProjectColumn'
);
$this
->
columns
=
$columns
;
return
$this
;
}
public
function
needColumns
(
$need_columns
)
{
$this
->
needColumns
=
true
;
return
$this
;
}
// NOTE: For now, boards are always attached to projects. However, they might
// not be in the future. This generalization just anticipates a future where
// we let other types of objects (like users) have boards, or let boards
// contain other types of objects.
private
function
newPositionObject
()
{
return
new
PhabricatorProjectColumnPosition
();
}
private
function
newColumnQuery
()
{
return
new
PhabricatorProjectColumnQuery
();
}
private
function
getBoardMembershipEdgeTypes
()
{
return
array
(
PhabricatorProjectProjectHasObjectEdgeType
::
EDGECONST
,
);
}
private
function
getBoardMembershipPHIDTypes
()
{
return
array
(
ManiphestTaskPHIDType
::
TYPECONST
,
);
}
protected
function
loadPage
()
{
$table
=
$this
->
newPositionObject
();
$conn_r
=
$table
->
establishConnection
(
'r'
);
// We're going to find results by combining two queries: one query finds
// objects on a board column, while the other query finds objects not on
// any board column and virtually puts them on the default column.
$unions
=
array
();
// First, find all the stuff that's actually on a column.
$unions
[]
=
qsprintf
(
$conn_r
,
'SELECT * FROM %T %Q'
,
$table
->
getTableName
(),
$this
->
buildWhereClause
(
$conn_r
));
// If we have a default column, find all the stuff that's not in any
// column and put it in the default column.
$must_type_filter
=
false
;
if
(
$this
->
columns
)
{
$default_map
=
array
();
foreach
(
$this
->
columns
as
$column
)
{
if
(
$column
->
isDefaultColumn
())
{
$default_map
[
$column
->
getProjectPHID
()]
=
$column
->
getPHID
();
}
}
if
(
$default_map
)
{
$where
=
array
();
// Find the edges attached to the boards we have default columns for.
$where
[]
=
qsprintf
(
$conn_r
,
'e.src IN (%Ls)'
,
array_keys
(
$default_map
));
// Find only edges which describe a board relationship.
$where
[]
=
qsprintf
(
$conn_r
,
'e.type IN (%Ld)'
,
$this
->
getBoardMembershipEdgeTypes
());
if
(
$this
->
boardPHIDs
!==
null
)
{
// This should normally be redundant, but construct it anyway if
// the caller has told us to.
$where
[]
=
qsprintf
(
$conn_r
,
'e.src IN (%Ls)'
,
$this
->
boardPHIDs
);
}
if
(
$this
->
objectPHIDs
!==
null
)
{
$where
[]
=
qsprintf
(
$conn_r
,
'e.dst IN (%Ls)'
,
$this
->
objectPHIDs
);
}
$where
[]
=
qsprintf
(
$conn_r
,
'p.id IS NULL'
);
$where
=
$this
->
formatWhereClause
(
$where
);
$unions
[]
=
qsprintf
(
$conn_r
,
'SELECT NULL id, e.src boardPHID, NULL columnPHID, e.dst objectPHID,
0 sequence
FROM %T e LEFT JOIN %T p
ON e.src = p.boardPHID AND e.dst = p.objectPHID
%Q'
,
PhabricatorEdgeConfig
::
TABLE_NAME_EDGE
,
$table
->
getTableName
(),
$where
);
$must_type_filter
=
true
;
}
}
$data
=
queryfx_all
(
$conn_r
,
'%Q %Q %Q'
,
implode
(
' UNION ALL '
,
$unions
),
$this
->
buildOrderClause
(
$conn_r
),
$this
->
buildLimitClause
(
$conn_r
));
// If we've picked up objects not in any column, we need to filter out any
// matched objects which have the wrong edge type.
if
(
$must_type_filter
)
{
$allowed_types
=
array_fuse
(
$this
->
getBoardMembershipPHIDTypes
());
foreach
(
$data
as
$id
=>
$row
)
{
if
(
$row
[
'columnPHID'
]
===
null
)
{
$object_phid
=
$row
[
'objectPHID'
];
if
(
empty
(
$allowed_types
[
phid_get_type
(
$object_phid
)]))
{
unset
(
$data
[
$id
]);
}
}
}
}
$positions
=
$table
->
loadAllFromArray
(
$data
);
foreach
(
$positions
as
$position
)
{
if
(
$position
->
getColumnPHID
()
===
null
)
{
$position
->
makeEphemeral
();
$column_phid
=
idx
(
$default_map
,
$position
->
getBoardPHID
());
$position
->
setColumnPHID
(
$column_phid
);
}
}
return
$positions
;
}
protected
function
willFilterPage
(
array
$page
)
{
if
(
$this
->
needColumns
)
{
$column_phids
=
mpull
(
$page
,
'getColumnPHID'
);
$columns
=
$this
->
newColumnQuery
()
->
setParentQuery
(
$this
)
->
setViewer
(
$this
->
getViewer
())
->
withPHIDs
(
$column_phids
)
->
execute
();
$columns
=
mpull
(
$columns
,
null
,
'getPHID'
);
foreach
(
$page
as
$key
=>
$position
)
{
$column
=
idx
(
$columns
,
$position
->
getColumnPHID
());
if
(!
$column
)
{
unset
(
$page
[
$key
]);
continue
;
}
$position
->
attachColumn
(
$column
);
}
}
return
$page
;
}
private
function
buildWhereClause
(
$conn_r
)
{
$where
=
array
();
if
(
$this
->
ids
!==
null
)
{
$where
[]
=
qsprintf
(
$conn_r
,
'id IN (%Ld)'
,
$this
->
ids
);
}
if
(
$this
->
boardPHIDs
!==
null
)
{
$where
[]
=
qsprintf
(
$conn_r
,
'boardPHID IN (%Ls)'
,
$this
->
boardPHIDs
);
}
if
(
$this
->
objectPHIDs
!==
null
)
{
$where
[]
=
qsprintf
(
$conn_r
,
'objectPHID IN (%Ls)'
,
$this
->
objectPHIDs
);
}
if
(
$this
->
columns
!==
null
)
{
$where
[]
=
qsprintf
(
$conn_r
,
'columnPHID IN (%Ls)'
,
mpull
(
$this
->
columns
,
'getPHID'
));
}
// NOTE: Explicitly not building the paging clause here, since it won't
// work with the UNION.
return
$this
->
formatWhereClause
(
$where
);
}
public
function
getQueryApplicationClass
()
{
return
'PhabricatorProjectApplication'
;
}
}
Event Timeline
Log In to Comment