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: /**
45: * Return the class name namespaced. This method checks if the class is defined on the
46: * application/plugin, otherwise try to load from the CakePHP core
47: *
48: * @param string $class Class name
49: * @param string $type Type of class
50: * @param string $suffix Class name suffix
51: * @return false|string False if the class is not found or namespaced class name
52: */
53: public static function className($class, $type = '', $suffix = '')
54: {
55: if (strpos($class, '\\') !== false) {
56: return $class;
57: }
58:
59: list($plugin, $name) = pluginSplit($class);
60: $base = $plugin ?: Configure::read('App.namespace');
61: $base = str_replace('/', '\\', rtrim($base, '\\'));
62: $fullname = '\\' . str_replace('/', '\\', $type . '\\' . $name) . $suffix;
63:
64: if (static::_classExistsInBase($fullname, $base)) {
65: return $base . $fullname;
66: }
67: if ($plugin) {
68: return false;
69: }
70: if (static::_classExistsInBase($fullname, 'Cake')) {
71: return 'Cake' . $fullname;
72: }
73:
74: return false;
75: }
76:
77: /**
78: * Returns the plugin split name of a class
79: *
80: * Examples:
81: *
82: * ```
83: * App::shortName(
84: * 'SomeVendor\SomePlugin\Controller\Component\TestComponent',
85: * 'Controller/Component',
86: * 'Component'
87: * )
88: * ```
89: *
90: * Returns: SomeVendor/SomePlugin.Test
91: *
92: * ```
93: * App::shortName(
94: * 'SomeVendor\SomePlugin\Controller\Component\Subfolder\TestComponent',
95: * 'Controller/Component',
96: * 'Component'
97: * )
98: * ```
99: *
100: * Returns: SomeVendor/SomePlugin.Subfolder/Test
101: *
102: * ```
103: * App::shortName(
104: * 'Cake\Controller\Component\AuthComponent',
105: * 'Controller/Component',
106: * 'Component'
107: * )
108: * ```
109: *
110: * Returns: Auth
111: *
112: * @param string $class Class name
113: * @param string $type Type of class
114: * @param string $suffix Class name suffix
115: * @return string Plugin split name of class
116: */
117: public static function shortName($class, $type, $suffix = '')
118: {
119: $class = str_replace('\\', '/', $class);
120: $type = '/' . $type . '/';
121:
122: $pos = strrpos($class, $type);
123: $pluginName = substr($class, 0, $pos);
124: $name = substr($class, $pos + strlen($type));
125:
126: if ($suffix) {
127: $name = substr($name, 0, -strlen($suffix));
128: }
129:
130: $nonPluginNamespaces = [
131: 'Cake',
132: str_replace('\\', '/', Configure::read('App.namespace'))
133: ];
134: if (in_array($pluginName, $nonPluginNamespaces)) {
135: return $name;
136: }
137:
138: return $pluginName . '.' . $name;
139: }
140:
141: /**
142: * _classExistsInBase
143: *
144: * Test isolation wrapper
145: *
146: * @param string $name Class name.
147: * @param string $namespace Namespace.
148: * @return bool
149: */
150: protected static function _classExistsInBase($name, $namespace)
151: {
152: return class_exists($namespace . $name);
153: }
154:
155: /**
156: * Used to read information stored path
157: *
158: * Usage:
159: *
160: * ```
161: * App::path('Plugin');
162: * ```
163: *
164: * Will return the configured paths for plugins. This is a simpler way to access
165: * the `App.paths.plugins` configure variable.
166: *
167: * ```
168: * App::path('Model/Datasource', 'MyPlugin');
169: * ```
170: *
171: * Will return the path for datasources under the 'MyPlugin' plugin.
172: *
173: * @param string $type type of path
174: * @param string|null $plugin name of plugin
175: * @return array
176: * @link https://book.cakephp.org/3.0/en/core-libraries/app.html#finding-paths-to-namespaces
177: */
178: public static function path($type, $plugin = null)
179: {
180: if ($type === 'Plugin') {
181: return (array)Configure::read('App.paths.plugins');
182: }
183: if (empty($plugin) && $type === 'Locale') {
184: return (array)Configure::read('App.paths.locales');
185: }
186: if (empty($plugin) && $type === 'Template') {
187: return (array)Configure::read('App.paths.templates');
188: }
189: if (!empty($plugin)) {
190: return [Plugin::classPath($plugin) . $type . DIRECTORY_SEPARATOR];
191: }
192:
193: return [APP . $type . DIRECTORY_SEPARATOR];
194: }
195:
196: /**
197: * Returns the full path to a package inside the CakePHP core
198: *
199: * Usage:
200: *
201: * ```
202: * App::core('Cache/Engine');
203: * ```
204: *
205: * Will return the full path to the cache engines package.
206: *
207: * @param string $type Package type.
208: * @return array Full path to package
209: */
210: public static function core($type)
211: {
212: return [CAKE . str_replace('/', DIRECTORY_SEPARATOR, $type) . DIRECTORY_SEPARATOR];
213: }
214: }
215: