IndexManager   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 7

Test Coverage

Coverage 88.89%

Importance

Changes 0
Metric Value
wmc 18
lcom 2
cbo 7
dl 0
loc 153
ccs 48
cts 54
cp 0.8889
rs 10
c 0
b 0
f 0

3 Methods

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