1: <?php
2: /**
3: * Horde Routes package
4: *
5: * This package is heavily inspired by the Python "Routes" library
6: * by Ben Bangert (http://routes.groovie.org). Routes is based
7: * largely on ideas from Ruby on Rails (http://www.rubyonrails.org).
8: *
9: * @author Maintainable Software, LLC. (http://www.maintainable.com)
10: * @author Mike Naberezny (mike@maintainable.com)
11: * @license http://www.horde.org/licenses/bsd BSD
12: * @package Routes
13: */
14:
15: /**
16: * Pretty-print a listing of routes connected to a mapper.
17: *
18: * @package Routes
19: */
20: class Horde_Routes_Printer
21: {
22: /**
23: * @var Horde_Routes_Mapper
24: */
25: protected $_mapper;
26:
27: /**
28: * Constructor.
29: *
30: * @param Horde_Routes_Mapper $mapper Mapper to analyze for printing
31: */
32: public function __construct($mapper)
33: {
34: $this->_mapper = $mapper;
35: }
36:
37: /**
38: * Pretty-print a listing of the routes connected to the mapper.
39: *
40: * @param stream|null $stream Output stream for printing (optional)
41: * @param string|null $eol Line ending (optional)
42: * @return void
43: */
44: public function printRoutes($stream = null, $eol = PHP_EOL)
45: {
46: $routes = $this->getRoutes();
47: if (empty($routes)) { return; }
48:
49: if ($stream === null) {
50: $stream = fopen('php://output', 'a');
51: }
52:
53: // find the max $widths to size the output columns {'name'=>40, 'method'=>6, ...}
54: $widths = array();
55: foreach (array_keys($routes[0]) as $key) {
56: $width = 0;
57: foreach($routes as $r) {
58: $l = strlen($r[$key]);
59: if ($l > $width) { $width = $l; }
60: }
61: $widths[$key] = $width;
62: }
63:
64: // print the output
65: foreach ($routes as $r) {
66: fwrite($stream, str_pad($r['name'], $widths['name'], ' ', STR_PAD_LEFT) . ' ');
67: fwrite($stream, str_pad($r['method'], $widths['method'], ' ', STR_PAD_RIGHT) . ' ');
68: fwrite($stream, str_pad($r['path'], $widths['path'], ' ', STR_PAD_RIGHT) . ' ');
69: fwrite($stream, $r['hardcodes'] . $eol);
70: }
71: }
72:
73: /**
74: * Analyze the mapper and return an array of data about the
75: * routes connected to the mapper.
76: *
77: * @return array
78: */
79: public function getRoutes()
80: {
81: /**
82: * Traverse all routes connected to the mapper in match order,
83: * and assemble an array of $routes used to build the output
84: */
85: $routes = array();
86: foreach ($this->_mapper->matchList as $route) {
87: // name of this route, or empty string if anonymous
88: $routeName = '';
89: foreach ($this->_mapper->routeNames as $name => $namedRoute) {
90: if ($route === $namedRoute) { $routeName = $name; break; }
91: }
92:
93: // request_method types recognized by this route, or empty string for any
94: $methods = array('');
95: if (isset($route->conditions['method']) && is_array($route->conditions['method']) ) {
96: $methods = $route->conditions['method'];
97: }
98:
99: // hardcoded defaults that can't be overriden by the request path as {:key=>"value"}
100: $hardcodes = array();
101: foreach ($route->hardCoded as $key) {
102: $value = isset($route->defaults[$key]) ? $route->defaults[$key] : 'NULL';
103: $dump = ":{$key}=>\"{$value}\"";
104: ($key == 'controller') ? array_unshift($hardcodes, $dump) : $hardcodes[] = $dump;
105: }
106: $hardcodes = empty($hardcodes) ? '' : '{'. implode(', ', $hardcodes) .'}';
107:
108: // route data for output
109: foreach ($methods as $method) {
110: $routes[] = array('name' => $routeName,
111: 'method' => $method,
112: 'path' => '/' . $route->routePath,
113: 'hardcodes' => $hardcodes);
114: }
115: }
116:
117: return $routes;
118: }
119:
120: }
121: