Completed
Push — master ( 69ef22...b74acb )
by Peter
06:58
created

IndexManager   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 7

Test Coverage

Coverage 90.2%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 17
c 4
b 0
f 0
lcom 2
cbo 7
dl 0
loc 148
ccs 46
cts 51
cp 0.902
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A fly() 0 8 2
C create() 0 69 11
B getStoragePath() 0 28 4
1
<?php
2
3
/**
4
 * This software package is licensed under AGPL or Commercial license.
5
 *
6
 * @package maslosoft/mangan
7
 * @licence AGPL or Commercial
8
 * @copyright Copyright (c) Piotr Masełkowski <[email protected]>
9
 * @copyright Copyright (c) Maslosoft
10
 * @copyright Copyright (c) Others as mentioned in code
11
 * @link https://maslosoft.com/mangan/
12
 */
13
14
namespace Maslosoft\Mangan\Helpers;
15
16
use Maslosoft\Addendum\Addendum;
17
use Maslosoft\Addendum\Helpers\SoftIncluder;
18
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
19
use Maslosoft\Cli\Shared\Helpers\PhpExporter;
20
use Maslosoft\Mangan\Helpers\Index\IndexModel;
21
use Maslosoft\Mangan\Mangan;
22
use Maslosoft\Mangan\Meta\DocumentPropertyMeta;
23
use Maslosoft\Mangan\Meta\ManganMeta;
24
use Maslosoft\ManganTest\Extensions\IndexMetaCleaner;
25
26
class IndexManager
27
{
28
	const IndexTypeHashed = 'hashed';
29
	const IndexType2dSphere = '2dsphere';
30
31
	const DefaultInstanceId = 'indexManager';
32
33
	private static $instances = [];
34
35
	private static $paths = [];
36
37
	/**
38
	 * NOTE: This is public because of IndexMetaCleaner testing extension
39
	 *
40
	 * DO NOT TOUCH!
41
	 *
42
	 * @see IndexMetaCleaner
43
	 * @internal
44
	 * @var array
45
	 */
46
	public static $haveIndex = [];
47
48
	/**
49
	 * NOTE: This is public because of IndexMetaCleaner testing extension
50
	 *
51
	 * DO NOT TOUCH!
52
	 *
53
	 * @see IndexMetaCleaner
54
	 * @internal
55
	 * @var bool
56
	 */
57
	public static $haveDir = false;
58
59
	/**
60
	 * Create flyweight instance of index manager
61
	 * @param string $instanceId
62
	 * @return static
63
	 */
64 126
	public static function fly($instanceId = self::DefaultInstanceId)
65
	{
66 126
		if (empty(self::$instances[$instanceId]))
67
		{
68
			self::$instances[$instanceId] = new static();
69
		}
70 126
		return self::$instances[$instanceId];
71
	}
72
73 125
	public function create(AnnotatedInterface $model)
74
	{
75 125
		$className = get_class($model);
76
77
		// If have or don't have indexes skip further checks
78 125
		if(array_key_exists($className, self::$haveIndex))
79
		{
80 100
			return self::$haveIndex[$className];
81
		}
82
83 125
		$fieldMetas = ManganMeta::create($model)->fields();
84
85
		// Filter out fields without index
86 125
		foreach($fieldMetas as $key => $metaProperty)
87
		{
88 125
			if(empty($metaProperty->index))
89
			{
90 125
				unset($fieldMetas[$key]);
91
			}
92
		}
93
94
		// Does not have indexes, mark as index-less
95 125
		if(empty($fieldMetas))
96
		{
97 117
			self::$haveIndex[$className] = false;
98 117
			return false;
99
		}
100
101 8
		$path = $this->getStoragePath($model, $className);
102
103 8
		$data = SoftIncluder::includeFile($path);
104
105 8
		if(!empty($data))
106
		{
107
			return true;
108
		}
109 8
		$results = [];
110 8
		$indexes = [];
111 8
		foreach($fieldMetas as $fieldMeta)
112
		{
113 8
			if(empty($fieldMeta->index))
114
			{
115
				continue;
116
			}
117
			/* @var $fieldMeta DocumentPropertyMeta */
118
119 8
			foreach($fieldMeta->index as $indexMeta)
120
			{
121 8
				$index = new IndexModel($model, $indexMeta);
122 8
				$results[] = (int)$index->apply();
123 8
				$indexes[] = $index->getIndexes();
124
			}
125
		}
126 8
		self::$haveIndex[$className] = true;
127
128 8
		$dir = dirname($path);
129
130 8
		if(!self::$haveDir && !file_exists($dir))
131
		{
132 8
			$mask = umask(0000);
133 8
			self::$haveDir = mkdir($dir, 0777);
134 8
			umask($mask);
135
		}
136
137 8
		file_put_contents($path, PhpExporter::export($indexes, 'Auto generated, do not modify'));
138 8
		@chmod($path, 0666);
139
140 8
		return array_sum($results) === count($results);
141
	}
142
143 9
	public function getStoragePath(AnnotatedInterface $model = null, $className = null)
144
	{
145 9
		if(empty($className))
146
		{
147
			$className = __CLASS__;
148
		}
149 9
		if(empty(self::$paths[$className]))
150
		{
151 7
			if(empty($model))
152
			{
153
				$mn = Mangan::fly();
154
			}
155
			else
156
			{
157 7
				$mn = Mangan::fromModel($model);
158
			}
159
160
			$params = [
161 7
				Addendum::fly()->runtimePath,
162 7
				str_replace('\\', '.', static::class),
163 7
				$mn->connectionId,
164 7
				$mn->dbName,
165 7
				str_replace('\\', '.', $className),
166
];
167 7
			self::$paths[$className] = vsprintf('%s/%s/%s.%s@%s.php', $params);
168
		}
169 9
		return self::$paths[$className];
170
	}
171
172
173
}