Completed
Push — dev ( 9c7928...5573ef )
by Nicolas
02:08
created

FieldEntry_relationship::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 45
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 45
rs 8.8571
cc 1
eloc 27
nc 1
nop 0
1
<?php
2
	/*
3
	Copyright: Deux Huit Huit 2014
4
	LICENCE: MIT http://deuxhuithuit.mit-license.org;
5
	*/
6
7
	if (!defined('__IN_SYMPHONY__')) die('<h2>Symphony Error</h2><p>You cannot directly access this file</p>');
8
9
	require_once(TOOLKIT . '/class.field.php');
10
	require_once(EXTENSIONS . '/entry_relationship_field/lib/class.cacheablefetch.php');
11
	require_once(EXTENSIONS . '/entry_relationship_field/lib/class.erfxsltutilities.php');
12
	
13
	/**
14
	 *
15
	 * Field class that will represent relationships between entries
16
	 * @author Deux Huit Huit
17
	 *
18
	 */
19
	class FieldEntry_relationship extends Field
20
	{
21
		
22
		/**
23
		 *
24
		 * Name of the field table
25
		 *  @var string
26
		 */
27
		const FIELD_TBL_NAME = 'tbl_fields_entry_relationship';
28
		
29
		/**
30
		 * 
31
		 * Separator char for values
32
		 *  @var string
33
		 */
34
		const SEPARATOR = ',';
35
		
36
		
37
		/**
38
		 *
39
		 * Current recursive level of output
40
		 *  @var int
41
		 */
42
		protected $recursiveLevel = 1;
43
		
44
		/**
45
		 *
46
		 * Parent's maximum recursive level of output
47
		 *  @var int
48
		 */
49
		protected $recursiveDeepness = null;
50
		
51
		/* Cacheable Managers */
52
		private $sectionManager;
53
		private $entryManager;
54
		
55
		/**
56
		 *
57
		 * Constructor for the oEmbed Field object
58
		 */
59
		public function __construct()
60
		{
61
			// call the parent constructor
62
			parent::__construct();
63
			// set the name of the field
64
			$this->_name = __('Entry Relationship');
65
			// permits to make it required
66
			$this->_required = true;
67
			// permits the make it show in the table columns
68
			$this->_showcolumn = true;
69
			// permits association
70
			$this->_showassociation = true;
71
			// current recursive level
72
			$this->recursiveLevel = 1;
73
			// parent's maximum recursive level of output
74
			$this->recursiveDeepness = null;
75
			// set as not required by default
76
			$this->set('required', 'no');
77
			// show association by default
78
			$this->set('show_association', 'yes');
79
			// no sections
80
			$this->set('sections', null);
81
			// no max deepness
82
			$this->set('deepness', null);
83
			// no included elements
84
			$this->set('elements', null);
85
			// no modes
86
			$this->set('mode', null);
87
			$this->set('mode_table', null);
88
			$this->set('mode_header', null);
89
			$this->set('mode_footer', null);
90
			// no limit
91
			$this->set('min_entries', null);
92
			$this->set('max_entries', null);
93
			// all permissions
94
			$this->set('allow_new', 'yes');
95
			$this->set('allow_edit', 'yes');
96
			$this->set('allow_link', 'yes');
97
			$this->set('allow_delete', 'no');
98
			// display options
99
			$this->set('allow_collapse', 'yes');
100
			$this->set('show_header', 'yes');
101
			$this->sectionManager = new CacheableFetch('SectionManager');
102
			$this->entryManager = new CacheableFetch('EntryManager');
103
		}
104
105
		public function isSortable()
106
		{
107
			return false;
108
		}
109
110
		public function canFilter()
111
		{
112
			return true;
113
		}
114
		
115
		public function canPublishFilter()
116
		{
117
			return false;
118
		}
119
120
		public function canImport()
121
		{
122
			return false;
123
		}
124
125
		public function canPrePopulate()
126
		{
127
			return false;
128
		}
129
		
130
		public function mustBeUnique()
131
		{
132
			return false;
133
		}
134
135
		public function allowDatasourceOutputGrouping()
136
		{
137
			return false;
138
		}
139
140
		public function requiresSQLGrouping()
141
		{
142
			return false;
143
		}
144
145
		public function allowDatasourceParamOutput()
146
		{
147
			return true;
148
		}
149
150
		/**
151
		 * @param string $name
152
		 */
153
		public function getInt($name)
154
		{
155
			return General::intval($this->get($name));
156
		}
157
158
		/**
159
		 * Check if a given property is == 'yes'
160
		 * @param string $name
161
		 * @return bool
162
		 *  True if the current field's value is 'yes'
163
		 */
164
		public function is($name)
165
		{
166
			return $this->get($name) == 'yes';
167
		}
168
169
		/**
170
		 * @return bool
171
		 *  True if the current field is required
172
		 */
173
		public function isRequired()
174
		{
175
			return $this->is('required');
176
		}
177
178
		public static function getEntries(array $data)
179
		{
180
			return array_map(array('General', 'intval'), array_filter(array_map(trim, explode(self::SEPARATOR, $data['entries']))));
181
		}
182
183
		/* ********** INPUT AND FIELD *********** */
184
185
186
		/**
187
		 * 
188
		 * Validates input
189
		 * Called before <code>processRawFieldData</code>
190
		 * @param $data
191
		 * @param $message
192
		 * @param $entry_id
193
		 */
194
		public function checkPostFieldData($data, &$message, $entry_id=NULL)
195
		{
196
			$message = NULL;
197
			$required = $this->isRequired();
198
			
199
			if ($required && (!is_array($data) || count($data) == 0 || strlen($data['entries']) < 1)) {
200
				$message = __("'%s' is a required field.", array($this->get('label')));
201
				return self::__MISSING_FIELDS__;
202
			}
203
			
204
			$entries = $data['entries'];
205
			
206
			if (!is_array($entries)) {
207
				$entries = static::getEntries($data);
208
			}
209
			
210
			// enforce limits only if required or it contains data
211
			if ($required || count($entries) > 0) {
212
				if ($this->getInt('min_entries') > 0 && $this->getInt('min_entries') > count($entries)) {
213
					$message = __("'%s' requires a minimum of %s entries.", array($this->get('label'), $this->getInt('min_entries')));
214
					return self::__INVALID_FIELDS__;
215
				} else if ($this->getInt('max_entries') > 0 && $this->getInt('max_entries') < count($entries)) {
216
					$message = __("'%s' can not contains more than %s entries.", array($this->get('label'), $this->getInt('max_entries')));
217
					return self::__INVALID_FIELDS__;
218
				}
219
			}
220
			
221
			return self::__OK__;
222
		}
223
224
225
		/**
226
		 *
227
		 * Process data before saving into database.
228
		 *
229
		 * @param array $data
230
		 * @param int $status
231
		 * @param boolean $simulate
232
		 * @param int $entry_id
233
		 *
234
		 * @return Array - data to be inserted into DB
235
		 */
236
		public function processRawFieldData($data, &$status, &$message = null, $simulate = false, $entry_id = null)
237
		{
238
			$status = self::__OK__;
239
			$entries = null;
240
			
241
			if (!is_array($data) && !is_string($data)) {
242
				return null;
243
			}
244
			
245
			if (isset($data['entries'])) {
246
				$entries = $data['entries'];
247
			}
248
			else if (is_string($data)) {
249
				$entries = $data;
250
			}
251
			
252
			$row = array(
253
				'entries' => $entries
254
			);
255
			
256
			// return row
257
			return $row;
258
		}
259
260
		/**
261
		 * This function permits parsing different field settings values
262
		 *
263
		 * @param array $settings
264
		 *	the data array to initialize if necessary.
265
		 */
266
		public function setFromPOST(Array &$settings = array())
267
		{
268
			// call the default behavior
269
			parent::setFromPOST($settings);
270
271
			// declare a new setting array
272
			$new_settings = array();
273
274
			// set new settings
275
			$new_settings['sections'] = is_array($settings['sections']) ? 
276
				implode(self::SEPARATOR, $settings['sections']) : 
277
				(is_string($settings['sections']) ? $settings['sections'] : null);
278
				
279
			$new_settings['show_association'] = $settings['show_association'] == 'yes' ? 'yes' : 'no';
280
			$new_settings['deepness'] = General::intval($settings['deepness']);
281
			$new_settings['deepness'] = $new_settings['deepness'] < 1 ? null : $new_settings['deepness'];
282
			$new_settings['elements'] = empty($settings['elements']) ? null : $settings['elements'];
283
			$new_settings['mode'] = empty($settings['mode']) ? null : $settings['mode'];
284
			$new_settings['mode_table'] = empty($settings['mode_table']) ? null : $settings['mode_table'];
285
			$new_settings['mode_header'] = empty($settings['mode_header']) ? null : $settings['mode_header'];
286
			$new_settings['mode_footer'] = empty($settings['mode_footer']) ? null : $settings['mode_footer'];
287
			$new_settings['allow_new'] = $settings['allow_new'] == 'yes' ? 'yes' : 'no';
288
			$new_settings['allow_edit'] = $settings['allow_edit'] == 'yes' ? 'yes' : 'no';
289
			$new_settings['allow_link'] = $settings['allow_link'] == 'yes' ? 'yes' : 'no';
290
			$new_settings['allow_delete'] = $settings['allow_delete'] == 'yes' ? 'yes' : 'no';
291
			$new_settings['allow_collapse'] = $settings['allow_collapse'] == 'yes' ? 'yes' : 'no';
292
			$new_settings['show_header'] = $settings['show_header'] == 'yes' ? 'yes' : 'no';
293
			
294
			// save it into the array
295
			$this->setArray($new_settings);
296
		}
297
298
299
		/**
300
		 *
301
		 * Validates the field settings before saving it into the field's table
302
		 */
303
		public function checkFields(Array &$errors, $checkForDuplicates)
304
		{
305
			$parent = parent::checkFields($errors, $checkForDuplicates);
306
			if ($parent != self::__OK__) {
307
				return $parent;
308
			}
309
			
310
			$sections = $this->get('sections');
311
			
312
			if (empty($sections)) {
313
				$errors['sections'] = __('At least one section must be chosen');
314
			}
315
316
			return (!empty($errors) ? self::__ERROR__ : self::__OK__);
317
		}
318
319
		/**
320
		 *
321
		 * Save field settings into the field's table
322
		 */
323
		public function commit()
324
		{
325
			// if the default implementation works...
326
			if(!parent::commit()) return false;
327
			
328
			$id = $this->get('id');
329
			
330
			// exit if there is no id
331
			if($id == false) return false;
332
			
333
			// we are the child, with multiple parents
334
			$child_field_id = $id;
335
			
336
			// delete associations, only where we are the child
337
			self::removeSectionAssociation($child_field_id);
338
			
339
			$sections = $this->getSelectedSectionsArray();
340
			
341
			foreach ($sections as $key => $sectionId) {
342
				if (empty($sectionId)) {
343
					continue;
344
				}
345
				$parent_section_id = General::intval($sectionId);
346
				$parent_section = SectionManager::fetch($sectionId);
347
				$fields = $parent_section->fetchVisibleColumns();
348
				if (empty($fields)) {
349
					// no visible field, revert to all
350
					$fields = $parent_section->fetchFields();
351
				}
352
				$parent_field_id = current(array_keys($fields));
353
				// create association
354
				SectionManager::createSectionAssociation(
355
					$parent_section_id,
356
					$child_field_id,
357
					$parent_field_id,
358
					$this->get('show_association') == 'yes'
359
				);
360
			}
361
			
362
			// declare an array contains the field's settings
363
			$settings = array(
364
				'sections' => $this->get('sections'),
365
				'show_association' => $this->get('show_association'),
366
				'deepness' => $this->get('deepness'),
367
				'elements' => $this->get('elements'),
368
				'mode' => $this->get('mode'),
369
				'mode_table' => $this->get('mode_table'),
370
				'mode_header' => $this->get('mode_header'),
371
				'mode_footer' => $this->get('mode_footer'),
372
				'min_entries' => $this->get('min_entries'),
373
				'max_entries' => $this->get('max_entries'),
374
				'allow_new' => $this->get('allow_new'),
375
				'allow_edit' => $this->get('allow_edit'),
376
				'allow_link' => $this->get('allow_link'),
377
				'allow_delete' => $this->get('allow_delete'),
378
				'allow_collapse' => $this->get('allow_collapse'),
379
				'show_header' => $this->get('show_header'),
380
			);
381
382
			return FieldManager::saveSettings($id, $settings);
383
		}
384
385
		/**
386
		 *
387
		 * This function allows Fields to cleanup any additional things before it is removed
388
		 * from the section.
389
		 * @return boolean
390
		 */
391
		public function tearDown()
392
		{
393
			self::removeSectionAssociation($this->get('id'));
394
			return parent::tearDown();
395
		}
396
		
397
		/**
398
		 * Generates the where filter for searching by entry id
399
		 *
400
		 * @param string $value
401
		 * @param @optional string $col
402
		 * @param @optional boolean $andOperation
403
		 */
404
		public function generateWhereFilter($value, $col = 'd', $andOperation = true)
405
		{
406
			$junction = $andOperation ? 'AND' : 'OR';
407
			if (!$value) {
408
				return "{$junction} (`{$col}`.`entries` IS NULL)";
409
			}
410
			return " {$junction} (`{$col}`.`entries` = '{$value}' OR 
411
					`{$col}`.`entries` LIKE '{$value},%' OR 
412
					`{$col}`.`entries` LIKE '%,{$value}' OR 
413
					`{$col}`.`entries` LIKE '%,{$value},%')";
414
		}
