Completed
Push — master ( a190f2...cdd7a4 )
by Nazar
04:06
created

Base::construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2013-2016, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs\Singleton;
9
use
10
	cs\False_class,
11
	cs\Request;
12
13
/**
14
 * Singleton trait
15
 *
16
 * Provides Singleton-like implementation with some advanced capabilities
17
 */
18
trait Base {
19
	private $__request_id;
20 164
	final protected function __construct () {
21 164
	}
22 134
	protected function construct () {
23 134
	}
24
	/**
25
	 * Get instance of class
26
	 *
27
	 * @param bool $check If true - checks, if instance was already created, if not - instance of cs\False_class will be returned
28
	 *
29
	 * @return False_class|static
30
	 */
31 2
	public static function instance ($check = false) {
32 2
		static $instance;
33 2
		return self::instance_prototype($instance, $check);
34
	}
35
	/**
36
	 * Get instance of class
37
	 *
38
	 * @param static $instance
39
	 * @param bool   $check If true - checks, if instance was already created, if not - instance of cs\False_class will be returned
40
	 *
41
	 * @return False_class|static
42
	 */
43 182
	protected static function instance_prototype (&$instance, $check = false) {
44 182
		if (is_object($instance)) {
45 168
			static::instance_reinit($instance);
46 168
			return $instance;
47
		}
48 150
		$called_class = get_called_class();
49 150
		if ($check || strpos($called_class, 'cs') !== 0) {
50 18
			return False_class::instance();
51
		}
52 150
		list($aliases, $final_class) = static::instance_prototype_get_aliases_final_class($called_class);
53 150
		foreach ($aliases as $alias) {
54
			/**
55
			 * If for whatever reason base class does not exists or file that should be included does not exists
56
			 */
57
			if (
58 2
				!class_exists($alias['original'], false) ||
59 2
				!file_exists($alias['path'])
60
			) {
61 2
				__classes_clean_cache();
62 2
				return static::instance_create($instance, $called_class, $called_class);
63
			}
64 2
			class_alias($alias['original'], $alias['alias']);
65 2
			require_once $alias['path'];
66
		}
67 150
		return static::instance_create($instance, $called_class, $final_class);
68
	}
69
	/**
70
	 * @param static $instance
71
	 */
72 168
	protected static function instance_reinit (&$instance) {
73 168
		if ($instance && $instance->__request_id !== Request::$id) {
74 130
			$instance->__request_id = Request::$id;
75 130
			if (defined('static::INIT_STATE_METHOD')) {
76 90
				$instance->{constant('static::INIT_STATE_METHOD')}();
77
			}
78
		}
79 168
	}
80
	/**
81
	 * @param static $instance
1 ignored issue
show
introduced by
The type Base for parameter $instance is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?
Loading history...
82
	 * @param string $called_class
83
	 * @param string $final_class
84
	 *
85
	 * @return static
86
	 */
87 150
	protected static function instance_create (&$instance, $called_class, $final_class) {
88 150
		if ($final_class != $called_class) {
89
			/**
90
			 * We can't access protected methods of class if it doesn't extend current class, so let's call its `::instance()` method instead
91
			 */
92 2
			return $final_class::instance();
93
		}
94 150
		$instance               = new $called_class;
95 150
		$instance->__request_id = Request::$id;
96 150
		$instance->construct();
97 146
		if (defined('static::INIT_STATE_METHOD')) {
98 100
			$instance->{constant('static::INIT_STATE_METHOD')}();
99
		}
100 146
		return $instance;
101
	}
102
	/**
103
	 * @param string $class
104
	 *
105
	 * @return array
106
	 */
107 150
	protected static function instance_prototype_get_aliases_final_class ($class) {
108 150
		$modified_classes = modified_classes();
109 150
		if (!isset($modified_classes[$class])) {
110 72
			$custom_class_base = 'cs\\custom'.substr($class, 2);
111 72
			$next_alias        = $class;
112 72
			$aliases           = [];
113 72
			if (class_exists($custom_class_base, false)) {
114 2
				$next_alias = $custom_class_base;
115
			}
116 72
			$custom_classes_paths = defined('CUSTOM') ? glob(CUSTOM.'/classes/'.str_replace('\\', '/', substr($class, 3)).'_*.php') : [];
117 72
			$custom_length        = defined('CUSTOM') ? strlen(CUSTOM.'/classes/') : 0;
118 72
			foreach ($custom_classes_paths as $custom_class_path) {
119 2
				$custom_class = substr($custom_class_path, $custom_length, -4);
120 2
				$custom_class = 'cs\\custom\\'.str_replace('/', '\\', $custom_class);
121
				// Same path with prefixed class name
122 2
				$_custom_class   = explode('\\', $custom_class);
123 2
				$_custom_class[] = '_'.array_pop($_custom_class);
124 2
				$_custom_class   = implode('\\', $_custom_class);
125 2
				$aliases[]       = [
126 2
					'original' => $next_alias,
127 2
					'alias'    => $_custom_class,
128 2
					'path'     => $custom_class_path
129
				];
130 2
				$next_alias      = $custom_class;
131
			}
132 72
			$modified_classes[$class] = [
133 72
				'aliases'     => $aliases,
134 72
				'final_class' => $next_alias
135
			];
136 72
			modified_classes($modified_classes);
137
		}
138
		return [
139 150
			$modified_classes[$class]['aliases'],
140 150
			$modified_classes[$class]['final_class']
141
		];
142
	}
143
	final protected function __clone () {
144
	}
145
	final protected function __wakeup () {
146
	}
147
}
148