EntityRoute.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.6.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Routing\Route;
  16. use ArrayAccess;
  17. use RuntimeException;
  18. /**
  19. * Matches entities to routes
  20. *
  21. * This route will match by entity and map its fields to the URL pattern by
  22. * comparing the field names with the template vars. This makes it easy and
  23. * convenient to change routes globally.
  24. */
  25. class EntityRoute extends Route
  26. {
  27. /**
  28. * Match by entity and map its fields to the URL pattern by comparing the
  29. * field names with the template vars.
  30. *
  31. * If a routing key is defined in both `$url` and the entity, the value defined
  32. * in `$url` will be preferred.
  33. *
  34. * @param array $url Array of parameters to convert to a string.
  35. * @param array $context An array of the current request context.
  36. * Contains information such as the current host, scheme, port, and base
  37. * directory.
  38. * @return bool|string Either false or a string URL.
  39. */
  40. public function match(array $url, array $context = [])
  41. {
  42. if (isset($url['_entity'])) {
  43. $entity = $url['_entity'];
  44. $this->_checkEntity($entity);
  45. preg_match_all('@:(\w+)@', $this->template, $matches);
  46. foreach ($matches[1] as $field) {
  47. if (!isset($url[$field]) && isset($entity[$field])) {
  48. $url[$field] = $entity[$field];
  49. }
  50. }
  51. }
  52. return parent::match($url, $context);
  53. }
  54. /**
  55. * Checks that we really deal with an entity object
  56. *
  57. * @throws \RuntimeException
  58. * @param \ArrayAccess|array $entity Entity value from the URL options
  59. * @return void
  60. */
  61. protected function _checkEntity($entity)
  62. {
  63. if (!$entity instanceof ArrayAccess && !is_array($entity)) {
  64. throw new RuntimeException(sprintf(
  65. 'Route `%s` expects the URL option `_entity` to be an array or object implementing \ArrayAccess, but `%s` passed.',
  66. $this->template,
  67. getTypeName($entity)
  68. ));
  69. }
  70. }
  71. }