415
416
		/**
417
		 * Fetch the number of associated entries for a particular entry id
418
		 *
419
		 * @param string $value
420
		 */
421
		public function fetchAssociatedEntryCount($value)
422
		{
423
			if (!$value) {
424
				return 0;
425
			}
426
			$join = sprintf(" INNER JOIN `tbl_entries_data_%s` AS `d` ON `e`.id = `d`.`entry_id`", $this->get('id'));
427
			$where = $this->generateWhereFilter($value);
428
			
429
			$entries = EntryManager::fetch(null, $this->get('parent_section'), null, 0, $where, $join, false, false, array());
430
			
431
			return count($entries);
432
		}
433
		
434
		public function fetchAssociatedEntrySearchValue($data, $field_id = null, $parent_entry_id = null)
435
		{
436
			return $parent_entry_id;
437
		}
438
		
439
		public function findRelatedEntries($entry_id)
440
		{
441
			$joins = '';
442
			$where = '';
443
			$this->buildDSRetrievalSQL(array($entry_id), $joins, $where, true);
444
			
445
			$entries = EntryManager::fetch(null, $this->get('parent_section'), null, 0, $where, $joins, false, false, array());
446
			
447
			$ids = array();
448
			foreach ($entries as $key => $e) {
449
				$ids[] = $e['id'];
450
			}
451
			return $ids;
452
		}
