Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F92696623
PhabricatorOwnersPackageQuery.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
Fri, Nov 22, 21:11
Size
10 KB
Mime Type
text/x-php
Expires
Sun, Nov 24, 21:11 (1 d, 18 h)
Engine
blob
Format
Raw Data
Handle
22477858
Attached To
rPH Phabricator
PhabricatorOwnersPackageQuery.php
View Options
<?php
final
class
PhabricatorOwnersPackageQuery
extends
PhabricatorCursorPagedPolicyAwareQuery
{
private
$ids
;
private
$phids
;
private
$ownerPHIDs
;
private
$authorityPHIDs
;
private
$repositoryPHIDs
;
private
$paths
;
private
$statuses
;
private
$controlMap
=
array
();
private
$controlResults
;
private
$needPaths
;
/**
* Query owner PHIDs exactly. This does not expand authorities, so a user
* PHID will not match projects the user is a member of.
*/
public
function
withOwnerPHIDs
(
array
$phids
)
{
$this
->
ownerPHIDs
=
$phids
;
return
$this
;
}
/**
* Query owner authority. This will expand authorities, so a user PHID will
* match both packages they own directly and packages owned by a project they
* are a member of.
*/
public
function
withAuthorityPHIDs
(
array
$phids
)
{
$this
->
authorityPHIDs
=
$phids
;
return
$this
;
}
public
function
withPHIDs
(
array
$phids
)
{
$this
->
phids
=
$phids
;
return
$this
;
}
public
function
withIDs
(
array
$ids
)
{
$this
->
ids
=
$ids
;
return
$this
;
}
public
function
withRepositoryPHIDs
(
array
$phids
)
{
$this
->
repositoryPHIDs
=
$phids
;
return
$this
;
}
public
function
withPaths
(
array
$paths
)
{
$this
->
paths
=
$paths
;
return
$this
;
}
public
function
withStatuses
(
array
$statuses
)
{
$this
->
statuses
=
$statuses
;
return
$this
;
}
public
function
withControl
(
$repository_phid
,
array
$paths
)
{
if
(
empty
(
$this
->
controlMap
[
$repository_phid
]))
{
$this
->
controlMap
[
$repository_phid
]
=
array
();
}
foreach
(
$paths
as
$path
)
{
$path
=
(
string
)
$path
;
$this
->
controlMap
[
$repository_phid
][
$path
]
=
$path
;
}
// We need to load paths to execute control queries.
$this
->
needPaths
=
true
;
return
$this
;
}
public
function
withNameNgrams
(
$ngrams
)
{
return
$this
->
withNgramsConstraint
(
new
PhabricatorOwnersPackageNameNgrams
(),
$ngrams
);
}
public
function
needPaths
(
$need_paths
)
{
$this
->
needPaths
=
$need_paths
;
return
$this
;
}
public
function
newResultObject
()
{
return
new
PhabricatorOwnersPackage
();
}
protected
function
willExecute
()
{
$this
->
controlResults
=
array
();
}
protected
function
loadPage
()
{
return
$this
->
loadStandardPage
(
$this
->
newResultObject
());
}
protected
function
willFilterPage
(
array
$packages
)
{
$package_ids
=
mpull
(
$packages
,
'getID'
);
$owners
=
id
(
new
PhabricatorOwnersOwner
())->
loadAllWhere
(
'packageID IN (%Ld)'
,
$package_ids
);
$owners
=
mgroup
(
$owners
,
'getPackageID'
);
foreach
(
$packages
as
$package
)
{
$package
->
attachOwners
(
idx
(
$owners
,
$package
->
getID
(),
array
()));
}
return
$packages
;
}
protected
function
didFilterPage
(
array
$packages
)
{
$package_ids
=
mpull
(
$packages
,
'getID'
);
if
(
$this
->
needPaths
)
{
$paths
=
id
(
new
PhabricatorOwnersPath
())->
loadAllWhere
(
'packageID IN (%Ld)'
,
$package_ids
);
$paths
=
mgroup
(
$paths
,
'getPackageID'
);
foreach
(
$packages
as
$package
)
{
$package
->
attachPaths
(
idx
(
$paths
,
$package
->
getID
(),
array
()));
}
}
if
(
$this
->
controlMap
)
{
foreach
(
$packages
as
$package
)
{
// If this package is archived, it's no longer a controlling package
// for any path. In particular, it can not force active packages with
// weak dominion to give up control.
if
(
$package
->
isArchived
())
{
continue
;
}
$this
->
controlResults
[
$package
->
getID
()]
=
$package
;
}
}
return
$packages
;
}
protected
function
buildJoinClauseParts
(
AphrontDatabaseConnection
$conn
)
{
$joins
=
parent
::
buildJoinClauseParts
(
$conn
);
if
(
$this
->
shouldJoinOwnersTable
())
{
$joins
[]
=
qsprintf
(
$conn
,
'JOIN %T o ON o.packageID = p.id'
,
id
(
new
PhabricatorOwnersOwner
())->
getTableName
());
}
if
(
$this
->
shouldJoinPathTable
())
{
$joins
[]
=
qsprintf
(
$conn
,
'JOIN %T rpath ON rpath.packageID = p.id'
,
id
(
new
PhabricatorOwnersPath
())->
getTableName
());
}
return
$joins
;
}
protected
function
buildWhereClauseParts
(
AphrontDatabaseConnection
$conn
)
{
$where
=
parent
::
buildWhereClauseParts
(
$conn
);
if
(
$this
->
phids
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'p.phid IN (%Ls)'
,
$this
->
phids
);
}
if
(
$this
->
ids
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'p.id IN (%Ld)'
,
$this
->
ids
);
}
if
(
$this
->
repositoryPHIDs
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'rpath.repositoryPHID IN (%Ls)'
,
$this
->
repositoryPHIDs
);
}
if
(
$this
->
authorityPHIDs
!==
null
)
{
$authority_phids
=
$this
->
expandAuthority
(
$this
->
authorityPHIDs
);
$where
[]
=
qsprintf
(
$conn
,
'o.userPHID IN (%Ls)'
,
$authority_phids
);
}
if
(
$this
->
ownerPHIDs
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'o.userPHID IN (%Ls)'
,
$this
->
ownerPHIDs
);
}
if
(
$this
->
paths
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'rpath.path IN (%Ls)'
,
$this
->
getFragmentsForPaths
(
$this
->
paths
));
}
if
(
$this
->
statuses
!==
null
)
{
$where
[]
=
qsprintf
(
$conn
,
'p.status IN (%Ls)'
,
$this
->
statuses
);
}
if
(
$this
->
controlMap
)
{
$clauses
=
array
();
foreach
(
$this
->
controlMap
as
$repository_phid
=>
$paths
)
{
$fragments
=
$this
->
getFragmentsForPaths
(
$paths
);
$clauses
[]
=
qsprintf
(
$conn
,
'(rpath.repositoryPHID = %s AND rpath.path IN (%Ls))'
,
$repository_phid
,
$fragments
);
}
$where
[]
=
implode
(
' OR '
,
$clauses
);
}
return
$where
;
}
protected
function
shouldGroupQueryResultRows
()
{
if
(
$this
->
shouldJoinOwnersTable
())
{
return
true
;
}
if
(
$this
->
shouldJoinPathTable
())
{
return
true
;
}
return
parent
::
shouldGroupQueryResultRows
();
}
public
function
getBuiltinOrders
()
{
return
array
(
'name'
=>
array
(
'vector'
=>
array
(
'name'
),
'name'
=>
pht
(
'Name'
),
),
)
+
parent
::
getBuiltinOrders
();
}
public
function
getOrderableColumns
()
{
return
parent
::
getOrderableColumns
()
+
array
(
'name'
=>
array
(
'table'
=>
$this
->
getPrimaryTableAlias
(),
'column'
=>
'name'
,
'type'
=>
'string'
,
'unique'
=>
true
,
'reverse'
=>
true
,
),
);
}
protected
function
getPagingValueMap
(
$cursor
,
array
$keys
)
{
$package
=
$this
->
loadCursorObject
(
$cursor
);
return
array
(
'id'
=>
$package
->
getID
(),
'name'
=>
$package
->
getName
(),
);
}
public
function
getQueryApplicationClass
()
{
return
'PhabricatorOwnersApplication'
;
}
protected
function
getPrimaryTableAlias
()
{
return
'p'
;
}
private
function
shouldJoinOwnersTable
()
{
if
(
$this
->
ownerPHIDs
!==
null
)
{
return
true
;
}
if
(
$this
->
authorityPHIDs
!==
null
)
{
return
true
;
}
return
false
;
}
private
function
shouldJoinPathTable
()
{
if
(
$this
->
repositoryPHIDs
!==
null
)
{
return
true
;
}
if
(
$this
->
paths
!==
null
)
{
return
true
;
}
if
(
$this
->
controlMap
)
{
return
true
;
}
return
false
;
}
private
function
expandAuthority
(
array
$phids
)
{
$projects
=
id
(
new
PhabricatorProjectQuery
())
->
setViewer
(
$this
->
getViewer
())
->
withMemberPHIDs
(
$phids
)
->
execute
();
$project_phids
=
mpull
(
$projects
,
'getPHID'
);
return
array_fuse
(
$phids
)
+
array_fuse
(
$project_phids
);
}
private
function
getFragmentsForPaths
(
array
$paths
)
{
$fragments
=
array
();
foreach
(
$paths
as
$path
)
{
foreach
(
PhabricatorOwnersPackage
::
splitPath
(
$path
)
as
$fragment
)
{
$fragments
[
$fragment
]
=
$fragment
;
}
}
return
$fragments
;
}
/* -( Path Control )------------------------------------------------------- */
/**
* Get a list of all packages which control a path or its parent directories,
* ordered from weakest to strongest.
*
* The first package has the most specific claim on the path; the last
* package has the most general claim. Multiple packages may have claims of
* equal strength, so this ordering is primarily one of usability and
* convenience.
*
* @return list<PhabricatorOwnersPackage> List of controlling packages.
*/
public
function
getControllingPackagesForPath
(
$repository_phid
,
$path
,
$ignore_dominion
=
false
)
{
$path
=
(
string
)
$path
;
if
(!
isset
(
$this
->
controlMap
[
$repository_phid
][
$path
]))
{
throw
new
PhutilInvalidStateException
(
'withControl'
);
}
if
(
$this
->
controlResults
===
null
)
{
throw
new
PhutilInvalidStateException
(
'execute'
);
}
$packages
=
$this
->
controlResults
;
$weak_dominion
=
PhabricatorOwnersPackage
::
DOMINION_WEAK
;
$path_fragments
=
PhabricatorOwnersPackage
::
splitPath
(
$path
);
$fragment_count
=
count
(
$path_fragments
);
$matches
=
array
();
foreach
(
$packages
as
$package_id
=>
$package
)
{
$best_match
=
null
;
$include
=
false
;
$repository_paths
=
$package
->
getPathsForRepository
(
$repository_phid
);
foreach
(
$repository_paths
as
$package_path
)
{
$strength
=
$package_path
->
getPathMatchStrength
(
$path_fragments
,
$fragment_count
);
if
(
$strength
>
$best_match
)
{
$best_match
=
$strength
;
$include
=
!
$package_path
->
getExcluded
();
}
}
if
(
$best_match
&&
$include
)
{
if
(
$ignore_dominion
)
{
$is_weak
=
false
;
}
else
{
$is_weak
=
(
$package
->
getDominion
()
==
$weak_dominion
);
}
$matches
[
$package_id
]
=
array
(
'strength'
=>
$best_match
,
'weak'
=>
$is_weak
,
'package'
=>
$package
,
);
}
}
// At each strength level, drop weak packages if there are also strong
// packages of the same strength.
$strength_map
=
igroup
(
$matches
,
'strength'
);
foreach
(
$strength_map
as
$strength
=>
$package_list
)
{
$any_strong
=
false
;
foreach
(
$package_list
as
$package_id
=>
$package
)
{
if
(!
$package
[
'weak'
])
{
$any_strong
=
true
;
break
;
}
}
if
(
$any_strong
)
{
foreach
(
$package_list
as
$package_id
=>
$package
)
{
if
(
$package
[
'weak'
])
{
unset
(
$matches
[
$package_id
]);
}
}
}
}
$matches
=
isort
(
$matches
,
'strength'
);
$matches
=
array_reverse
(
$matches
);
$strongest
=
null
;
foreach
(
$matches
as
$package_id
=>
$match
)
{
if
(
$strongest
===
null
)
{
$strongest
=
$match
[
'strength'
];
}
if
(
$match
[
'strength'
]
===
$strongest
)
{
continue
;
}
if
(
$match
[
'weak'
])
{
unset
(
$matches
[
$package_id
]);
}
}
return
array_values
(
ipull
(
$matches
,
'package'
));
}
}
Event Timeline
Log In to Comment