Completed
Pull Request — staging (#840)
by
unknown
18:46
created

Autoloader::autoload()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 10
nop 1
dl 0
loc 38
rs 8.6897
c 0
b 0
f 0
1
<?php
2
/**
3
 * YIKES Inc. Easy Forms.
4
 *
5
 * @package   YIKES\EasyForms
6
 * @author    Freddie Mixell
7
 * @license   GPL2
8
 */
9
10
namespace YIKES\EasyForms;
11
12
/**
13
 * Class Autoloader.
14
 *
15
 * This is a custom autoloader to replace the functionality that we would
16
 * normally get through the autoloader generated by Composer.
17
 *
18
 * @since   %VERSION%
19
 *
20
 * @package YIKES\EasyForms
21
 */
22
final class Autoloader {
23
24
	/**
25
	 * Array containing the registered namespace structures
26
	 *
27
	 * @since %VERSION%
28
	 *
29
	 * @var array
30
	 */
31
	private $namespaces = [];
32
33
	/**
34
	 * Destructor for the Autoloader class.
35
	 *
36
	 * The destructor automatically unregisters the autoload callback function
37
	 * with the SPL autoload system.
38
	 *
39
	 * @since  %VERSION%
40
	 */
41
	public function __destruct() {
42
		$this->unregister();
43
	}
44
45
	/**
46
	 * Registers the autoload callback with the SPL autoload system.
47
	 *
48
	 * @since    %VERSION%
49
	 */
50
	public function register() {
51
		spl_autoload_register( [ $this, 'autoload' ] );
52
	}
53
54
	/**
55
	 * Unregisters the autoload callback with the SPL autoload system.
56
	 *
57
	 * @since    %VERSION%
58
	 */
59
	public function unregister() {
60
		spl_autoload_unregister( [ $this, 'autoload' ] );
61
	}
62
63
	/**
64
	 * Add a specific namespace structure with our custom autoloader.
65
	 *
66
	 * @since  %VERSION%
67
	 *
68
	 * @param string  $root        Root namespace name.
69
	 * @param string  $base_dir    Directory containing the class files.
70
	 * @param string  $prefix      Prefix to be added before the class.
71
	 * @param string  $suffix      Suffix to be added after the class.
72
	 * @param boolean $lowercase   Whether the class should be changed to
73
	 *                             lowercase.
74
	 * @param boolean $underscores Whether the underscores should be changed to
75
	 *                             hyphens.
76
	 *
77
	 * @return self
78
	 */
79
	public function add_namespace(
80
		$root,
81
		$base_dir,
82
		$prefix = '',
83
		$suffix = '.php',
84
		$lowercase = false,
85
		$underscores = false
86
	) {
87
		$this->namespaces[] = [
88
			'root'        => $this->normalize_root( (string) $root ),
89
			'base_dir'    => trailingslashit( (string) $base_dir ),
90
			'prefix'      => (string) $prefix,
91
			'suffix'      => (string) $suffix,
92
			'lowercase'   => (bool) $lowercase,
93
			'underscores' => (bool) $underscores,
94
		];
95
96
		return $this;
97
	}
98
99
	/**
100
	 * The autoload function that gets registered with the SPL Autoloader
101
	 * system.
102
	 *
103
	 * @since %VERSION%
104
	 *
105
	 * @param string $class The class that got requested by the spl_autoloader.
106
	 */
107
	public function autoload( $class ) {
108
109
		// Iterate over namespaces to find a match.
110
		foreach ( $this->namespaces as $namespace ) {
111
112
			// Move on if the object does not belong to the current namespace.
113
			if ( 0 !== strpos( $class, $namespace['root'] ) ) {
114
				continue;
115
			}
116
117
			// Remove namespace root level to correspond with root filesystem.
118
			$filename = str_replace( $namespace['root'], '', $class );
119
120
			// Replace the namespace separator "\" by the system-dependent directory separator.
121
			$filename = str_replace( '\\', DIRECTORY_SEPARATOR, $filename );
122
123
			// Remove a leading backslash from the class name.
124
			$filename = $this->remove_leading_backslash( $filename );
125
126
			// Change to lower case if requested.
127
			if ( true === $namespace['lowercase'] ) {
128
				$filename = strtolower( $filename );
129
			}
130
131
			// Change underscores into hyphens if requested.
132
			if ( true === $namespace['underscores'] ) {
133
				$filename = str_replace( '_', '-', $filename );
134
			}
135
136
			// Add base_dir, prefix and suffix.
137
			$filepath = "{$namespace['base_dir']}{$namespace['prefix']}{$filename}{$namespace['suffix']}";
138
139
			// Require the file if it exists and is readable.
140
			if ( is_readable( $filepath ) ) {
141
				require $filepath;
142
			}
143
		}
144
	}
145
146
	/**
147
	 * Normalize a namespace root.
148
	 *
149
	 * @since %VERSION%
150
	 *
151
	 * @param string $root Namespace root that needs to be normalized.
152
	 *
153
	 * @return string Normalized namespace root.
154
	 */
155
	private function normalize_root( $root ) {
156
		$root = $this->remove_leading_backslash( $root );
157
158
		return $this->add_trailing_backslash( $root );
159
	}
160
161
	/**
162
	 * Remove a leading backslash from a string.
163
	 *
164
	 * @since %VERSION%
165
	 *
166
	 * @param string $string String to remove the leading backslash from.
167
	 *
168
	 * @return string Modified string.
169
	 */
170
	private function remove_leading_backslash( $string ) {
171
		return ltrim( $string, '\\' );
172
	}
173
174
	/**
175
	 * Make sure a string ends with a trailing backslash.
176
	 *
177
	 * @since %VERSION%
178
	 *
179
	 * @param string $string String to check the trailing backslash of.
180
	 *
181
	 * @return string Modified string.
182
	 */
183
	private function add_trailing_backslash( $string ) {
184
		return rtrim( $string, '\\' ) . '\\';
185
	}
186
}