Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F82359017
AphrontRoutingMap.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
Tue, Sep 10, 23:26
Size
3 KB
Mime Type
text/x-php
Expires
Thu, Sep 12, 23:26 (2 d)
Engine
blob
Format
Raw Data
Handle
20658443
Attached To
rPH Phabricator
AphrontRoutingMap.php
View Options
<?php
/**
* Collection of routes on a site for an application.
*
* @task info Map Information
* @task routing Routing
*/
final
class
AphrontRoutingMap
extends
Phobject
{
private
$site
;
private
$application
;
private
$routes
=
array
();
/* -( Map Info )----------------------------------------------------------- */
public
function
setSite
(
AphrontSite
$site
)
{
$this
->
site
=
$site
;
return
$this
;
}
public
function
getSite
()
{
return
$this
->
site
;
}
public
function
setApplication
(
PhabricatorApplication
$application
)
{
$this
->
application
=
$application
;
return
$this
;
}
public
function
getApplication
()
{
return
$this
->
application
;
}
public
function
setRoutes
(
array
$routes
)
{
$this
->
routes
=
$routes
;
return
$this
;
}
public
function
getRoutes
()
{
return
$this
->
routes
;
}
/* -( Routing )------------------------------------------------------------ */
/**
* Find the route matching a path, if one exists.
*
* @param string Path to route.
* @return AphrontRoutingResult|null Routing result, if path matches map.
* @task routing
*/
public
function
routePath
(
$path
)
{
$map
=
$this
->
getRoutes
();
foreach
(
$map
as
$route
=>
$value
)
{
$match
=
$this
->
tryRoute
(
$route
,
$value
,
$path
);
if
(!
$match
)
{
continue
;
}
$result
=
$this
->
newRoutingResult
();
$application
=
$result
->
getApplication
();
$controller_class
=
$match
[
'class'
];
$controller
=
newv
(
$controller_class
,
array
());
$controller
->
setCurrentApplication
(
$application
);
$result
->
setController
(
$controller
)
->
setURIData
(
$match
[
'data'
]);
return
$result
;
}
return
null
;
}
/**
* Test a sub-map to see if any routes match a path.
*
* @param string Path to route.
* @param string Pattern from the map.
* @param string Value from the map.
* @return dict<string, wild>|null Match details, if path matches sub-map.
* @task routing
*/
private
function
tryRoute
(
$route
,
$value
,
$path
)
{
$has_submap
=
is_array
(
$value
);
if
(!
$has_submap
)
{
// If the value is a controller rather than a sub-map, any matching
// route must completely consume the path.
$pattern
=
'(^'
.
$route
.
'
\z
)'
;
}
else
{
$pattern
=
'(^'
.
$route
.
')'
;
}
$data
=
null
;
$ok
=
preg_match
(
$pattern
,
$path
,
$data
);
if
(
$ok
===
false
)
{
throw
new
Exception
(
pht
(
'Routing fragment "%s" is not a valid regular expression.'
,
$route
));
}
if
(!
$ok
)
{
return
null
;
}
$path_match
=
$data
[
0
];
// Clean up the data. We only want to retain named capturing groups, not
// the duplicated numeric captures.
foreach
(
$data
as
$k
=>
$v
)
{
if
(
is_numeric
(
$k
))
{
unset
(
$data
[
$k
]);
}
}
if
(!
$has_submap
)
{
return
array
(
'class'
=>
$value
,
'data'
=>
$data
,
);
}
$sub_path
=
substr
(
$path
,
strlen
(
$path_match
));
foreach
(
$value
as
$sub_route
=>
$sub_value
)
{
$result
=
$this
->
tryRoute
(
$sub_route
,
$sub_value
,
$sub_path
);
if
(
$result
)
{
$result
[
'data'
]
+=
$data
;
return
$result
;
}
}
return
null
;
}
/**
* Build a new routing result for this map.
*
* @return AphrontRoutingResult New, empty routing result.
* @task routing
*/
private
function
newRoutingResult
()
{
return
id
(
new
AphrontRoutingResult
())
->
setSite
(
$this
->
getSite
())
->
setApplication
(
$this
->
getApplication
());
}
}
Event Timeline
Log In to Comment