453
		
454
		public function prepareAssociationsDrawerXMLElement(Entry $e, array $parent_association, $prepolutate = '')
455
		{
456
			$currentSection = SectionManager::fetch($parent_association['child_section_id']);
457
			$visibleCols = $currentSection->fetchVisibleColumns();
458
			$outputFieldId = current(array_keys($visibleCols));
459
			$outputField = FieldManager::fetch($outputFieldId);
460
			
461
			$value = $outputField->prepareReadableValue($e->getData($outputFieldId), $e->get('id'), true, __('None'));
462
			
463
			$li = new XMLElement('li');
464
			$li->setAttribute('class', 'field-' . $this->get('type'));
465
			$a = new XMLElement('a', strip_tags($value));
466
			$a->setAttribute('href', SYMPHONY_URL . '/publish/' . $parent_association['handle'] . '/edit/' . $e->get('id') . '/');
467
			$li->appendChild($a);
468
469
			return $li;
470
		}
471
		
472
		/**
473
		 * @param string $joins
474
		 * @param string $where
475
		 */
476
		public function buildDSRetrievalSQL($data, &$joins, &$where, $andOperation = false)
477
		{
478
			$field_id = $this->get('id');
479
			
480
			// REGEX filtering is a special case, and will only work on the first item
481
			// in the array. You cannot specify multiple filters when REGEX is involved.
482
			if (self::isFilterRegex($data[0])) {
483
				return $this->buildRegexSQL($data[0], array('entries'), $joins, $where);
484
			}
485
			
486
			$this->_key++;
487
			
488
			$where .= ' AND (1=' . ($andOperation ? '1' : '0') . ' ';
489
			
490
			$joins .= "
491
				INNER JOIN
492
					`tbl_entries_data_{$field_id}` AS `t{$field_id}_{$this->_key}`
493
					ON (`e`.`id` = `t{$field_id}_{$this->_key}`.`entry_id`)
494
			";
495
			
496
			foreach ($data as $value) {
497
				$where .= $this->generateWhereFilter($this->cleanValue($value), "t{$field_id}_{$this->_key}", $andOperation);
498
			}
499
			
500
			$where .= ')';
501
			
502
			return true; // this tells the DS Manager that filters are OK!!
503
		}
504
505
		/* ******* EVENTS ******* */
506
507
		public function getExampleFormMarkup()
508
		{
509
			$label = Widget::Label($this->get('label'));
510
			$label->appendChild(Widget::Input('fields['.$this->get('element_name').'][entries]', null, 'hidden'));
511
512
			return $label;
513
		}
514
515
516
		/* ******* DATA SOURCE ******* */
517
		
518
		private function fetchEntry($eId, $elements = array())
519
		{
520
			$entry = EntryManager::fetch($eId, null, 1, 0, null, null, false, true, $elements, false);
521
			if (!is_array($entry) || count($entry) !== 1) {
522
				return null;
523
			}
524
			return $entry[0];
525
		}
526
		
527
		public function fetchIncludableElements()
528
		{
529
			$label = $this->get('element_name');
530
			$elements = array_filter(array_map(trim, explode(self::SEPARATOR, trim($this->get('elements')))));
531
			$includedElements = array($label . ': *');
532
			foreach ($elements as $elem) {
533
				$elem = trim($elem);
534
				if ($elem !== '*') {
535
					$includedElements[] = $label . ': ' . $elem;
536
				}
537
			}
538
			return $includedElements;
539
		}
540
		
541
		/**
542
		 * Appends data into the XML tree of a Data Source
543
		 * @param $wrapper
544
		 * @param $data
545
		 */
546
		public function appendFormattedElement(&$wrapper, $data, $encode = false, $mode = null, $entry_id = null)
