1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Created by PhpStorm. |
4
|
|
|
* User: peter |
5
|
|
|
* Date: 17.12.17 |
6
|
|
|
* Time: 14:36 |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace Maslosoft\Mangan\Helpers; |
10
|
|
|
|
11
|
|
|
use Maslosoft\Addendum\Addendum; |
12
|
|
|
use Maslosoft\Addendum\Helpers\SoftIncluder; |
13
|
|
|
use Maslosoft\Addendum\Interfaces\AnnotatedInterface; |
14
|
|
|
use Maslosoft\Cli\Shared\Helpers\PhpExporter; |
15
|
|
|
use Maslosoft\Mangan\Helpers\Index\IndexModel; |
16
|
|
|
use Maslosoft\Mangan\Mangan; |
17
|
|
|
use Maslosoft\Mangan\Meta\DocumentPropertyMeta; |
18
|
|
|
use Maslosoft\Mangan\Meta\ManganMeta; |
19
|
|
|
use Maslosoft\ManganTest\Extensions\IndexMetaCleaner; |
20
|
|
|
|
21
|
|
|
class IndexManager |
22
|
|
|
{ |
23
|
|
|
const IndexTypeHashed = 'hashed'; |
24
|
|
|
const IndexType2dSphere = '2dsphere'; |
25
|
|
|
|
26
|
|
|
const DefaultInstanceId = 'indexManager'; |
27
|
|
|
|
28
|
|
|
private static $instances = []; |
29
|
|
|
|
30
|
|
|
private static $paths = []; |
31
|
|
|
|
32
|
|
|
private static $haveIndex = []; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* NOTE: This is public because of IndexMetaCleaner testing extension |
36
|
|
|
* |
37
|
|
|
* @see IndexMetaCleaner |
38
|
|
|
* @internal |
39
|
|
|
* @var bool |
40
|
|
|
*/ |
41
|
|
|
public static $haveDir = false; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Create flyweight instance of index manager |
45
|
|
|
* @param string $instanceId |
46
|
|
|
* @return static |
47
|
|
|
*/ |
48
|
|
|
public static function fly($instanceId = self::DefaultInstanceId) |
49
|
|
|
{ |
50
|
|
|
if (empty(self::$instances[$instanceId])) |
51
|
|
|
{ |
52
|
|
|
self::$instances[$instanceId] = new static(); |
53
|
|
|
} |
54
|
|
|
return self::$instances[$instanceId]; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
public function create(AnnotatedInterface $model) |
58
|
|
|
{ |
59
|
|
|
$className = get_class($model); |
60
|
|
|
|
61
|
|
|
// If have or don't have indexes skip further checks |
62
|
|
|
if(array_key_exists($className, self::$haveIndex)) |
63
|
|
|
{ |
64
|
|
|
return self::$haveIndex[$className]; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
$fieldMetas = ManganMeta::create($model)->fields('index'); |
|
|
|
|
68
|
|
|
|
69
|
|
|
// Does not have indexes, mark as index-less |
70
|
|
|
if(empty($fieldMetas)) |
71
|
|
|
{ |
72
|
|
|
self::$haveIndex[$className] = false; |
73
|
|
|
return false; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
$path = $this->getStoragePath($model, $className); |
77
|
|
|
|
78
|
|
|
$data = SoftIncluder::includeFile($path); |
79
|
|
|
|
80
|
|
|
if(!empty($data)) |
81
|
|
|
{ |
82
|
|
|
return true; |
83
|
|
|
} |
84
|
|
|
$results = []; |
85
|
|
|
$indexes = []; |
86
|
|
|
foreach($fieldMetas as $fieldMeta) |
87
|
|
|
{ |
88
|
|
|
if(empty($fieldMeta->index)) |
89
|
|
|
{ |
90
|
|
|
continue; |
91
|
|
|
} |
92
|
|
|
/* @var $fieldMeta DocumentPropertyMeta */ |
93
|
|
|
|
94
|
|
|
foreach($fieldMeta->index as $indexMeta) |
95
|
|
|
{ |
96
|
|
|
$index = new IndexModel($model, $indexMeta); |
97
|
|
|
$results[] = (int)$index->apply(); |
98
|
|
|
$indexes[] = $index->getIndexes(); |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
self::$haveIndex[$className] = true; |
102
|
|
|
|
103
|
|
|
$dir = dirname($path); |
104
|
|
|
if(!self::$haveDir && !file_exists($dir)) |
105
|
|
|
{ |
106
|
|
|
self::$haveDir = mkdir($dir); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
file_put_contents($path, PhpExporter::export($indexes, 'Auto generated, do not modify')); |
110
|
|
|
|
111
|
|
|
return array_sum($results) === count($results); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
public function getStoragePath(AnnotatedInterface $model, $className) |
115
|
|
|
{ |
116
|
|
|
if(empty(self::$paths[$className])) |
117
|
|
|
{ |
118
|
|
|
$mn = Mangan::fromModel($model); |
119
|
|
|
|
120
|
|
|
$params = [ |
121
|
|
|
Addendum::fly()->runtimePath, |
122
|
|
|
str_replace('\\', '.', static::class), |
123
|
|
|
$mn->connectionId, |
124
|
|
|
$mn->dbName, |
125
|
|
|
str_replace('\\', '.', $className), |
126
|
|
|
]; |
127
|
|
|
self::$paths[$className] = vsprintf('%s/%s/%s.%s@%s.php', $params); |
128
|
|
|
} |
129
|
|
|
return self::$paths[$className]; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
|
133
|
|
|
} |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.