Passed
Branchfeature/useWidgetsNamespaces (b6928f)
by Robin
03:02
created

AppLinkSet::selectForSources()   B

Complexity

Conditions 7
Paths 27

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 18
c 1
b 0
f 1
dl 0
loc 30
rs 8.8333
cc 7
nc 27
nop 3
1
<?php
2
3
// -------------------------------------------------------------------------
4
// OVIDENTIA http://www.ovidentia.org
5
// Ovidentia is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 2, or (at your option)
8
// any later version.
9
//
10
// This program is distributed in the hope that it will be useful, but
11
// WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
// See the GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18
// USA.
19
// -------------------------------------------------------------------------
20
/**
21
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
22
 * @copyright Copyright (c) 2022 by SI4YOU ({@link https://www.siforyou.com})
23
 */
24
namespace Capwelton\LibApp\Set;
25
26
use Capwelton\LibApp\Func_App;
27
use Capwelton\LibOrm\ORMIterator;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\ORMIterator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Capwelton\LibOrm\Criteria\ORMCriteria;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\Criteria\ORMCriteria was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
use Capwelton\LibOrm\Criteria\ORMIsCriterion;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\Criteria\ORMIsCriterion was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use function Capwelton\LibOrm\ORM_StringField;
0 ignored issues
show
introduced by
The function Capwelton\LibOrm\ORM_StringField was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
31
32
/**
33
 * An arbitrary link between two records.
34
 *
35
 * @property ORM_StringField $sourceClass
36
 * @property ORM_StringField $sourceId
37
 * @property ORM_StringField $targetClass
38
 * @property ORM_StringField $targetId
39
 * @property ORM_StringField $type
40
 * @property ORM_StringField $data
41
 *
42
 * @method app_Link get()
43
 * @method app_Link request()
44
 * @method app_Link[]|\ORM_Iterator select()
45
 * @method app_Link newRecord()
46
 * @method Func_App App()
47
 */
48
class AppLinkSet extends AppRecordSet
49
{
50
    
51
    /**
52
     * @param Func_App $App
53
     */
54
    public function __construct(Func_App $App)
55
    {
56
        parent::__construct($App);
57
        
58
        $App = $this->App();
0 ignored issues
show
Unused Code introduced by
The assignment to $App is dead and can be removed.
Loading history...
59
        $this->setTableName("app_link");
60
        $this->setPrimaryKey('id');
61
        
62
        $this->addFields(
63
            ORM_StringField('sourceClass')->setDescription('Source object class'), 
64
            ORM_StringField('sourceId')->setDescription('Source object id'), 
65
            ORM_StringField('targetClass')->setDescription('Target object class'), 
66
            ORM_StringField('targetId')->setDescription('Target object id'), 
67
            ORM_StringField('type')->setDescription('Link type'), 
68
            ORM_StringField('data')->setDescription('Additional data')
69
        );
70
    }
71
    
72
    /**
73
     * Link record to $source
74
     *
75
     * @param AppRecord $source
76
     * @param string $linkType
77
     * @param string $data
78
     * @return self
79
     */
80
    
81
    /**
82
     * Create a link from $source to $target with the specified type and optional associated data.
83
     *
84
     * @param AppRecord $source
85
     * @param AppRecord $target
86
     * @param string $linkType
87
     * @param string $data
88
     * @return AppLink
89
     */
90
    public function create(AppRecord $source, AppRecord $target, $linkType = '', $data = '')
91
    {
92
        $link = $this->newRecord();
93
        $sourceClass = $source->getClassName();
94
        if(strpos($sourceClass, '\\')){
95
            $sourceClass = (new \ReflectionClass($sourceClass))->getShortName();
96
        }
97
        $targetClass = $target->getClassName();
98
        if(strpos($targetClass, '\\')){
99
            $targetClass = (new \ReflectionClass($targetClass))->getShortName();
100
        }
101
        $link->sourceClass = $sourceClass;
102
        $link->sourceId = $source->id;
103
        $link->targetClass = $targetClass;
104
        $link->targetId = $target->id;
105
        $link->type = $linkType;
106
        $link->data = $data;
107
        $link->save();
108
        
109
        return $link;
110
    }
111
    
112
    /**
113
     * @param string $sourceClass
114
     */
115
    public function joinSource($sourceClass)
116
    {
117
        if(strpos($sourceClass, '\\')){
118
            $sourceClass = (new \ReflectionClass($sourceClass))->getShortName();
119
        }
120
        if(! $this->sourceId instanceof $sourceClass){
121
            $this->hasOne('sourceId', $sourceClass . 'Set');
122
            $this->join('sourceId');
123
        }
124
    }
125
    
126
    /**
127
     * @param string $targetClass
128
     */
129
    public function joinTarget($targetClass = null)
130
    {
131
        if(strpos($targetClass, '\\')){
0 ignored issues
show
Bug introduced by
It seems like $targetClass can also be of type null; however, parameter $haystack of strpos() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

131
        if(strpos(/** @scrutinizer ignore-type */ $targetClass, '\\')){
Loading history...
132
            $targetClass = (new \ReflectionClass($targetClass))->getShortName();
133
        }
134
        if(! $this->targetId instanceof $targetClass){
135
            $this->hasOne('targetId', $targetClass . 'Set');
136
            $this->join('targetId');
137
        }
138
    }
139
    
140
    /**
141
     * @param string $recordClass
142
     * @return ORMIsCriterion
143
     */
144
    public function sourceIsA($recordClass)
145
    {
146
        if(strpos($recordClass, '\\')){
147
            $recordClass = (new \ReflectionClass($recordClass))->getShortName();
148
        }
149
        return $this->sourceClass->is($recordClass);
150
    }
151
    
152
    /**
153
     * @param AppRecord $record
154
     * @return ORMCriteria
155
     */
156
    public function sourceIs(AppRecord $record)
157
    {
158
        return $this->all($this->sourceId->is($record->id), $this->sourceIsA($record->getClassName()));
159
    }
160
    
161
    /**
162
     * @param string $recordClass
163
     * @return ORMIsCriterion
164
     */
165
    public function targetIsA($recordClass)
166
    {
167
        if(strpos($recordClass, '\\')){
168
            $recordClass = (new \ReflectionClass($recordClass))->getShortName();
169
        }
170
        return $this->targetClass->is($recordClass);
171
    }
172
    
173
    /**
174
     * @param AppRecord $record
175
     * @return ORMCriteria
176
     */
177
    public function targetIs(AppRecord $record)
178
    {
179
        return $this->all($this->targetId->is($record->id), $this->targetIsA($record->getClassName()));
180
    }
181
    
182
    /**
183
     * @return ORMIterator
184
     */
185
    public function selectForSource(AppRecord $object, $targetClass = null, $linkType = null)
186
    {
187
        $criteria = $this->sourceIs($object);
188
        
189
        
190
        if(isset($targetClass)){
191
            if(strpos($targetClass, '\\')){
192
                $targetClass = (new \ReflectionClass($targetClass))->getShortName();
193
            }
194
            $this->joinTarget($targetClass);
195
            $criteria = $criteria->_AND_($this->targetClass->is($targetClass));
196
        }
197
        
198
        if(isset($linkType)){
199
            if(is_array($linkType)){
200
                $criteria = $criteria->_AND_($this->type->in($linkType));
201
            }
202
            else{
203
                $criteria = $criteria->_AND_($this->type->is($linkType));
204
            }
205
        }
206
        
207
        if(is_a($this->targetId, 'app_TraceableRecordSet')){
208
            $criteria = $criteria->_AND_($this->targetId->deleted->is(false));
209
        }
210
        
211
        return $this->select($criteria);
0 ignored issues
show
Unused Code introduced by
The call to Capwelton\LibApp\Set\AppLinkSet::select() has too many arguments starting with $criteria. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

211
        return $this->/** @scrutinizer ignore-call */ select($criteria);

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. Please note the @ignore annotation hint above.

Loading history...
Bug Best Practice introduced by
The expression return $this->select($criteria) returns the type Capwelton\LibApp\Set\app_Link[]&ORM_Iterator which is incompatible with the documented return type Capwelton\LibOrm\ORMIterator.
Loading history...
212
    }
213
    
214
    /**
215
     * @return ORMIterator
216
     */
217
    public function selectForSources($objects, $targetClass, $linkType = null)
218
    {
219
        $sourceClass = null;
220
        $sourceIds = array();
221
        
222
        foreach ($objects as $obj){
223
            if(is_null($sourceClass)){
224
                $sourceClass = $obj->getClassName();
225
            }
226
            $sourceIds[] = $obj->id;
227
        }
228
        $criteria = $this->sourceId->in($sourceIds)->_AND_($this->sourceClass->is($sourceClass));
229
        
230
        if(isset($targetClass)){
231
            if(strpos($targetClass, '\\')){
232
                $targetClass = (new \ReflectionClass($targetClass))->getShortName();
233
            }
234
            $this->joinTarget($targetClass);
235
            $criteria = $criteria->_AND_($this->targetClass->is($targetClass));
236
        }
237
        
238
        if(isset($linkType)){
239
            if(is_array($linkType)){
240
                $criteria = $criteria->_AND_($this->type->in($linkType));
241
            }
242
            else{
243
                $criteria = $criteria->_AND_($this->type->is($linkType));
244
            }
245
        }
246
        return $this->select($criteria);
0 ignored issues
show
Unused Code introduced by
The call to Capwelton\LibApp\Set\AppLinkSet::select() has too many arguments starting with $criteria. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

246
        return $this->/** @scrutinizer ignore-call */ select($criteria);

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. Please note the @ignore annotation hint above.

Loading history...
Bug Best Practice introduced by
The expression return $this->select($criteria) returns the type Capwelton\LibApp\Set\app_Link[]&ORM_Iterator which is incompatible with the documented return type Capwelton\LibOrm\ORMIterator.
Loading history...
247
    }
248
    
249
    /**
250
     * @return ORMIterator
251
     */
252
    public function selectForTarget(AppRecord $object, $sourceClass = null, $linkType = null)
253
    {
254
        $criteria = $this->targetIs($object);
255
        
256
        if(isset($sourceClass)){
257
            if(strpos($sourceClass, '\\')){
258
                $sourceClass = (new \ReflectionClass($sourceClass))->getShortName();
259
            }
260
            $this->joinSource($sourceClass);
261
            $criteria = $criteria->_AND_($this->sourceClass->is($sourceClass));
262
        }
263
        
264
        if(isset($linkType)){
265
            if(is_array($linkType)){
266
                $criteria = $criteria->_AND_($this->type->in($linkType));
267
            }
268
            else{
269
                $criteria = $criteria->_AND_($this->type->is($linkType));
270
            }
271
        }
272
        
273
        return $this->select($criteria);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->select($criteria) returns the type Capwelton\LibApp\Set\app_Link[]&ORM_Iterator which is incompatible with the documented return type Capwelton\LibOrm\ORMIterator.
Loading history...
Unused Code introduced by
The call to Capwelton\LibApp\Set\AppLinkSet::select() has too many arguments starting with $criteria. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

273
        return $this->/** @scrutinizer ignore-call */ select($criteria);

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. Please note the @ignore annotation hint above.

Loading history...
274
    }
275
    
276
    /**
277
     * @return ORMIterator
278
     */
279
    public function selectForTargets($objects, $sourceClass = null, $linkType = null)
280
    {
281
        $targetClass = null;
282
        $targetIds = array();
283
        
284
        foreach ($objects as $obj){
285
            if(is_null($targetClass)){
286
                $targetClass = $obj->getClassName();
287
            }
288
            $targetIds[] = $obj->id;
289
        }
290
        $criteria = $this->targetId->in($targetIds)->_AND_($this->targetClass->is($targetClass));
291
        
292
        if(isset($sourceClass)){
293
            if(strpos($sourceClass, '\\')){
294
                $sourceClass = (new \ReflectionClass($sourceClass))->getShortName();
295
            }
296
            $this->joinSource($sourceClass);
297
            $criteria = $criteria->_AND_($this->sourceClass->is($sourceClass));
298
        }
299
        
300
        if(isset($linkType)){
301
            if(is_array($linkType)){
302
                $criteria = $criteria->_AND_($this->type->in($linkType));
303
            }
304
            else{
305
                $criteria = $criteria->_AND_($this->type->is($linkType));
306
            }
307
        }
308
        
309
        return $this->select($criteria);
0 ignored issues
show
Unused Code introduced by
The call to Capwelton\LibApp\Set\AppLinkSet::select() has too many arguments starting with $criteria. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

309
        return $this->/** @scrutinizer ignore-call */ select($criteria);

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. Please note the @ignore annotation hint above.

Loading history...
Bug Best Practice introduced by
The expression return $this->select($criteria) returns the type Capwelton\LibApp\Set\app_Link[]&ORM_Iterator which is incompatible with the documented return type Capwelton\LibOrm\ORMIterator.
Loading history...
310
    }
311
    
312
    /**
313
     * delete all links to an object
314
     *
315
     * @param AppRecord $object
316
     * @param string $targetClass
317
     *            if target class is set, links will be deleted only for target classes
318
     * @param bool $deleteTarget
319
     *            if set to true, the target will be deleted to
320
     */
321
    public function deleteForSource(AppRecord $object, $targetClass = null, $deleteTarget = false, $linkType = null)
322
    {
323
        $set = clone $this;
324
        $App = $object->App();
325
        
326
        $criteria = $set->sourceId->is($object->id)->_AND_($set->sourceClass->is($object->getClassName()));
327
        
328
        if(null !== $targetClass){
329
            if(strpos($targetClass, '\\')){
330
                $targetClass = (new \ReflectionClass($targetClass))->getShortName();
331
            }
332
            $criteria = $criteria->_AND_($set->targetClass->is($targetClass));
333
        }
334
        if(null !== $linkType){
335
            $criteria = $criteria->_AND_($set->type->is($linkType));
336
        }
337
        
338
        if($deleteTarget){
339
            foreach ($set->select($criteria) as $link){
0 ignored issues
show
Unused Code introduced by
The call to Capwelton\LibApp\Set\AppLinkSet::select() has too many arguments starting with $criteria. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

339
            foreach ($set->/** @scrutinizer ignore-call */ select($criteria) as $link){

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. Please note the @ignore annotation hint above.

Loading history...
340
                
341
                $className = $link->targetClass . 'Set';
342
                
343
                // remove prefix
344
                
345
                $className = mb_substr($className, 1 + mb_strpos($className, '_'));
346
                $targetSet = $App->$className();
347
                
348
                $targetSet->delete($targetSet->id->is($link->targetId));
349
            }
350
        }
351
        
352
        return $set->delete($criteria);
353
    }
354
    
355
    /**
356
     * Deletes links between two objects
357
     *
358
     * @param AppRecord $source
359
     * @param AppRecord $target
360
     * @param string $linkType
361
     * @return self
362
     */
363
    public function deleteLink($source, $target, $linkType = null)
364
    {
365
        $sourceClass = $source->getClassName();
366
        if(strpos($sourceClass, '\\')){
367
            $sourceClass = (new \ReflectionClass($sourceClass))->getShortName();
368
        }
369
        $targetClass = $target->getClassName();
370
        if(strpos($targetClass, '\\')){
371
            $targetClass = (new \ReflectionClass($targetClass))->getShortName();
372
        }
373
        $criteria = $this->sourceId->is($source->id)
374
            ->_AND_($this->sourceClass->is($sourceClass))
375
            ->_AND_($this->targetId->is($target->id))
376
            ->_AND_($this->targetClass->is($targetClass));
377
        if(isset($linkType)){
378
            if(is_array($linkType)){
0 ignored issues
show
introduced by
The condition is_array($linkType) is always false.
Loading history...
379
                $criteria = $criteria->_AND_($this->type->in($linkType));
380
            }
381
            else{
382
                $criteria = $criteria->_AND_($this->type->is($linkType));
383
            }
384
        }
385
        
386
        $this->delete($criteria);
387
        return $this;
388
    }
389
}