Completed
Push — master ( 235414...6c1418 )
by Peter
03:40
created

IndexManager::create()   C

Complexity

Conditions 11
Paths 25

Size

Total Lines 65
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 65
rs 5.9999
cc 11
eloc 30
nc 25
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
	public static function fly($instanceId = self::DefaultInstanceId)
65
	{
66
		if (empty(self::$instances[$instanceId]))
67
		{
68
			self::$instances[$instanceId] = new static();
69
		}
70
		return self::$instances[$instanceId];
71
	}
72
73
	public function create(AnnotatedInterface $model)
74
	{
75
		$className = get_class($model);
76
77
		// If have or don't have indexes skip further checks
78
		if(array_key_exists($className, self::$haveIndex))
79
		{
80
			return self::$haveIndex[$className];
81
		}
82
83
		$fieldMetas = ManganMeta::create($model)->fields();
84
85
		// Filter out fields without index
86
		foreach($fieldMetas as $key => $metaProperty)
87
		{
88
			if(empty($metaProperty->index))
89
			{
90
				unset($fieldMetas[$key]);
91
			}
92
		}
93
94
		// Does not have indexes, mark as index-less
95
		if(empty($fieldMetas))
96
		{
97
			self::$haveIndex[$className] = false;
98
			return false;
99
		}
100
101
		$path = $this->getStoragePath($model, $className);
102
103
		$data = SoftIncluder::includeFile($path);
104
105
		if(!empty($data))
106
		{
107
			return true;
108
		}
109
		$results = [];
110
		$indexes = [];
111
		foreach($fieldMetas as $fieldMeta)
112
		{
113
			if(empty($fieldMeta->index))
114
			{
115
				continue;
116
			}
117
			/* @var $fieldMeta DocumentPropertyMeta */
118
119
			foreach($fieldMeta->index as $indexMeta)
120
			{
121
				$index = new IndexModel($model, $indexMeta);
122
				$results[] = (int)$index->apply();
123
				$indexes[] = $index->getIndexes();
124
			}
125
		}
126
		self::$haveIndex[$className] = true;
127
128
		$dir = dirname($path);
129
		if(!self::$haveDir && !file_exists($dir))
130
		{
131
			self::$haveDir = mkdir($dir);
132
		}
133
134
		file_put_contents($path, PhpExporter::export($indexes, 'Auto generated, do not modify'));
135
136
		return array_sum($results) === count($results);
137
	}
138
139
	public function getStoragePath(AnnotatedInterface $model, $className)
140
	{
141
		if(empty(self::$paths[$className]))
142
		{
143
			$mn = Mangan::fromModel($model);
144
145
			$params = [
146
				Addendum::fly()->runtimePath,
147
				str_replace('\\', '.', static::class),
148
				$mn->connectionId,
149
				$mn->dbName,
150
				str_replace('\\', '.', $className),
151
];
152
			self::$paths[$className] = vsprintf('%s/%s/%s.%s@%s.php', $params);
153
		}
154
		return self::$paths[$className];
155
	}
156
157
158
}