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 1.2.0
13: * @license https://opensource.org/licenses/mit-license.php MIT License
14: */
15: namespace Cake\Core;
16:
17: /**
18: * App is responsible for resource location, and path management.
19: *
20: * ### Adding paths
21: *
22: * Additional paths for Templates and Plugins are configured with Configure now. See config/app.php for an
23: * example. The `App.paths.plugins` and `App.paths.templates` variables are used to configure paths for plugins
24: * and templates respectively. All class based resources should be mapped using your application's autoloader.
25: *
26: * ### Inspecting loaded paths
27: *
28: * You can inspect the currently loaded paths using `App::path('Controller')` for example to see loaded
29: * controller paths.
30: *
31: * It is also possible to inspect paths for plugin classes, for instance, to get
32: * the path to a plugin's helpers you would call `App::path('View/Helper', 'MyPlugin')`
33: *
34: * ### Locating plugins
35: *
36: * Plugins can be located with App as well. Using Plugin::path('DebugKit') for example, will
37: * give you the full path to the DebugKit plugin.
38: *
39: * @link https://book.cakephp.org/3.0/en/core-libraries/app.html
40: */
41: class App
42: {
43: /**
44: * Return the class name namespaced. This method checks if the class is defined on the
45: * application/plugin, otherwise try to load from the CakePHP core
46: *
47: * @param string $class Class name
48: * @param string $type Type of class
49: * @param string $suffix Class name suffix
50: * @return string|false False if the class is not found or namespaced class name
51: */
52: public static function className($class, $type = '', $suffix = '')
53: {
54: if (strpos($class, '\\') !== false) {
55: return $class;
56: }
57:
58: list($plugin, $name) = pluginSplit($class);
59: $base = $plugin ?: Configure::read('App.namespace');
60: $base = str_replace('/', '\\', rtrim($base, '\\'));
61: $fullname = '\\' . str_replace('/', '\\', $type . '\\' . $name) . $suffix;
62:
63: if (static::_classExistsInBase($fullname, $base)) {
64: return $base . $fullname;
65: }
66: if ($plugin) {
67: return false;
68: }
69: if (static::_classExistsInBase($fullname, 'Cake')) {
70: return 'Cake' . $fullname;
71: }
72:
73: return false;
74: }
75:
76: /**
77: * Returns the plugin split name of a class
78: *
79: * Examples:
80: *
81: * ```
82: * App::shortName(
83: * 'SomeVendor\SomePlugin\Controller\Component\TestComponent',
84: * 'Controller/Component',
85: * 'Component'
86: * )
87: * ```
88: *
89: * Returns: SomeVendor/SomePlugin.Test
90: *
91: * ```
92: * App::shortName(
93: * 'SomeVendor\SomePlugin\Controller\Component\Subfolder\TestComponent',
94: * 'Controller/Component',
95: * 'Component'
96: * )
97: * ```
98: *
99: * Returns: SomeVendor/SomePlugin.Subfolder/Test
100: *
101: * ```
102: * App::shortName(
103: * 'Cake\Controller\Component\AuthComponent',
104: * 'Controller/Component',
105: * 'Component'
106: * )
107: * ```
108: *
109: * Returns: Auth
110: *
111: * @param string $class Class name
112: * @param string $type Type of class
113: * @param string $suffix Class name suffix
114: * @return string Plugin split name of class
115: */
116: public static function shortName($class, $type, $suffix = '')
117: {
118: $class = str_replace('\\', '/', $class);
119: $type = '/' . $type . '/';
120:
121: $pos = strrpos($class, $type);
122: $pluginName = substr($class, 0, $pos);
123: $name = substr($class, $pos + strlen($type));
124:
125: if ($suffix) {
126: $name = substr($name, 0, -strlen($suffix));
127: }
128:
129: $nonPluginNamespaces = [
130: 'Cake',
131: str_replace('\\', '/', Configure::read('App.namespace'))
132: ];
133: if (in_array($pluginName, $nonPluginNamespaces)) {
134: return $name;
135: }
136:
137: return $pluginName . '.' . $name;
138: }
139:
140: /**
141: * _classExistsInBase
142: *
143: * Test isolation wrapper
144: *
145: * @param string $name Class name.
146: * @param string $namespace Namespace.
147: * @return bool
148: */
149: protected static function _classExistsInBase($name, $namespace)
150: {
151: return class_exists($namespace . $name);
152: }
153:
154: /**
155: * Used to read information stored path
156: *
157: * Usage:
158: *
159: * ```
160: * App::path('Plugin');
161: * ```
162: *
163: * Will return the configured paths for plugins. This is a simpler way to access
164: * the `App.paths.plugins` configure variable.
165: *
166: * ```
167: * App::path('Model/Datasource', 'MyPlugin');
168: * ```
169: *
170: * Will return the path for datasources under the 'MyPlugin' plugin.
171: *
172: * @param string $type type of path
173: * @param string|null $plugin name of plugin
174: * @return array
175: * @link https://book.cakephp.org/3.0/en/core-libraries/app.html#finding-paths-to-namespaces
176: */
177: public static function path($type, $plugin = null)
178: {
179: if ($type === 'Plugin') {
180: return (array)Configure::read('App.paths.plugins');
181: }
182: if (empty($plugin) && $type === 'Locale') {
183: return (array)Configure::read('App.paths.locales');
184: }
185: if (empty($plugin) && $type === 'Template') {
186: return (array)Configure::read('App.paths.templates');
187: }
188: if (!empty($plugin)) {
189: return [Plugin::classPath($plugin) . $type . DIRECTORY_SEPARATOR];
190: }
191:
192: return [APP . $type . DIRECTORY_SEPARATOR];
193: }
194:
195: /**
196: * Returns the full path to a package inside the CakePHP core
197: *
198: * Usage:
199: *
200: * ```
201: * App::core('Cache/Engine');
202: * ```
203: *
204: * Will return the full path to the cache engines package.
205: *
206: * @param string $type Package type.
207: * @return array Full path to package
208: */
209: public static function core($type)
210: {
211: return [CAKE . str_replace('/', DIRECTORY_SEPARATOR, $type) . DIRECTORY_SEPARATOR];
212: }
213: }
214: