Test Setup Failed
Push — develop ( b46587...bd8dda )
by Craig
07:01
created

Datastore::getFieldValues()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
// @todo - move this to a smaller instance and move more of the logic to the Model itself
4
5
namespace Phpsa\Datastore;
6
7
use Phpsa\Datastore\Models\Datastore as DatastoreModel;
8
use Phpsa\Datastore\DatastoreException;
9
use Phpsa\Datastore\Asset;
10
use Phpsa\Datastore\Helpers;
11
use Illuminate\Support\Facades\Storage;
12
use Illuminate\Validation\ValidationException;
13
use Illuminate\Support\Carbon;
14
use Validator;
15
use ReflectionClass;
16
use ReflectionProperty;
17
18
class Datastore{
19
20
	protected $__asset				 = false;
21
	protected $__asset_properties	 = false;
22
	protected $__value_equals		 = false;
23
	protected $__status_equals		 = false;
24
	protected $__start_date			 = null;
25
	protected $__end_date			 = null;
26
27
	/**
28
	 *
29
	 * @var DatastoreModel
30
	 */
31
	protected $__model;
32
33
	/**
34
	 *
35
	 * @var array of datastore_model
36
	 */
37
	public $ownDatastore = false;
38
39
	/**
40
	 * The current record id
0 ignored issues
show
Bug introduced by
The type Phpsa\Datastore\record 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...
41
	 * @var record id
42
	 */
43
	public $id = 0;
44
45
	/**
46
	 * construct a new datastore instance
47
	 * if an id is passed populate the data
48
	 * @param int $id
49
	 */
50
	public function __construct($id = 0)
51
	{
52
53
		$this->id = $id;
0 ignored issues
show
Documentation Bug introduced by
It seems like $id of type integer is incompatible with the declared type Phpsa\Datastore\record of property $id.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
		if ($id)
55
		{
56
			$this->__model = DatastoreModel::findOrFail($id);
57
58
			if(!$this->__model){
59
				//could not load <div class="">thr</div>
60
				throw new DatastoreException("Record not found");
61
			}
62
63
			foreach ($this->__model->toArray() as $k => $v)
64
			{
65
				if($k === 'options' || $k === 'meta'){
66
					$v = json_decode($v, true);
67
				}
68
				if(in_array($k, ['created_at','updated_at','date_start','date_end'])){
69
					$v = Carbon::parse($v);
70
				}
71
				$this->{$k} = $v;
72
			}
73
74
75
			$stores = $this->__model->properties;
76
			if ($stores)
77
			{
78
				foreach ($stores as $ds)
79
				{
80
					$this->ownDatastore[] = self::getAssetById($ds->id);
81
				}
82
			}
83
		}else{
84
			$this->__model = new DatastoreModel();
85
		}
86
	}
87
88
	/**
89
	 * Gets an existing asset by ID
90
	 *
91
	 * @param [type] $id
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
92
	 *
93
	 * @return void
94
	 */
95
	public static function getAssetById($id){
96
		$datastore = new self($id);
97
		$datastore->setAssetType($datastore->type);
98
		return $datastore;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $datastore returns the type Phpsa\Datastore\Datastore which is incompatible with the documented return type void.
Loading history...
99
	}
100
101
	public static function find($id){
102
		if(!is_array($id)){
103
			if(is_object($id)){
104
				return self::getAssetById($id->id);
105
			}
106
			return self::getAssetById($id);
107
		}
108
109
		if(is_array($id)){
0 ignored issues
show
introduced by
The condition is_array($id) is always true.
Loading history...
110
			$assets = [];
111
			foreach($id as $i){
112
				$assets[] = self::getAssetById($i);
113
			}
114
			return $assets;
115
		}
116
	}
117
118
	/**
119
	 * Gets a new asset instance
120
	 * @param string $type
121
	 * @param int $id
122
	 * @return \DF_Datastore
0 ignored issues
show
Bug introduced by
The type DF_Datastore 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...
123
	 */
124
	public static function getAsset($type, $id = false)
125
	{
126
		$ds = new self($id);
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type false; however, parameter $id of Phpsa\Datastore\Datastore::__construct() does only seem to accept integer, 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

126
		$ds = new self(/** @scrutinizer ignore-type */ $id);
Loading history...
127
		$ds->setAssetType($type);
128
		return $ds;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ds returns the type Phpsa\Datastore\Datastore which is incompatible with the documented return type DF_Datastore.
Loading history...
129
	}
130
131
132
	public function ownDatastore(){
133
		return ($this->ownDatastore)?$this->ownDatastore: array();
134
	}
135
136
	/**
137
	 * Sets the type of asset & maps identifier keys
138
	 * @param string $type
139
	 * @return DF_Datastore
0 ignored issues
show
Bug introduced by
The type Phpsa\Datastore\DF_Datastore 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...
140
	 */
141
	public function setAssetType($type)
142
	{
143
144
		$this->__asset = Asset::factory($type);
145
146
		foreach ($this->__asset as $k => $v)
147
		{
148
			if ($k != 'properties')
149
			{
150
				if ($k == 'value_equals')
151
				{
152
					$this->__value_equals = $v;
153
				}
154
				else if ($k == 'status_equals')
155
				{
156
					$this->__status_equals = $v;
157
				}
158
				else if ($k == 'start_date')
159
				{
160
					$this->__start_date = $v;
161
				}
162
				else if ($k == 'end_date')
163
				{
164
					$this->__end_date = $v;
165
				}
166
				else
167
				{
168
					$this->$k = (isset($this->$k)) ? $this->$k : $v;
169
				}
170
			}
171
		}
172
		$this->type = $type;
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
173
174
		$this->module = Helpers::getModule($type);
0 ignored issues
show
Bug Best Practice introduced by
The property module does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
175
176
		$this->setInternals();
177
178
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpsa\Datastore\Datastore which is incompatible with the documented return type Phpsa\Datastore\DF_Datastore.
Loading history...
179
	}
180
181
182
	/**
183
	 * Sets the internal mapping
184
	 * @todo - pehaps this should become protected ?
185
	 */
186
	public function setInternals()
187
	{
188
189
		foreach ($this->__asset->properties as $p => $v)
190
		{
191
192
			if (!isset($this->__asset_properties[$p]))
193
			{
194
				$this->__asset_properties[$p]['temp']					 = self::getAsset($this->__asset->properties[$p]['type']);
0 ignored issues
show
Bug introduced by
The property properties does not exist on boolean.
Loading history...
195
				$this->__asset_properties[$p]['temp']->name				 = (isset($this->__asset->properties[$p]['name'])) ? $this->__asset->properties[$p]['name'] : null;
196
				$this->__asset_properties[$p]['temp']->key				 = $p;
197
				$this->__asset_properties[$p]['temp']->private			 = (isset($this->__asset->properties[$p]['private'])) ? $this->__asset->properties[$p]['private'] : false; // accessibility
198
				$this->__asset_properties[$p]['temp']->value			 = (isset($this->__asset->properties[$p]['value'])) ? $this->__asset->properties[$p]['value'] : null; // the actual value of the property
199
				$this->__asset_properties[$p]['temp']->options			 = (isset($this->__asset->properties[$p]['options'])) ? $this->__asset->properties[$p]['options'] : null; // additional options specific to the property
200
				$this->__asset_properties[$p]['temp']->callback			 = (isset($this->__asset->properties[$p]['callback'])) ? $this->__asset->properties[$p]['callback'] : null; // additional options specific to the property
201
				$this->__asset_properties[$p]['temp']->meta				 = (isset($this->__asset->properties[$p]['meta'])) ? $this->__asset->properties[$p]['meta'] : null; // additional options specific to the property
202
				$this->__asset_properties[$p]['temp']->help				 = (isset($this->__asset->properties[$p]['help'])) ? $this->__asset->properties[$p]['help'] : null; // additional options specific to the property
203
				$this->__asset_properties[$p]['temp']->required			 = (isset($this->__asset->properties[$p]['required'])) ? $this->__asset->properties[$p]['required'] : true; // is the property required
204
				$this->__asset_properties[$p]['temp']->limit			 = (isset($this->__asset->properties[$p]['limit'])) ? $this->__asset->properties[$p]['limit'] : null; // additional options specific to the property
205
				$this->__asset_properties[$p]['temp']->warning			 = (isset($this->__asset->properties[$p]['warning'])) ? $this->__asset->properties[$p]['warning'] : null; // additional options specific to the property
206
				$this->__asset_properties[$p]['temp']->max_instances	 = (isset($this->__asset->properties[$p]['max_instances'])) ? $this->__asset->properties[$p]['max_instances'] : 0; // there can be only one
207
			}
208
		}
209
210
		// fitst check whether we have any datastore set
211
		if ($this->ownDatastore)
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->ownDatastore of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
212
		{
213
214
			// if it has a datastore, its easy - map the buggers
215
			$this->key = self::getKey($this->type);
0 ignored issues
show
Bug Best Practice introduced by
The property key does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
216
217
			foreach ($this->ownDatastore as $idx => $each)
218
			{
219
				// create a map to our property bean
220
				if ($each->namespace == 'property')
221
				{
222
					$this->__asset_properties[$each->key]	 = array('temp' => $each);
223
					@$this->ownDatastore[$idx]->required		 = (isset($this->__asset->properties[$each->key]['required'])) ? $this->__asset->properties[$each->key]['required'] : true;
224
					@$this->ownDatastore[$idx]->limit		 = (isset($this->__asset->properties[$each->key]['limit'])) ? $this->__asset->properties[$each->key]['limit'] : null;
225
					@$this->ownDatastore[$idx]->warning		 = (isset($this->__asset->properties[$each->key]['warning'])) ? $this->__asset->properties[$each->key]['warning'] : null;
226
					@$this->ownDatastore[$idx]->help			 = (isset($this->__asset->properties[$each->key]['help'])) ? $this->__asset->properties[$each->key]['help'] : null;
227
					@$this->ownDatastore[$idx]->max_instances = (isset($this->__asset->properties[$each->key]['max_instances'])) ? $this->__asset->properties[$each->key]['max_instances'] : 0;
228
					@$this->ownDatastore[$idx]->options = (isset($this->__asset->properties[$each->key]['options'])) ? $this->__asset->properties[$each->key]['options'] : null;
229
				}
230
			}
231
			//echo '<pre>$this->ownDatastore: '; print_r($this->ownDatastore); echo '</pre>'; die();
232
		}
233
		else
234
		{
235
			// nope - net to create some datastore beans to represent our properties
236
			foreach ($this->__asset->properties as $prop => $data)
237
			{
238
239
				// we need to create a temporary new bean to store new data
240
				$this->__asset_properties[$prop]['temp']				 = self::getAsset($this->__asset->properties[$prop]['type']);
241
				$this->__asset_properties[$prop]['temp']->name			 = (isset($this->__asset->properties[$prop]['name'])) ? $this->__asset->properties[$prop]['name'] : null;
242
				$this->__asset_properties[$prop]['temp']->key			 = $prop;
243
				$this->__asset_properties[$prop]['temp']->private		 = (isset($this->__asset->properties[$prop]['private'])) ? $this->__asset->properties[$prop]['private'] : false; // accessibility
244
				$this->__asset_properties[$prop]['temp']->value			 = (isset($this->__asset->properties[$prop]['value'])) ? $this->__asset->properties[$prop]['value'] : null; // the actual value of the property
245
				$this->__asset_properties[$prop]['temp']->options		 = (isset($this->__asset->properties[$prop]['options'])) ? $this->__asset->properties[$prop]['options'] : null; // additional options specific to the property
246
				$this->__asset_properties[$prop]['temp']->callback		 = (isset($this->__asset->properties[$prop]['callback'])) ? $this->__asset->properties[$prop]['callback'] : null; // additional options specific to the property
247
				$this->__asset_properties[$prop]['temp']->meta			 = (isset($this->__asset->properties[$prop]['meta'])) ? $this->__asset->properties[$prop]['meta'] : null; // additional options specific to the property
248
				$this->__asset_properties[$prop]['temp']->help			 = (isset($this->__asset->properties[$prop]['help'])) ? $this->__asset->properties[$prop]['help'] : null; // additional options specific to the property
249
				$this->__asset_properties[$prop]['temp']->required		 = (isset($this->__asset->properties[$prop]['required'])) ? $this->__asset->properties[$prop]['required'] : true; // is the property required
250
				$this->__asset_properties[$prop]['temp']->limit			 = (isset($this->__asset->properties[$prop]['limit'])) ? $this->__asset->properties[$prop]['limit'] : null; // additional options specific to the property
251
				$this->__asset_properties[$prop]['temp']->warning		 = (isset($this->__asset->properties[$prop]['warning'])) ? $this->__asset->properties[$prop]['warning'] : null; // additional options specific to the property
252
				$this->__asset_properties[$prop]['temp']->max_instances	 = (isset($this->__asset->properties[$prop]['max_instances'])) ? $this->__asset->properties[$prop]['max_instances'] : null; // there can be only one
253
254
			}
255
		}
256
	}
257
258
259
260
	/**
261
	 * Gets the Asset Key
262
	 * @param string $string
263
	 * @return string
264
	 */
265
	public static function getKey($string)
266
	{
267
		$new	 = Helpers::splitByCaps($string);
268
		$explode = explode(' ', $new);
269
270
		if (isset($explode[0]) && $explode[0] == 'Ams')
271
		{
272
			// drop the ams portion
273
			array_shift($explode);
274
		}
275
		// drop the last part too
276
		$last = array_pop($explode);
0 ignored issues
show
Unused Code introduced by
The assignment to $last is dead and can be removed.
Loading history...
277
		//lowercase the first part
278
		if (isset($explode[0]))
279
		{
280
			$explode[0] = strtolower($explode[0]);
281
		}
282
283
		return (count($explode) > 1) ? implode('', $explode) : $explode[0];
284
	}
285
286
	/**
287
	 * Setter / getter of asset property value,
288
	 * pass 1 param to get the value,
289
	 * pass 2 params to set the value
290
	 * @return mixed
291
	 * @throws Exception
292
	 */
293
	public function prop()
294
	{
295
		$num_args = func_num_args();
296
297
		// one arg, return prop by key
298
		// two args set prop by name to arg2
299
		switch ($num_args)
300
		{
301
			case 1:
302
				$prop = func_get_arg(0);
303
				if (isset($this->__asset_properties[$prop]))
304
				{
305
					// check whether this is new or existibng
306
					if (isset($this->__asset_properties[$prop]['temp']))
307
					{
308
						return $this->__asset_properties[$prop]['temp']->value;
309
					}
310
					else
311
					{
312
						return $this->ownDatastore[$this->__asset_properties[$prop]]->value;
313
					}
314
				}
315
				else
316
				{
317
					return false;
318
				}
319
				break;
320
321
			case 2:
322
				$prop	 = func_get_arg(0);
323
				$val	 = func_get_arg(1);
324
				if (isset($this->__asset_properties[$prop]))
325
				{
326
					// check whether this is new or existing
327
					if (isset($this->__asset_properties[$prop]['temp']))
328
					{
329
						$this->__asset_properties[$prop]['temp']->value = $val;
330
						// if value equals is set, set it too
331
332
						if ($this->__value_equals && $this->__value_equals == $prop)
333
						{
334
							$this->val(Helpers::callStatic($this->type, 'valueEquals', array($val)));
335
						}
336
						else if ($this->__status_equals && $this->__status_equals == $prop)
337
						{
338
							$this->status($val);
339
						}
340
						else if ($this->__start_date && $this->__start_date == $prop)
341
						{
342
							$this->start_date($val);
0 ignored issues
show
Bug introduced by
The method start_date() does not exist on Phpsa\Datastore\Datastore. ( Ignorable by Annotation )

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

342
							$this->/** @scrutinizer ignore-call */ 
343
              start_date($val);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
343
						}
344
						else if ($this->__end_date && $this->__end_date == $prop)
345
						{
346
							$this->end_date($val);
0 ignored issues
show
Bug introduced by
The method end_date() does not exist on Phpsa\Datastore\Datastore. ( Ignorable by Annotation )

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

346
							$this->/** @scrutinizer ignore-call */ 
347
              end_date($val);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
347
						}
348
					}
349
					else
350
					{
351
						$this->ownDatastore[$this->__asset_properties[$prop]]->value = $val;
352
						// if value equals is set, set it too
353
						if ($this->__value_equals && $this->__value_equals == $prop)
354
						{
355
							$this->val(Helpers::callStatic($this->type, 'valueEquals', array($val)));
356
						}
357
						else if ($this->__status_equals && $this->__status_equals == $prop)
358
						{
359
							$this->status($val);
360
						}
361
						else if ($this->__start_date && $this->__start_date == $prop)
362
						{
363
							$this->start_date($val);
364
						}
365
						else if ($this->__end_date && $this->__end_date == $prop)
366
						{
367
							$this->end_date($val);
368
						}
369
					}
370
					return $this;
371
				}
372
				else
373
				{
374
					throw new DatastoreException('The property "' . $prop . '" is not defined for the "' . $this->type . '" asset');
375
				}
376
				break;
377
378
			default:
379
				throw new DatastoreException('DF_Datastore::prop accepts either a property name, or a property and value');
380
		}
381
	}
382
383
	/**
384
	 *  shortcut to write to the asset's value property
385
	 * @return mixed
386
	 */
387
	public function val()
388
	{
389
		$num_args = func_num_args();
390
391
		switch ($num_args)
392
		{
393
			case 0:
394
				// return all props as beans
395
				return $this->value;
396
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
397
398
			default:
399
				$val		 = func_get_arg(0);
400
				$this->value = $val;
0 ignored issues
show
Bug Best Practice introduced by
The property value does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
401
		}
402
	}
403
404
	public function __toString()
405
	{
406
407
		return (string) $this->val();
408
	}
409
410
	/**
411
	 * Stores our asset
412
	 * @param DF_Datastore $asset
413
	 * @param Int $pid Parent Datastore id
414
	 */
415
	protected function __store($asset, $pid = null)
416
	{
417
418
		$class	 = new ReflectionClass($asset->__asset);
419
		$props	 = $class->getProperties(ReflectionProperty::IS_PUBLIC);
420
		$record = $asset->__model;
421
		$record->datastore_id = $pid;
422
423
		foreach ($props as $prop)
424
		{
425
			if (!in_array($prop->name, array('status_equals', 'properties','help','value_equals')))
426
			{
427
				$record->{$prop->name} = isset($asset->{$prop->name}) ? $asset->{$prop->name} : NULL;
428
			}
429
		}
430
431
		if ($asset->__status_equals)
432
		{
433
			$record->status = isset($record->{$asset->__status_equals})? $record->{$asset->__status_equals} : $this->prop($this->__status_equals);
434
		}
435
		if ($asset->__start_date)
436
		{
437
			$record->start_date = isset($record->{$asset->__start_date})? $record->{$asset->__start_date} : $this->prop($this->__start_date);
438
		}
439
		if ($asset->__end_date)
440
		{
441
			$record->end_date = isset($record->{$asset->__end_date})? $record->{$asset->__end_date} : $this->prop($this->__end_date);
442
		}
443
444
		$record->options = json_encode($record->options);
445
		$record->meta = json_encode($record->meta);
446
447
		$record->save();
448
449
		if ($asset->__asset_properties)
450
		{
451
			foreach ($asset->__asset_properties as $prop)
452
			{
453
				$this->__store($prop['temp'], $record->id);
454
			}
455
		}
456
		return $record->id;
457
	}
458
459
	/**
460
	 * Stores the asset
461
	 * @return int Datastore id
462
	 */
463
	public function store($parent = null)
464
	{
465
466
		return $this->__store($this, $parent);
467
	}
468
469
	/**
470
	 * Echos out the asset markup
471
	 * @param string $prop
472
	 * @param string $template
473
	 */
474
	public function render($prop, $template = false)
475
	{
476
		if (isset($this->__asset_properties[$prop]['temp']))
477
		{
478
			return $this->__asset_properties[$prop]['temp']->getMarkup($template);
479
		}
480
		else
481
		{
482
			if (isset($this->__asset_properties[$prop]))
483
			{
484
				return $this->ownDatastore[$this->__asset_properties[$prop]]->getMarkup($template);
485
			}
486
		}
487
	}
488
489
	/**
490
	 * Gets the current Datastore markup
491
	 * @param string $template
492
	 * @return string
493
	 */
494
	public function getMarkup($template = false)
495
	{
496
497
		$vars				 = $this->export();
498
		$vars['_unique_id']	 = uniqid();
499
500
		// we also want to know what asset this property belongs to
501
		$output = Helpers::callStatic($this->type, 'render', array($vars, $template));
502
		if (!$output)
503
		{
504
			return null;
505
		}
506
		return $output;
507
	}
508
509
510
	/**
511
	 * exports current Datastore to an array
512
	 * @return array
513
	 */
514
	public function export()
515
	{
516
517
		$class	 = new ReflectionClass($this->__asset);
518
		$props	 = $class->getProperties(ReflectionProperty::IS_PUBLIC);
519
520
521
522
		foreach ($props as $prop)
523
		{
524
525
			$data[$prop->name] = isset($this->{$prop->name}) ? $this->{$prop->name} : NULL;
526
		}
527
528
		if ($this->__status_equals)
529
		{
530
531
			$data['status'] = isset($data[$this->__status_equals])? $data[$this->__status_equals] : $this->prop($this->__status_equals);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $data seems to be defined by a foreach iteration on line 522. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
532
		}
533
		if ($this->__start_date)
534
		{
535
			$data['start_date'] = $data[$this->__start_date];
536
		}
537
		if ($this->__end_date)
538
		{
539
			$data['end_date'] = $data[$this->__end_date];
540
		}
541
542
		$data['id'] = $this->id;
543
544
		return $data;
545
	}
546
547
548
	/**
549
	 * Gets form element for a propery
550
	 * @param string $prop
551
	 * @param string $template
552
	 */
553
	public function form($prop, $template = false)
554
	{
555
		if (isset($this->__asset_properties[$prop]['temp']))
556
		{
557
			echo $this->__asset_properties[$prop]['temp']->getForm($template, $prop);
558
		}
559
		else
560
		{
561
			if (isset($this->__asset_properties[$prop]))
562
			{
563
				echo $this->ownDatastore[$this->__asset_properties[$prop]]->getForm($template, $prop);
564
			}
565
		}
566
	}
567
568
	/**
569
	 * Gets property form markup
570
	 * @param string $prop
571
	 * @param string $template
572
	 * @param array $_prop
573
	 * @return type
0 ignored issues
show
Bug introduced by
The type Phpsa\Datastore\type 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...
574
	 */
575
	public function returnForm($prop, $template = false, $_prop)
576
	{
577
578
		if (isset($this->__asset_properties[$prop]['temp']))
579
		{
580
			return $this->__asset_properties[$prop]['temp']->getForm($template, $_prop);
581
		}
582
		else
583
		{
584
			if (isset($this->__asset_properties[$prop]))
585
			{
586
587
				return $this->ownDatastore[$this->__asset_properties[$prop]]->getForm($template, $_prop);
588
			}
589
		}
590
	}
591
592
	public function getFieldValues(){
593
		$data = [];
594
		foreach(array_keys($this->__asset->properties) as $key){
0 ignored issues
show
Bug introduced by
The property properties does not exist on boolean.
Loading history...
595
			$data[$key] = $this->prop($key);
596
		}
597
		return $data;
598
	}
599
600
601
	/**
602
	 * Gets the form
603
	 * @param string $template
604
	 * @param array $_prop
605
	 * @return string
606
	 */
607
	public function getForm($template = false, $_prop = array())
608
	{
609
610
		$output = null;
611
		if ($this->namespace == 'asset')
0 ignored issues
show
Bug Best Practice introduced by
The property namespace does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
612
		{
613
			foreach ($this->__asset_properties as $prop => $val)
0 ignored issues
show
Bug introduced by
The expression $this->__asset_properties of type boolean is not traversable.
Loading history...
614
			{
615
				$output .= $this->returnForm($prop, false, $_prop);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $template of Phpsa\Datastore\Datastore::returnForm(). ( Ignorable by Annotation )

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

615
				$output .= $this->returnForm($prop, /** @scrutinizer ignore-type */ false, $_prop);
Loading history...
616
			}
617
		}
618
		else
619
		{
620
			return $this->propGetForm($template, $_prop);
0 ignored issues
show
Bug introduced by
It seems like $template can also be of type false; however, parameter $template of Phpsa\Datastore\Datastore::propGetForm() 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

620
			return $this->propGetForm(/** @scrutinizer ignore-type */ $template, $_prop);
Loading history...
621
		}
622
623
		if (!$output)
624
		{
625
			return null;
626
		}
627
		return $output;
628
	}
629
630
	/**
631
	 * Gets property form
632
	 * @param string $template
633
	 * @param array $_prop
634
	 * @return string
635
	 */
636
	public function propGetForm($template = false, $_prop = array())
637
	{
638
		$vars = $this->export();
639
640
		if (isset($_prop['unique_id']))
641
		{
642
			$vars['_unique_id'] = $_prop['unique_id'];
643
		}
644
		else
645
		{
646
			$vars['_unique_id'] = md5(uniqid(rand(), true)); //UUID ??
647
		}
648
649
		// we also want to know what asset this property belongs to
650
		$output = Helpers::callStatic($this->type, 'form', array($vars, $template));
651
		if (!$output)
652
		{
653
			return null;
654
		}
655
		return $output;
656
	}
657
658
	public function propGetValue($prop){
659
		dd($prop);
660
	}
661
662
	/**
663
	 * Injects a form into an asset
664
	 * Children asset instances
665
	 * @param string $uid
666
	 * @return string
667
	 */
668
	public function injectForm($uid)
669
	{
670
671
		$output = null;
672
		if ($uid)
673
		{
674
			$unique_id = md5($uid);
675
		}
676
		else
677
		{
678
			$unique_id = md5(uniqid(rand(), true));
679
		}
680
681
682
		foreach ($this->__asset_properties as $prop => $each)
0 ignored issues
show
Bug introduced by
The expression $this->__asset_properties of type boolean is not traversable.
Loading history...
683
		{
684
			if (isset($this->__asset_properties[$prop]['temp']))
685
			{
686
				$xvars				 = $this->__asset_properties[$prop]['temp']->export();
687
				$xvars['unique_id']	 = $unique_id;
688
689
				$output .= Helpers::callStatic($this->__asset_properties[$prop]['temp']->type, 'form', array($xvars, $this->type));
690
			}
691
			else
692
			{
693
				if (isset($this->__asset_properties[$prop]))
694
				{
695
					$xvars				 = $this->ownDatastore[$this->__asset_properties[$prop]]->export();
696
					$xvars['unique_id']	 = $unique_id;
697
698
					$output .= Helpers::callStatic($this->ownDatastore[$this->__asset_properties[$prop]]->type, 'form', array($xvars, $this->type));
699
				}
700
			}
701
		}
702
703
		// we also want to know what asset this property belongs to
704
		$output .= '<input type="hidden" class="asset-injector-input" data-type="' . $this->type . '" id="' . $unique_id . '" name="assetInjectionform[' . $this->type . '][' . $unique_id . '][id]" value="' . $this->id . '" />';
705
		if (!$output)
706
		{
707
			return null;
708
		}
709
		return $output;
710
	}
711
712
	public function hasMetadataForm(){
713
		if ($this->namespace == 'asset' && !$this->is_child){
0 ignored issues
show
Bug Best Practice introduced by
The property namespace does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property is_child does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
714
			return ($this->meta_description !== 'off' || $this->meta_keywords !== 'off');
0 ignored issues
show
Bug Best Practice introduced by
The property meta_keywords does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property meta_description does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
715
		}
716
		return false;
717
	}
718
719
	/**
720
	 *  gets the form necessary for building the meta data
721
	 * @return string
722
	 */
723
	public function getMetadataForm()
724
	{
725
		$output = null;
726
		// must be a parent asset
727
		if ($this->namespace == 'asset' && !$this->is_child)
0 ignored issues
show
Bug Best Practice introduced by
The property is_child does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property namespace does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
728
		{
729
			if ($this->meta_description !== 'off')
0 ignored issues
show
Bug Best Practice introduced by
The property meta_description does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
730
			{
731
				$data = array(
732
					'name'		 => 'Meta-Description',
733
					'key'		 => 'meta_description',
734
					'help'	 => 'You can associate a Meta-Description with this content. No more than 155 characters is considered optimal',
735
					'value'		 => $this->meta_description
736
				);
737
738
				$output .= Helpers::callStatic(ASSET::METATEXT, 'form', array($data, 'metatext'));
739
			}
740
741
			if ($this->meta_keywords !== 'off' /* &&  CONFIG->get('settings.allow_meta_keywords' ) */)
0 ignored issues
show
Bug Best Practice introduced by
The property meta_keywords does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
742
			{
743
				$data = array(
744
					'name'		 => 'Meta-Keywords',
745
					'key'		 => 'meta_keywords',
746
					'help'	 => 'You can associate Meta-Keywords with this content, with each keyword or key-phrase being seperated by a comma. <br/><b>Note :</b> There is evidence that suggests Keywords can hurt your SEO Ranking',
747
					'value'		 => $this->meta_keywords
748
				);
749
750
				$output .= Helpers::callStatic(ASSET::METATEXT, 'form', array($data, 'metatext'));
751
			}
752
		}
753
		if (!$output)
754
		{
755
			return null;
756
		}
757
		return $output;
758
	}
759
760
	public function hasDeveloperForm(){
761
		if ($this->namespace == 'asset' && !$this->is_child){
0 ignored issues
show
Bug Best Practice introduced by
The property namespace does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property is_child does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
762
			return ($this->page_js !== 'off' || $this->page_css !== 'off');
0 ignored issues
show
Bug Best Practice introduced by
The property page_js does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property page_css does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
763
		}
764
		return false;
765
	}
766
767
	/**
768
	 * gets the form necessary for building the styling and behaviour data
769
	 * @return string
770
	 */
771
	public function getDeveloperForm() :string
772
	{
773
		$output = null;
774
		// must be a parent asset
775
		if ($this->namespace == 'asset' && !$this->is_child)
0 ignored issues
show
Bug Best Practice introduced by
The property is_child does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property namespace does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
776
		{
777
			if ($this->page_css !== 'off')
0 ignored issues
show
Bug Best Practice introduced by
The property page_css does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
778
			{
779
				$data = array(
780
					'name'		 => 'Custom CSS',
781
					'key'		 => 'page_css',
782
					'help'	 	 => 'Custom css rules for this page display', // 'You can associate a Meta-Description with this content. No more than 155 characters is considered optimal',
783
					'value'		 => $this->page_css
784
				);
785
786
				$output .= Helpers::callStatic(ASSET::METATEXT, 'form', array($data, 'metatext'));
787
			}
788
789
			if ($this->page_js !== 'off' )
0 ignored issues
show
Bug Best Practice introduced by
The property page_js does not exist on Phpsa\Datastore\Datastore. Since you implemented __get, consider adding a @property annotation.
Loading history...
790
			{
791
				$data = array(
792
					'name'		 => 'Custom JS',
793
					'key'		 => 'page_js',
794
					'help'	 	 => 'custom javascript for this page display', // 'You can associate Meta-Keywords with this content, with each keyword or key-phrase being seperated by a comma. <br/><b>Note :</b> There is evidence that suggests Keywords can hurt your SEO Ranking',
795
					'value'		 => $this->page_js
796
				);
797
798
				$output .= Helpers::callStatic(ASSET::METATEXT, 'form', array($data, 'metatext'));
799
			}
800
		}
801
		if (!$output)
802
		{
803
			return null;
0 ignored issues
show
Bug Best Practice introduced by
The expression return null returns the type null which is incompatible with the type-hinted return string.
Loading history...
804
		}
805
		return $output;
806
	}
807
808
809
	/**
810
	 * Validates the current form
811
	 * @return boolean if the form is valid or not
812
	 */
813
	public function validate($request = null) :bool
814
	{
815
816
		$config = array();
817
		$messages = array();
818
		foreach ($this->__asset->properties as $key => $property)
0 ignored issues
show
Bug introduced by
The property properties does not exist on boolean.
Loading history...
819
		{
820
			if($property['type'] !== \Phpsa\Datastore\Ams\AutoCallBackAdderAsset::class && (empty($property['required']) || $property['required'] === true) )
821
			{
822
				$rules = empty($property['validation_rules']) ? 'required' : $property['validation_rules'];
823
				if(!empty($property['validation_messages'])){
824
					if(is_string($property['validation_messages'])){
825
						$messages[$key . '.required'] = $property['validation_messages'];
826
					}
827
				}
828
				$config[$key] = $rules;
829
			}
830
831
		}
832
833
		if ($config)
834
		{
835
			$validator = Validator::make($request, $config, $messages);
836
837
			if($validator->fails()){
838
				throw new ValidationException($validator);
839
			}
840
		}
841
		return true;
842
	}
843
844
	/**
845
	 * gets current datastore id
846
	 * @return int
847
	 */
848
	public function getId() :int
849
	{
850
		return $this->id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->id returns the type Phpsa\Datastore\record which is incompatible with the type-hinted return integer.
Loading history...
851
	}
852
853
	/**
854
	 * Gets the current datastore children
855
	 * @return array
856
	 */
857
	public function children() :array
858
	{
859
		$return = false;
860
861
		if ($this->ownDatastore)
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->ownDatastore of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
862
		{
863
			foreach ($this->ownDatastore as $child => $child_bean)
864
			{
865
				if ($child_bean->namespace == 'asset')
866
				{
867
					$return[] = $child_bean;
868
				}
869
			}
870
		}
871
		return $return;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $return returns the type false which is incompatible with the type-hinted return array.
Loading history...
872
	}
873
874
	/**
875
	 * does this datastore have this property?
876
	 * @param string $prop
877
	 * @return bool
878
	 */
879
	public function propExists($prop) :bool
880
	{
881
		if (isset($this->__asset_properties[$prop]))
882
		{
883
			return true;
884
		}
885
		return false;
886
	}
887
888
889
	/**
890
	 * Populates the current Datastore with data passedin array
891
	 * @param array $post_data
892
	 * @return $this
893
	 */
894
	public function populateAsset($post_data = array())
895
	{
896
897
		foreach ($post_data as $k => $v)
898
		{
899
			switch ($k)
900
			{
901
				case 'meta_description':
902
				case 'meta_keywords':
903
					$this->$k = strip_tags($v);
904
					break;
905
906
				case 'page_css':
907
				case 'page_js':
908
					$this->$k = $v;
909
					break;
910
911
				case '_meta_':
912
					foreach ($v as $pr => $pv)
913
					{
914
						if ($this->propExists($pr))
915
						{
916
							if (isset($this->__asset_properties[$pr]))
917
							{
918
								// check whether this is new or existibng
919
								if (isset($this->__asset_properties[$pr]['temp']))
920
								{
921
									$this->__asset_properties[$pr]['temp']->meta = $pv;
922
								}
923
								else
924
								{
925
									$this->ownDatastore[$this->__asset_properties[$pr]]->meta = $pv;
926
								}
927
							}
928
						}
929
					}
930
931
				default:
932
					// if the property exists, populate the props
933
					if ($this->propExists($k))
934
					{
935
						$this->prop($k, $v);
936
					}
937
			}
938
		}
939
940
		return $this;
941
	}
942
943
	/**
944
	 * gets the avaialble status options
945
	 *
946
	 * @return array|bool
947
	 */
948
	public function statusOptions()
949
	{
950
		return ($this->__status_equals) ? $this->__asset_properties[$this->__status_equals]['temp']->options : false;
951
	}
952
953
	/**
954
	 * Gets the readable version of the status
955
	 *
956
	 * @return string
957
	 */
958
	public function getStatusValue() :string
959
	{
960
		$options = $this->statusOptions();
961
		return ($options && Helpers::isAssocArray($options) && isset($options[$this->status])) ? $options[$this->status] : $this->status;
0 ignored issues
show
Bug introduced by
It seems like $options can also be of type true; however, parameter $array of Phpsa\Datastore\Helpers::isAssocArray() does only seem to accept array, 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

961
		return ($options && Helpers::isAssocArray(/** @scrutinizer ignore-type */ $options) && isset($options[$this->status])) ? $options[$this->status] : $this->status;
Loading history...
962
	}
963
964
	/**
965
	 * Get / set the current status value
966
	 *
967
	 * @return mixed
968
	 */
969
	public function status()
970
	{
971
		$num_args = func_num_args();
972
973
		 switch ($num_args)
974
		 {
975
			case 0:
976
				// return all props as beans
977
				return $this->status();
978
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
979
980
			default:
981
				$val = func_get_arg(0);
982
				$this->status = $val;
0 ignored issues
show
Bug Best Practice introduced by
The property status does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
983
		 }
984
	}
985
986
	/**
987
	 * Checks to see if the current asset is actaully active
988
	 *
989
	 * @return bool
990
	 */
991
	public function statusIsActive() :bool
992
	{
993
		if($this->__status_equals){
994
995
			if(!isset($this->__asset->properties[$this->__status_equals]['published'])){
0 ignored issues
show
Bug introduced by
The property properties does not exist on boolean.
Loading history...
996
				throw new DatastoreException("Statused assests need a published option in the asset definition");
997
			}
998
999
			$activeOptions = $this->__asset->properties[$this->__status_equals]['published'];
1000
1001
			return is_array($activeOptions) ? in_array($this->status, $activeOptions) : $activeOptions === $this->status;
1002
1003
		}
1004
		return true;
1005
	}
1006
1007
	/**
1008
	 * Gets the url path for the current type
1009
	 *
1010
	 * @return string
1011
	 */
1012
	public function urlPath() : string
1013
	{
1014
		return Helpers::getPath($this->type);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Phpsa\Datastore\H...s::getPath($this->type) returns the type void which is incompatible with the type-hinted return string.
Loading history...
Bug introduced by
Are you sure the usage of Phpsa\Datastore\Helpers::getPath($this->type) targeting Phpsa\Datastore\Helpers::getPath() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1015
	}
1016
1017
	/**
1018
	 * Gets our view name
1019
	 *
1020
	 * @param string $prefix
1021
	 *
1022
	 * @return string
1023
	 */
1024
	public function getViewName($prefix = 'frontend.ams') :string
1025
	{
1026
		return $this->__asset::getAssetView($prefix);
1027
	}
1028
1029
	/**
1030
	 * Magic method to get from teh model if we not included it already
1031
	 *
1032
	 * @param string $name
1033
	 *
1034
	 * @return mixed
1035
	 */
1036
	public function __get($name)
1037
	{
1038
		return $this->propExists($name) ? $this->prop($name) : $this->__model->{$name};
1039
	}
1040
1041
	/**
1042
	 * gets the title of the asset
1043
	 *
1044
	 * @return string
1045
	 */
1046
	public function getTitleField() :string
1047
	{
1048
		return $this->__value_equals;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->__value_equals returns the type boolean which is incompatible with the type-hinted return string.
Loading history...
1049
	}
1050
1051
}
1052