Development

/branches/1.3/lib/routing/sfObjectRoute.class.php

You must first sign up to be able to contribute.

root/branches/1.3/lib/routing/sfObjectRoute.class.php

Revision 20784, 6.7 kB (checked in by Kris.Wallsmith, 5 years ago)

[1.3] rolled back function signature changes made in r17403 for due to BC concerns

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * sfObjectRoute represents a route that is bound to PHP object(s).
13  *
14  * An object route can represent a single object or a list of objects.
15  *
16  * @package    symfony
17  * @subpackage routing
18  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
19  * @version    SVN: $Id$
20  */
21 class sfObjectRoute extends sfRequestRoute
22 {
23   protected
24     $object  = false,
25     $objects = false;
26
27   /**
28    * Constructor.
29    *
30    * @param string $pattern       The pattern to match
31    * @param array  $defaults      An array of default parameter values
32    * @param array  $requirements  An array of requirements for parameters (regexes)
33    * @param array  $options       An array of options
34    *
35    * @see sfRoute
36    */
37   public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array())
38   {
39     if (!isset($options['model']))
40     {
41       throw new InvalidArgumentException(sprintf('You must pass a "model" option for a %s object (%s).', get_class($this), $pattern));
42     }
43
44     if (!isset($options['type']))
45     {
46       throw new InvalidArgumentException(sprintf('You must pass a "type" option for a %s object (%s).', get_class($this), $pattern));
47     }
48
49     if (!in_array($options['type'], array('object', 'list')))
50     {
51       throw new InvalidArgumentException(sprintf('The "type" option can only be "object" or "list", "%s" given (%s).', $options['type'], $pattern));
52     }
53
54     parent::__construct($pattern, $defaults, $requirements, $options);
55   }
56
57   /**
58    * Returns true if the parameters matches this route, false otherwise.
59    *
60    * @param  mixed  $params  The parameters
61    * @param  array  $context The context
62    *
63    * @return Boolean         true if the parameters matches this route, false otherwise.
64    */
65   public function matchesParameters($params, $context = array())
66   {
67     return parent::matchesParameters('object' == $this->options['type'] ? $this->convertObjectToArray($params) : $params);
68   }
69
70   /**
71    * Generates a URL from the given parameters.
72    *
73    * @param  mixed   $params    The parameter values
74    * @param  array   $context   The context
75    * @param  Boolean $absolute  Whether to generate an absolute URL
76    *
77    * @return string The generated URL
78    */
79   public function generate($params, $context = array(), $absolute = false)
80   {
81     return parent::generate('object' == $this->options['type'] ? $this->convertObjectToArray($params) : $params, $context, $absolute);
82   }
83
84   /**
85    * Gets the object related to the current route and parameters.
86    *
87    * This method is only accessible if the route is bound and of type "object".
88    *
89    * @return Object The related object
90    */
91   public function getObject()
92   {
93     if (!$this->isBound())
94     {
95       throw new LogicException('The route is not bound.');
96     }
97
98     if ('object' != $this->options['type'])
99     {
100       throw new LogicException(sprintf('The route "%s" is not of type "object".', $this->pattern));
101     }
102
103     if (false !== $this->object)
104     {
105       return $this->object;
106     }
107
108     // check the related object
109     if (!($this->object = $this->getObjectForParameters($this->parameters)) && (!isset($this->options['allow_empty']) || !$this->options['allow_empty']))
110     {
111       throw new sfError404Exception(sprintf('Unable to find the %s object with the following parameters "%s").', $this->options['model'], str_replace("\n", '', var_export($this->filterParameters($this->parameters), true))));
112     }
113
114     return $this->object;
115   }
116
117   /**
118    * Gets the list of objects related to the current route and parameters.
119    *
120    * This method is only accessible if the route is bound and of type "list".
121    *
122    * @return array And array of related objects
123    */
124   public function getObjects()
125   {
126     if (!$this->isBound())
127     {
128       throw new LogicException('The route is not bound.');
129     }
130
131     if ('list' != $this->options['type'])
132     {
133       throw new LogicException(sprintf('The route "%s" is not of type "list".', $this->pattern));
134     }
135
136     if (false !== $this->objects)
137     {
138       return $this->objects;
139     }
140
141     $this->objects = $this->getObjectsForParameters($this->parameters);
142
143     if (!count($this->objects) && isset($this->options['allow_empty']) && !$this->options['allow_empty'])
144     {
145       throw new sfError404Exception(sprintf('No %s object found for the following parameters "%s").', $this->options['model'], str_replace("\n", '', var_export($this->filterParameters($this->parameters), true))));
146     }
147
148     return $this->objects;
149   }
150
151   protected function getObjectForParameters($parameters)
152   {
153     $className = $this->options['model'];
154
155     if (!isset($this->options['method']))
156     {
157       throw new InvalidArgumentException(sprintf('You must pass a "method" option for a %s object.', get_class($this)));
158     }
159
160     return call_user_func(array($className, $this->options['method']), $this->filterParameters($parameters));
161   }
162
163   protected function getObjectsForParameters($parameters)
164   {
165     $className = $this->options['model'];
166
167     if (!isset($this->options['method']))
168     {
169       throw new InvalidArgumentException(sprintf('You must pass a "method" option for a %s object.', get_class($this)));
170     }
171
172     return call_user_func(array($className, $this->options['method']), $this->filterParameters($parameters));
173   }
174
175   protected function filterParameters($parameters)
176   {
177     if (!is_array($parameters))
178     {
179       return $parameters;
180     }
181
182     $params = array();
183     foreach (array_keys($this->variables) as $variable)
184     {
185       $params[$variable] = $parameters[$variable];
186     }
187
188     return $params;
189   }
190
191   protected function convertObjectToArray($object)
192   {
193     if (!$this->compiled)
194     {
195       $this->compile();
196     }
197
198     if (is_array($object))
199     {
200       if (!isset($object['sf_subject']))
201       {
202         return $object;
203       }
204
205       $parameters = $object;
206       $object = $parameters['sf_subject'];
207       unset($parameters['sf_subject']);
208     }
209     else
210     {
211       $parameters = array();
212     }
213
214     return array_merge($parameters, $this->doConvertObjectToArray($object));
215   }
216
217   protected function doConvertObjectToArray($object)
218   {
219     $method = isset($this->options['convert']) ? $this->options['convert'] : 'toParams';
220
221     return $object->$method();
222   }
223
224   protected function getRealVariables()
225   {
226     $variables = array();
227
228     foreach (array_keys($this->variables) as $variable)
229     {
230       if (0 === strpos($variable, 'sf_') || in_array($variable, array('module', 'action')))
231       {
232         continue;
233       }
234
235       $variables[] = $variable;
236     }
237
238     return $variables;
239   }
240 }
241
Note: See TracBrowser for help on using the browser.