547
		{
548
			if(!is_array($data) || empty($data)) return;
549
550
			// root for all values
551
			$root = new XMLElement($this->get('element_name'));
552
			
553
			// selected items
554
			$entries = static::getEntries($data);
555
			
556
			// current linked entries
557
			$root->setAttribute('entries', $data['entries']);
558
			
559
			// available sections
560
			$root->setAttribute('sections', $this->get('sections'));
561
			
562
			// included elements
563
			$elements = static::parseElements($this);
564
			
565
			// DS mode
566
			if (!$mode) {
567
				$mode = '*';
568
			}
569
			
570
			$parentDeepness = General::intval($this->recursiveDeepness);
571
			$deepness = General::intval($this->get('deepness'));
572
			
573
			// both deepnesses are defined and parent restricts more
574
			if ($parentDeepness > 0 && $deepness > 0 && $parentDeepness < $deepness) {
575
				$deepness = $parentDeepness;
576
			}
577
			// parent is defined, current is not
578
			else if ($parentDeepness > 0 && $deepness < 1) {
579
				$deepness = $parentDeepness;
580
			}
581
			
582
			// cache recursive level because recursion might
583
			// change its value later on.
584
			$recursiveLevel = $this->recursiveLevel;
585
			
586
			// build entries
587
			foreach ($entries as $eId) {
588
				$item = new XMLElement('item');
589
				// output id
590
				$item->setAttribute('id', $eId);
591
				// output recursive level
592
				$item->setAttribute('level', $recursiveLevel);
593
				$item->setAttribute('max-level', $deepness);
594
				
595
				// max recursion check
596
				if ($deepness < 1 || $recursiveLevel < $deepness) {
597
					// current entry, without data
598
					$entry = $this->fetchEntry($eId);
599
					
600
					// entry not found...
601
					if (!$entry || empty($entry)) {
602
						$error = new XMLElement('error');
603
						$error->setAttribute('id', $eId);
604
						$error->setValue(__('Error: entry `%s` not found', array($eId)));
605
						$root->prependChild($error);
606
						continue;
607
					}
608
					
609
					// fetch section infos
610
					$sectionId = $entry->get('section_id');
611
					$section = $this->sectionsManager->fetch($sectionId);
612
					$sectionName = $section->get('handle');
613
					// cache fields info
614
					if (!isset($section->er_field_cache)) {
615
						$section->er_field_cache = $section->fetchFields();
616
					}
617
					
618
					// set section related attributes
619
					$item->setAttribute('section-id', $sectionId);
620
					$item->setAttribute('section', $sectionName);
621
					
622
					// Get the valid elements for this section only
623
					$validElements = $elements[$sectionName];
624
					
625
					// adjust the mode for the current section
626
					$curMode = $mode;
627
					
628
					// remove section name from current mode, i.e sectionName.field
629
					if (preg_match('/^(' . $sectionName . '\.)(.*)$/sU', $curMode)) {
630
						$curMode = preg_replace('/^' . $sectionName . '\./sU', '', $curMode);
631
					}
632
					// remove section name from current mode, i.e sectionName
633
					else if (preg_match('/^(' . $sectionName . ')$/sU', $curMode)) {
634
						$curMode = '*';
635
					}
636
					// section name was not found in mode
637
					else if ($curMode != '*') {
638
						// mode forbids this section
639
						$validElements = null;
640
					}
641
					
642
					// this section is not selected, bail out
643
					if (!is_array($validElements)) {
644
						$item->setAttribute('forbidden-by', $curMode);
645
						$root->appendChild($item);
646
						continue;
647
					}
648
					
649
					// selected fields for fetching
650
					$sectionElements = array();
0 ignored issues
show
Unused Code introduced by
$sectionElements is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
651
					
652
					// everything is allowed
653
					if (in_array('*', $validElements)) {
654
						if ($curMode !== '*') {
655
							// get only the mode
656
							$sectionElements = array($curMode);
657
						}
658
						else {
659
							// setting null = get all
660
							$sectionElements = null;
661
						}
662
					}
663
					// only use valid elements
664
					else {
665
						if ($curMode !== '*') {
666
							// is this field allowed ?
667
							if (self::isFieldIncluded($curMode, $validElements)) {
668
								// get only the mode
669
								$sectionElements = array($curMode);
670
							}
671
							else {
672
								// $curMode selects something outside of
673
								// the valid elements: select nothing
674
								$sectionElements = array();
675
							}
676
						}
677
						else {
678
							// use field's valid elements
679
							$sectionElements = $validElements;
680
						}
681
					}
682
					
683
					if (is_array($sectionElements) && empty($sectionElements)) {
684
						$item->setAttribute('selection-empty', 'yes');
685
						$item->setAttribute('forbidden-by', $curMode);
686
						$root->appendChild($item);
687
						continue;
688
					}
689
					
690
					// current entry again, but with data and the allowed schema
691
					$entry = $this->fetchEntry($eId, $sectionElements);
692
					
693
					// cache the entry data
694
					$entryData = $entry->getData();
695
					
696
					// for each field returned for this entry...
697
					foreach ($entryData as $fieldId => $data) {
698
						$filteredData = array_filter($data, function ($value) {
699
							return $value != null;
700
						});
701
						
702
						if (empty($filteredData)) {
703
							continue;
704
						}
705
						
706
						$field = $section->er_field_cache[$fieldId];
707
						$fieldName = $field->get('element_name');
708
						$fieldCurMode = self::extractMode($fieldName, $curMode);
709
						
710
						$parentIncludableElement = self::getSectionElementName($fieldName, $validElements);
711
						$parentIncludableElementMode = self::extractMode($fieldName, $parentIncludableElement);
712
						
713
						// Special treatments for ERF
714
						if ($field instanceof FieldEntry_relationship) {
715
							// Increment recursive level
716
							$field->recursiveLevel = $recursiveLevel + 1;
717
							$field->recursiveDeepness = $deepness;
718
						}
719
						
720
						$submodes = null;
0 ignored issues
show
Unused Code introduced by
$submodes is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
721
						if ($parentIncludableElementMode == null) {
722
							if ($fieldCurMode == null) {
723
								$submodes = null;
724
							}
725
							else {
726
								$submodes = array($fieldCurMode);
727
							}
728
						}
729
						else {
730
							if ($fieldCurMode == null || $fieldCurMode == $parentIncludableElementMode) {
731
								$submodes = array($parentIncludableElementMode);
732
							}
733
							else {
734
								$item->setAttribute('selection-mode-empty', 'yes');
735
								$submodes = array();
736
							}
737
						}
738
						
739
						// current selection does not specify a mode
740 View Code Duplication
						if ($submodes == null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
741
							$submodes = array_map(function ($fieldIncludableElement) use ($fieldName) {
742
								return FieldEntry_relationship::extractMode($fieldName, $fieldIncludableElement);
743
							}, $field->fetchIncludableElements());
744
						}
745
						
746
						foreach ($submodes as $submode) {
747
							$field->appendFormattedElement($item, $data, $encode, $submode, $eId);
748
						}
749
					}
750
					// output current mode
751
					$item->setAttribute('matched-element', $curMode);
752
					// no field selected
753
					if (is_array($sectionElements) && empty($sectionElements)) {
754
						$item->setAttribute('empty-selection', 'yes');
755
					}
756
				}
757
				// append item when done
758
				$root->appendChild($item);
759
			} // end each entries
760
			
761
			// output mode for this field
762
			$root->setAttribute('data-source-mode', $mode);
763
			$root->setAttribute('field-included-elements', $this->get('elements'));
764
			
765
			// add all our data to the wrapper;
766
			$wrapper->appendChild($root);
767
			
768
			// clean up
769
			$this->recursiveLevel = 1;
770
			$this->recursiveDeepness = null;
771
		}
772
773
		public function getParameterPoolValue(array $data, $entry_id = null)
774
		{
775
			if(!is_array($data) || empty($data)) return;
776
			return static::getEntries($data);
777
		}
778
779
		/* ********* Utils *********** */
780
		
781
		/**
782
		 * Return true if $fieldName is allowed in $sectionElements
783
		 * @param string $fieldName
784
		 * @param string $sectionElements
785
		 * @return bool
786
		 */
787
		public static function isFieldIncluded($fieldName, $sectionElements)
788
		{
789
			return self::getSectionElementName($fieldName, $sectionElements) !== null;
790
		}
791
792
		public static function getSectionElementName($fieldName, $sectionElements)
793
		{
794
			if (is_array($sectionElements)) {
795
				foreach ($sectionElements as $element) {
796
					if ($element == '*') {
797
						return $fieldName;
798
					}
799
					if ($fieldName == $element || preg_match('/^' . $fieldName . '\s*:/sU', $element)) {
800
						return $element;
801
					}
802
				}
803
			}
804
			return null;
805
		}
806
		
807
		public static function parseElements($field)
808
		{
809
			$elements = array();
810
			$exElements = array_map(trim, explode(self::SEPARATOR, $field->get('elements')));
811
			
812
			if (in_array('*', $exElements)) {
813
				$sections = array_map(trim, explode(self::SEPARATOR, $field->get('sections')));
814
				$sections = SectionManager::fetch($sections);
815
				return array_reduce($sections, function ($result, $section) {
816
					$result[$section->get('handle')] = array('*');
817
					return $result;
818
				}, array());
819
			}
820
			
821
			foreach ($exElements as $value) {
822
				if (!$value) {
823
					continue;
824
				}
825
				// sectionName.fieldName or sectionName.*
826
				$parts = array_map(trim, explode('.', $value));
827
				// first time seeing this section
828
				if (!isset($elements[$parts[0]])) {
829
					$elements[$parts[0]] = array();
830
				}
831
				// we have a value after the dot
832
				if (isset($parts[1]) && !!$parts[1]) {
833
					$elements[$parts[0]][] = $parts[1];
834
				}
835
				// sectionName only
836
				else if (!isset($parts[1])) {
837
					$elements[$parts[0]][] = '*';
838
				}
839
			}
840
			
841
			return $elements;
842
		}
843
844
		public static function extractMode($fieldName, $mode)
845
		{
846
			$pattern = '/^' . $fieldName . '\s*:\s*/s';
847
			if (!preg_match($pattern, $mode)) {
848
				return null;
849
			}
850
			$mode = preg_replace($pattern, '', $mode, 1);
851
			if ($mode === '*') {
852
				return null;
853
			}
854
			return $mode;
855
		}
856
857
		/**
858
		 * @param string $prefix
859
		 * @param string $name
860
		 * @param @optional bool $multiple
861
		 */
862
		private function createFieldName($prefix, $name, $multiple = false)
863
		{
864
			$name = "fields[$prefix][$name]";
865
			if ($multiple) {
866
				$name .= '[]';
867
			}
868
			return $name;
869
		}
870
		
871
		/**
872
		 * @param string $name
873
		 */
874
		private function createSettingsFieldName($name, $multiple = false)
875
		{
876
			return $this->createFieldName($this->get('sortorder'), $name, $multiple);
877
		}
878
		
879
		/**
880
		 * @param string $name
881
		 */
882
		private function createPublishFieldName($name, $multiple = false)
883
		{
884
			return $this->createFieldName($this->get('element_name'), $name, $multiple);
885
		}
886
		
887
		private function getSelectedSectionsArray()
888
		{
889
			$selectedSections = $this->get('sections');
890
			if (!is_array($selectedSections)) {
891
				if (is_string($selectedSections) && strlen($selectedSections) > 0) {
892
					$selectedSections = explode(self::SEPARATOR, $selectedSections);
893
				}
894
				else {
895
					$selectedSections = array();
896
				}
897
			}
898
			return $selectedSections;
899
		}
900
		
901
		private function buildSectionSelect($name)
902
		{
903
			$sections = SectionManager::fetch();
904
			$options = array();
905
			$selectedSections = $this->getSelectedSectionsArray();
906
			
907
			foreach ($sections as $section) {
908
				$driver = $section->get('id');
909
				$selected = in_array($driver, $selectedSections);
910
				$options[] = array($driver, $selected, $section->get('name'));
911
			}
912
			
913
			return Widget::Select($name, $options, array('multiple' => 'multiple'));
914
		} 
915
		
916
		private function appendSelectionSelect(&$wrapper)
917
		{
918
			$name = $this->createSettingsFieldName('sections', true);
919
920
			$input = $this->buildSectionSelect($name);
921
			$input->setAttribute('class', 'entry_relationship-sections');
922
923
			$label = Widget::Label();
924
			$label->setAttribute('class', 'column');
925
926
			$label->setValue(__('Available sections %s', array($input->generate())));
927
928
			$wrapper->appendChild($label);
929
		}
930
931
		private function createEntriesList($entries)
932
		{
933
			$wrap = new XMLElement('div');
934
			$wrapperClass = 'frame collapsible orderable';
935
			if (count($entries) > 0) {
936
				$wrapperClass .= ' empty';
937
			}
938
			if (!$this->is('show_header')) {
939
				$wrapperClass .= ' no-header';
940
			}
941
			$wrap->setAttribute('class', $wrapperClass);
942
			
943
			$list = new XMLElement('ul');
944
			$list->setAttribute('class', '');
945
			if ($this->is('allow_collapse')) {
946
				$list->setAttribute('data-collapsible', '');
947
			}
948
			
949
			$wrap->appendChild($list);
950
			
951
			return $wrap;
952
		}
953
		
954
		private function createEntriesHiddenInput($data)
955
		{
956
			$hidden = new XMLElement('input', null, array(
957
				'type' => 'hidden',
958
				'name' => $this->createPublishFieldName('entries'),
959
				'value' => $data['entries']
960
			));
961
			
962
			return $hidden;
963
		}
964
		
965
		private function createActionBarMenu($sections)
966
		{
967
			$wrap = new XMLElement('div');
968
			$actionBar = '';
969
			$modeFooter = $this->get('mode_footer');
970
			if ($modeFooter) {
971
				$section = $this->sectionManager->fetch($this->get('parent_section'));
972
				$actionBar = ERFXSLTUTilities::processXSLT($this, null, $section->get('handle'), null, 'mode_footer', isset($_REQUEST['debug']), 'field');
973
			}
974
			if (empty($actionBar)) {
975
				$fieldset = new XMLElement('fieldset');
976
				$fieldset->setAttribute('class', 'single');
977
				if ($this->is('allow_new') || $this->is('allow_link')) {
978
					$selectWrap = new XMLElement('div');
979
					$selectWrap->appendChild(new XMLElement('span', __('Related section: ')));
980
					$options = array();
981
					foreach ($sections as $section) {
982
						$options[] = array($section->get('handle'), false, $section->get('name'));
983
					}
984
					$select = Widget::Select('', $options, array('class' => 'sections'));
985
					$selectWrap->appendChild($select);
986
					$fieldset->appendChild($selectWrap);
987
				}
988 View Code Duplication
				if ($this->is('allow_new')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
989
					$fieldset->appendChild(new XMLElement('button', __('Create new'), array(
990
						'type' => 'button',
991
						'class' => 'create',
992
						'data-create' => '',
993
					)));
994
				}
995 View Code Duplication
				if ($this->is('allow_link')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
996
					$fieldset->appendChild(new XMLElement('button', __('Link to entry'), array(
997
						'type' => 'button',
998
						'class' => 'link',
999
						'data-link' => '',
1000
					)));
1001
				}
1002
				$wrap->appendChild($fieldset);
1003
			}
1004
			else {
1005
				$wrap->setValue($actionBar);
1006
			}
1007
			
1008
			return $wrap;
1009
		}
1010
1011
		/* ********* UI *********** */
1012
		
1013
		/**
1014
		 *
1015
		 * Builds the UI for the field's settings when creating/editing a section
1016
		 * @param XMLElement $wrapper
1017
		 * @param array $errors
1018
		 */
1019
		public function displaySettingsPanel(&$wrapper, $errors=NULL)
1020
		{
1021
			/* first line, label and such */
1022
			parent::displaySettingsPanel($wrapper, $errors);
1023
			
1024
			// sections
1025
			$sections = new XMLElement('fieldset');
1026
			
1027
			$this->appendSelectionSelect($sections);
1028
			if (is_array($errors) && isset($errors['sections'])) {
1029
				$sections = Widget::Error($sections, $errors['sections']);
1030
			}
1031
			$wrapper->appendChild($sections);
1032
			
1033
			// elements
1034
			$elements = new XMLElement('div');
1035
			$element = Widget::Label();
1036
			$element->setValue(__('Included elements in Data Sources and Backend Templates'));
1037
			$element->setAttribute('class', 'column');
1038
			$element->appendChild(Widget::Input($this->createSettingsFieldName('elements'), $this->get('elements'), 'text', array(
1039
				'class' => 'entry_relationship-elements'
1040
			)));
1041
			$elements->appendChild($element);
1042
			$elements_choices = new XMLElement('ul', null, array('class' => 'tags singular entry_relationship-field-choices'));
1043
			
1044
			$elements->appendChild($elements_choices);
1045
			$wrapper->appendChild($elements);
1046
			
1047
			// limit entries
1048
			$limits = new XMLElement('fieldset');
1049
			$limits->appendChild(new XMLElement('legend', __('Limits')));
1050
			$limits_cols = new XMLElement('div');
1051
			$limits_cols->setAttribute('class', 'three columns');
1052
			// min
1053
			$limit_min = Widget::Label();
1054
			$limit_min->setValue(__('Minimum count of entries in this field'));
1055
			$limit_min->setAttribute('class', 'column');
1056
			$limit_min->appendChild(Widget::Input($this->createSettingsFieldName('min_entries'), $this->get('min_entries'), 'number', array(
1057
				'min' => 0,
1058
				'max' => 99999
1059
			)));
1060
			$limits_cols->appendChild($limit_min);
1061
			// max
1062
			$limit_max = Widget::Label();
1063
			$limit_max->setValue(__('Maximum count of entries in this field'));
1064
			$limit_max->setAttribute('class', 'column');
1065
			$limit_max->appendChild(Widget::Input($this->createSettingsFieldName('max_entries'), $this->get('max_entries'), 'number', array(
1066
				'min' => 0,
1067
				'max' => 99999
1068
			)));
1069
			$limits_cols->appendChild($limit_max);
1070
			
1071
			// deepness
1072
			$deepness = Widget::Label();
1073
			$deepness->setValue(__('Maximum level of recursion in Data Sources'));
1074
			$deepness->setAttribute('class', 'column');
1075
			$deepness->appendChild(Widget::Input($this->createSettingsFieldName('deepness'), $this->get('deepness'), 'number', array(
1076
				'min' => 0,
1077
				'max' => 99
1078
			)));
1079
			$limits_cols->appendChild($deepness);
1080
			$limits->appendChild($limits_cols);
1081
			$wrapper->appendChild($limits);
1082
			
1083
			// xsl
1084
			$xsl = new XMLElement('fieldset');
1085
			$xsl->appendChild(new XMLElement('legend', __('Backend XSL templates options')));
1086
			$xsl_cols = new XMLElement('div');
1087
			$xsl_cols->setAttribute('class', 'four columns');
1088
			
1089
			// xsl mode
1090
			$xslmode = Widget::Label();
1091
			$xslmode->setValue(__('XSL mode for entries content template'));
1092
			$xslmode->setAttribute('class', 'column');
1093
			$xslmode->appendChild(Widget::Input($this->createSettingsFieldName('mode'), $this->get('mode'), 'text'));
1094
			$xsl_cols->appendChild($xslmode);
1095
			// xsl header mode
1096
			$xslmodetable = Widget::Label();
1097
			$xslmodetable->setValue(__('XSL mode for entries header template'));
1098
			$xslmodetable->setAttribute('class', 'column');
1099
			$xslmodetable->appendChild(Widget::Input($this->createSettingsFieldName('mode_header'), $this->get('mode_header'), 'text'));
1100
			$xsl_cols->appendChild($xslmodetable);
1101
			// xsl table mode
1102
			$xslmodetable = Widget::Label();
1103
			$xslmodetable->setValue(__('XSL mode for publish table value'));
1104
			$xslmodetable->setAttribute('class', 'column');
1105
			$xslmodetable->appendChild(Widget::Input($this->createSettingsFieldName('mode_table'), $this->get('mode_table'), 'text'));
1106
			$xsl_cols->appendChild($xslmodetable);
1107
			// xsl action bar mode
1108
			$xslmodetable = Widget::Label();
1109
			$xslmodetable->setValue(__('XSL mode for publish action bar'));
1110
			$xslmodetable->setAttribute('class', 'column');
1111
			$xslmodetable->appendChild(Widget::Input($this->createSettingsFieldName('mode_footer'), $this->get('mode_footer'), 'text'));
1112
			$xsl_cols->appendChild($xslmodetable);
1113
			
1114
			$xsl->appendChild($xsl_cols);
1115
			$wrapper->appendChild($xsl);
1116
			
1117
			// permissions
1118
			$permissions = new XMLElement('fieldset');
1119
			$permissions->appendChild(new XMLElement('legend', __('Permissions')));
1120
			$permissions_cols = new XMLElement('div');
1121
			$permissions_cols->setAttribute('class', 'four columns');
1122
			$permissions_cols->appendChild($this->createCheckbox('allow_new', 'Show new button'));
1123
			$permissions_cols->appendChild($this->createCheckbox('allow_edit', 'Show edit button'));
1124
			$permissions_cols->appendChild($this->createCheckbox('allow_link', 'Show link button'));
1125
			$permissions_cols->appendChild($this->createCheckbox('allow_delete', 'Show delete button'));
1126
			$permissions->appendChild($permissions_cols);
1127
			$wrapper->appendChild($permissions);
1128
			
1129
			// display options
1130
			$display = new XMLElement('fieldset');
1131
			$display->appendChild(new XMLElement('legend', __('Display options')));
1132
			$display_cols = new XMLElement('div');
1133
			$display_cols->setAttribute('class', 'four columns');
1134
			$display_cols->appendChild($this->createCheckbox('allow_collapse', 'Allow content collapsing'));
1135
			$display_cols->appendChild($this->createCheckbox('show_header', 'Show the header box before entries templates'));
1136
			$display->appendChild($display_cols);
1137
			$wrapper->appendChild($display);
1138
			
1139
			// assoc
1140
			$assoc = new XMLElement('fieldset');
1141
			$assoc->appendChild(new XMLElement('legend', __('Associations')));
1142
			$assoc_cols = new XMLElement('div');
1143
			$assoc_cols->setAttribute('class', 'three columns');
1144
			$this->appendShowAssociationCheckbox($assoc_cols);
1145
			$assoc->appendChild($assoc_cols);
1146
			$wrapper->appendChild($assoc);
1147
			
1148
			// footer
1149
			$this->appendStatusFooter($wrapper);
1150
		}
1151
		
1152
		/**
1153
		 * @param string $fieldName
1154
		 * @param string $text
1155
		 */
1156
		private function createCheckbox($fieldName, $text) {
1157
			$chk = Widget::Label();
1158
			$chk->setAttribute('class', 'column');
1159
			$attrs = null;
1160
			if ($this->get($fieldName) == 'yes') {
1161
				$attrs = array('checked' => 'checked');
1162
			}
1163
			$chk->appendChild(Widget::Input($this->createSettingsFieldName($fieldName), 'yes', 'checkbox', $attrs));
1164
			$chk->setValue(__($text));
1165
			return $chk;
1166
		}
1167
1168
		/**
1169
		 *
1170
		 * Builds the UI for the publish page
1171
		 * @param XMLElement $wrapper
1172
		 * @param mixed $data
1173
		 * @param mixed $flagWithError
1174
		 * @param string $fieldnamePrefix
1175
		 * @param string $fieldnamePostfix
1176
		 */
1177
		public function displayPublishPanel(&$wrapper, $data=NULL, $flagWithError=NULL, $fieldnamePrefix=NULL, $fieldnamePostfix=NULL, $entry_id = null)
1178
		{
1179
			$entriesId = array();
1180
			$sectionsId = $this->getSelectedSectionsArray();
1181
			
1182
			if ($data['entries'] != null) {
1183
				$entriesId = static::getEntries($data);
1184
			}
1185
			
1186
			$sectionsId = array_map(array('General', 'intval'), $sectionsId);
1187
			$sections = SectionManager::fetch($sectionsId);
1188
			
1189
			$label = Widget::Label($this->get('label'));
1190
			$notes = '';
1191
			
1192
			// min note
1193
			if ($this->getInt('min_entries') > 0) {
1194
				$notes .= __('Minimum number of entries: <b>%s</b>. ', array($this->get('min_entries')));
1195
			}
1196
			// max note
1197
			if ($this->getInt('max_entries') > 0) {
1198
				$notes .= __('Maximum number of entries: <b>%s</b>. ', array($this->get('max_entries')));
1199
			}
1200
			// not required note
1201
			if (!$this->isRequired()) {
1202
				$notes .= __('Optional');
1203
			}
1204
			// append notes
1205
			if ($notes) {
1206
				$label->appendChild(new XMLElement('i', $notes));
1207
			}
1208
			
1209
			// label error management
1210
			if ($flagWithError != NULL) {
1211
				$wrapper->appendChild(Widget::Error($label, $flagWithError));
1212
			} else {
1213
				$wrapper->appendChild($label);
1214
			}
1215
			
1216
			$wrapper->appendChild($this->createEntriesList($entriesId));
1217
			$wrapper->appendChild($this->createActionBarMenu($sections));
1218
			$wrapper->appendChild($this->createEntriesHiddenInput($data));
1219
			$wrapper->setAttribute('data-value', $data['entries']);
1220
			$wrapper->setAttribute('data-field-id', $this->get('id'));
1221
			$wrapper->setAttribute('data-field-label', $this->get('label'));
1222
			$wrapper->setAttribute('data-min', $this->get('min_entries'));
1223
			$wrapper->setAttribute('data-max', $this->get('max_entries'));
1224
			if (isset($_REQUEST['debug'])) {
1225
				$wrapper->setAttribute('data-debug', true);
1226
			}
1227
		}
1228
1229
		/**
1230
		 * @param integer $count
1231
		 */
1232
		private static function formatCount($count)
1233
		{
1234
			if ($count == 0) {
1235
				return __('No item');
1236
			} else if ($count == 1) {
1237
				return __('1 item');
1238
			}
1239
			return __('%s items', array($count));
1240
		}
1241
1242
		/**
1243
		 *
1244
		 * Return a plain text representation of the field's data
1245
		 * @param array $data
1246
		 * @param int $entry_id
1247
		 */
1248
		public function prepareTextValue($data, $entry_id = null)
1249
		{
1250
			if ($entry_id == null || !is_array($data) || empty($data)) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $entry_id of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
1251
				return '';
1252
			}
1253
			return $data['entries'];
1254
		}
1255
1256
		/**
1257
		 * Format this field value for display as readable text value.
1258
		 *
1259
		 * @param array $data
1260
		 *  an associative array of data for this string. At minimum this requires a
1261
		 *  key of 'value'.
1262
		 * @param integer $entry_id (optional)
1263
		 *  An option entry ID for more intelligent processing. Defaults to null.
1264
		 * @param string $defaultValue (optional)
1265
		 *  The value to use when no plain text representation of the field's data
1266
		 *  can be made. Defaults to null.
1267
		 * @return string
1268
		 *  the readable text summary of the values of this field instance.
1269
		 */
1270
		public function prepareReadableValue($data, $entry_id = null, $truncate = false, $defaultValue = 'None')
1271
		{
1272
			if ($entry_id == null || !is_array($data) || empty($data)) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $entry_id of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
1273
				return __($defaultValue);
1274
			}
1275
			$entries = static::getEntries($data);
1276
			$realEntries = array();
1277
			foreach ($entries as $entryId) {
1278
				$e = EntryManager::fetch($entryId);
1279
				if (is_array($e) && !empty($e)) {
1280
					$realEntries = array_merge($realEntries, $e);
1281
				}
1282
			}
1283
			$count = count($entries);
1284
			$realCount = count($realEntries);
1285
			if ($count === $realCount) {
1286
				return self::formatCount($count);
1287
			}
1288
			return self::formatCount($realCount) . ' (' . self::formatCount($count - $realCount) . ' not found)';
1289
		}
1290
1291
		/**
1292
		 * Format this field value for display in the publish index tables.
1293
		 *
1294
		 * @param array $data
1295
		 *  an associative array of data for this string. At minimum this requires a
1296
		 *  key of 'value'.
1297
		 * @param XMLElement $link (optional)
1298
		 *  an XML link structure to append the content of this to provided it is not
1299
		 *  null. it defaults to null.
1300
		 * @param integer $entry_id (optional)
1301
		 *  An option entry ID for more intelligent processing. defaults to null
1302
		 * @return string
1303
		 *  the formatted string summary of the values of this field instance.
1304
		 */
1305
		public function prepareTableValue($data, XMLElement $link = null, $entry_id = null)
1306
		{
1307
			$value = $this->prepareReadableValue($data, $entry_id, false, __('None'));
1308
1309
			if ($link) {
1310
				$link->setValue($value);
1311
				return $link->generate();
1312
			}
1313
			else if ($entry_id != null && $this->get('mode_table')) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $entry_id of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
1314
				$entries = static::getEntries($data);
1315
				$cellcontent = '';
1316
				foreach ($entries as $child_entry_id) {
1317
					$entry = current($this->entryManager->fetch($child_entry_id));
1318
					$section = $this->sectionManager->fetch($entry->get('section_id'));
1319
					$content = ERFXSLTUTilities::processXSLT($this, $entry, $section->get('handle'), $section->fetchFields(), 'mode_table', isset($_REQUEST['debug']));
1320
					if ($content) {
1321
						$cellcontent .= $content;
1322
					}
1323
				}
1324
				
1325
				if (General::strlen(trim($cellcontent))) {
1326
					return $cellcontent;
1327
				}
1328
			}
1329
1330
			return $value;
1331
		}
1332
1333
		/* ********* SQL Data Definition ************* */
1334
1335
		/**
1336
		 *
1337
		 * Creates table needed for entries of individual fields
1338
		 */
1339
		public function createTable()
1340
		{
1341
			$id = $this->get('id');
1342
1343
			return Symphony::Database()->query("
1344
				CREATE TABLE `tbl_entries_data_$id` (
1345
					`id` int(11) 		unsigned NOT NULL AUTO_INCREMENT,
1346
					`entry_id` 			int(11) unsigned NOT NULL,
1347
					`entries` 			text COLLATE utf8_unicode_ci NULL,
1348
					PRIMARY KEY  (`id`),
1349
					UNIQUE KEY `entry_id` (`entry_id`)
1350
				) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
1351
			");
1352
		}
1353
1354
		/**
1355
		 * Creates the table needed for the settings of the field
1356
		 */
1357
		public static function createFieldTable()
1358
		{
1359
			$tbl = self::FIELD_TBL_NAME;
1360
1361
			return Symphony::Database()->query("
1362
				CREATE TABLE IF NOT EXISTS `$tbl` (
1363
					`id` 				int(11) unsigned NOT NULL AUTO_INCREMENT,
1364
					`field_id` 			int(11) unsigned NOT NULL,
1365
					`sections`			varchar(255) NULL COLLATE utf8_unicode_ci,
1366
					`show_association` 	enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes',
1367
					`deepness` 			int(2) unsigned NULL,
1368
					`elements` 			varchar(1024) NULL COLLATE utf8_unicode_ci,
1369
					`mode`				varchar(50) NULL COLLATE utf8_unicode_ci,
1370
					`mode_table`		varchar(50) NULL COLLATE utf8_unicode_ci DEFAULT NULL,
1371
					`mode_header`		varchar(50) NULL COLLATE utf8_unicode_ci DEFAULT NULL,
1372
					`mode_footer`		varchar(50) NULL COLLATE utf8_unicode_ci DEFAULT NULL,
1373
					`min_entries`		int(5) unsigned NULL,
1374
					`max_entries`		int(5) unsigned NULL,
1375
					`allow_edit` 		enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes',
1376
					`allow_new` 		enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes',
1377
					`allow_link` 		enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes',
1378
					`allow_delete` 		enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'no',
1379
					`allow_collapse` 	enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes',
1380
					`show_header` 		enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes',
1381
					PRIMARY KEY (`id`),
1382
					UNIQUE KEY `field_id` (`field_id`)
1383
				) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
1384
			");
1385
		}
1386
		
1387
		public static function update_102()
1388
		{
1389
			$tbl = self::FIELD_TBL_NAME;
1390
			$sql = "
1391
				ALTER TABLE `$tbl`
1392
					ADD COLUMN `allow_edit` enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes',
1393
					ADD COLUMN `allow_new` enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes',
1394
					ADD COLUMN `allow_link` enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes'
1395
					AFTER `max_entries`
1396
			";
1397
			$addColumns = Symphony::Database()->query($sql);
1398
			if (!$addColumns) {
1399
				return false;
1400
			}
1401
1402
			$fields = FieldManager::fetch(null, null, null, 'id', 'entry_relationship');
1403
			if (!empty($fields) && is_array($fields)) {
1404
				foreach ($fields as $fieldId => $field) {
1405
					$sql = "ALTER TABLE `tbl_entries_data_$fieldId` MODIFY `entries` TEXT";
1406
					if (!Symphony::Database()->query($sql)) {
1407
						throw new Exception(__('Could not update table `tbl_entries_data_%s`.', array($fieldId)));
1408
					}
1409
				}
1410
			}
1411
			return true;
1412
		}
1413
		
1414
		public static function update_103()
1415
		{
1416
			$tbl = self::FIELD_TBL_NAME;
1417
			$sql = "
1418
				ALTER TABLE `$tbl`
1419
					ADD COLUMN `allow_delete` enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'no'
1420
						AFTER `allow_link`
1421
			";
1422
			return Symphony::Database()->query($sql);
1423
		}
1424
		
1425
		public static function update_200()
1426
		{
1427
			$tbl = self::FIELD_TBL_NAME;
1428
			$sql = "
1429
				ALTER TABLE `$tbl`
1430
					ADD COLUMN `allow_collapse` enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes'
1431
						AFTER `allow_delete`,
1432
					ADD COLUMN `mode_table` varchar(50) NULL COLLATE utf8_unicode_ci DEFAULT NULL
1433
						AFTER `mode`,
1434
					ADD COLUMN `mode_header` varchar(50) NULL COLLATE utf8_unicode_ci DEFAULT NULL
1435
						AFTER `mode_table`,
1436
					ADD COLUMN `show_header` enum('yes','no') NOT NULL COLLATE utf8_unicode_ci DEFAULT 'yes'
1437
						AFTER `allow_collapse`,
1438
					ADD COLUMN `mode_footer` varchar(50) NULL COLLATE utf8_unicode_ci DEFAULT NULL
1439
						AFTER `mode_header`
1440
			";
1441
			return Symphony::Database()->query($sql);
1442
		}
1443
		
1444
		/**
1445
		 *
1446
		 * Drops the table needed for the settings of the field
1447
		 */
1448
		public static function deleteFieldTable()
1449
		{
1450
			$tbl = self::FIELD_TBL_NAME;
1451
			
1452
			return Symphony::Database()->query("
1453
				DROP TABLE IF EXISTS `$tbl`
1454
			");
1455
		}
1456
		
1457
		private static function removeSectionAssociation($child_field_id)
1458
		{
1459
			return Symphony::Database()->delete('tbl_sections_association', "`child_section_field_id` = {$child_field_id}");
1460
		}
1461
	}