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.0.0
13: * @license https://opensource.org/licenses/mit-license.php MIT License
14: */
15: namespace Cake\Datasource;
16:
17: use Cake\Datasource\Exception\MissingModelException;
18: use UnexpectedValueException;
19:
20: /**
21: * Provides functionality for loading table classes
22: * and other repositories onto properties of the host object.
23: *
24: * Example users of this trait are Cake\Controller\Controller and
25: * Cake\Console\Shell.
26: */
27: trait ModelAwareTrait
28: {
29:
30: /**
31: * This object's primary model class name. Should be a plural form.
32: * CakePHP will not inflect the name.
33: *
34: * Example: For an object named 'Comments', the modelClass would be 'Comments'.
35: * Plugin classes should use `Plugin.Comments` style names to correctly load
36: * models from the correct plugin.
37: *
38: * Use false to not use auto-loading on this object. Null auto-detects based on
39: * controller name.
40: *
41: * @var string|false|null
42: */
43: public $modelClass;
44:
45: /**
46: * A list of overridden model factory functions.
47: *
48: * @var array
49: */
50: protected $_modelFactories = [];
51:
52: /**
53: * The model type to use.
54: *
55: * @var string
56: */
57: protected $_modelType = 'Table';
58:
59: /**
60: * Set the modelClass and modelKey properties based on conventions.
61: *
62: * If the properties are already set they will not be overwritten
63: *
64: * @param string $name Class name.
65: * @return void
66: */
67: protected function _setModelClass($name)
68: {
69: if (empty($this->modelClass)) {
70: $this->modelClass = $name;
71: }
72: }
73:
74: /**
75: * Loads and constructs repository objects required by this object
76: *
77: * Typically used to load ORM Table objects as required. Can
78: * also be used to load other types of repository objects your application uses.
79: *
80: * If a repository provider does not return an object a MissingModelException will
81: * be thrown.
82: *
83: * @param string|null $modelClass Name of model class to load. Defaults to $this->modelClass
84: * @param string|null $modelType The type of repository to load. Defaults to the modelType() value.
85: * @return \Cake\Datasource\RepositoryInterface The model instance created.
86: * @throws \Cake\Datasource\Exception\MissingModelException If the model class cannot be found.
87: * @throws \InvalidArgumentException When using a type that has not been registered.
88: * @throws \UnexpectedValueException If no model type has been defined
89: */
90: public function loadModel($modelClass = null, $modelType = null)
91: {
92: if ($modelClass === null) {
93: $modelClass = $this->modelClass;
94: }
95: if ($modelType === null) {
96: $modelType = $this->getModelType();
97:
98: if ($modelType === null) {
99: throw new UnexpectedValueException('No model type has been defined');
100: }
101: }
102:
103: list(, $alias) = pluginSplit($modelClass, true);
104:
105: if (isset($this->{$alias})) {
106: return $this->{$alias};
107: }
108:
109: if (isset($this->_modelFactories[$modelType])) {
110: $factory = $this->_modelFactories[$modelType];
111: }
112: if (!isset($factory)) {
113: $factory = FactoryLocator::get($modelType);
114: }
115: $this->{$alias} = $factory($modelClass);
116: if (!$this->{$alias}) {
117: throw new MissingModelException([$modelClass, $modelType]);
118: }
119:
120: return $this->{$alias};
121: }
122:
123: /**
124: * Override a existing callable to generate repositories of a given type.
125: *
126: * @param string $type The name of the repository type the factory function is for.
127: * @param callable $factory The factory function used to create instances.
128: * @return void
129: */
130: public function modelFactory($type, callable $factory)
131: {
132: $this->_modelFactories[$type] = $factory;
133: }
134:
135: /**
136: * Get the model type to be used by this class
137: *
138: * @return string
139: */
140: public function getModelType()
141: {
142: return $this->_modelType;
143: }
144:
145: /**
146: * Set the model type to be used by this class
147: *
148: * @param string $modelType The model type
149: *
150: * @return $this
151: */
152: public function setModelType($modelType)
153: {
154: $this->_modelType = $modelType;
155:
156: return $this;
157: }
158:
159: /**
160: * Set or get the model type to be used by this class
161: *
162: * @deprecated 3.5.0 Use getModelType()/setModelType() instead.
163: * @param string|null $modelType The model type or null to retrieve the current
164: *
165: * @return string|$this
166: */
167: public function modelType($modelType = null)
168: {
169: deprecationWarning(
170: get_called_class() . '::modelType() is deprecated. ' .
171: 'Use setModelType()/getModelType() instead.'
172: );
173: if ($modelType === null) {
174: return $this->_modelType;
175: }
176:
177: $this->_modelType = $modelType;
178:
179: return $this;
180: }
181: }
182: