Completed
Push — master ( 5c161a...b70884 )
by Fabien
52:39
created
Classes/Processor/ContentObjectProcessor.php 1 patch
Indentation   +112 added lines, -112 removed lines patch added patch discarded remove patch
@@ -23,116 +23,116 @@
 block discarded – undo
23 23
  */
24 24
 class ContentObjectProcessor implements SingletonInterface
25 25
 {
26
-    /**
27
-     * @param ProcessContentDataSignalArguments $signalArguments
28
-     * @return array
29
-     */
30
-    public function processRelations(ProcessContentDataSignalArguments $signalArguments)
31
-    {
32
-        $contentObject = $signalArguments->getContentObject();
33
-        $fieldNameAndPath = $signalArguments->getFieldNameAndPath();
34
-        $contentData = $signalArguments->getContentData();
35
-        $savingBehavior = $signalArguments->getSavingBehavior();
36
-
37
-        if ($savingBehavior !== SavingBehavior::REPLACE) {
38
-            $contentData = $this->appendOrRemoveRelations($contentObject, $fieldNameAndPath, $contentData, $savingBehavior);
39
-            $signalArguments->setContentData($contentData);
40
-        }
41
-
42
-        return array($signalArguments);
43
-    }
44
-
45
-    /**
46
-     * @param Content $object
47
-     * @param $fieldNameAndPath
48
-     * @param array $contentData
49
-     * @param string $savingBehavior
50
-     * @return array
51
-     */
52
-    protected function appendOrRemoveRelations(Content $object, $fieldNameAndPath, array $contentData, $savingBehavior)
53
-    {
54
-        foreach ($contentData as $fieldName => $values) {
55
-            $resolvedObject = $this->getContentObjectResolver()->getObject($object, $fieldNameAndPath);
56
-
57
-            if (Tca::table($resolvedObject)->field($fieldName)->hasMany()) {
58
-                // true means CSV values must be converted to array.
59
-                if (!is_array($values)) {
60
-                    $values = GeneralUtility::trimExplode(',', $values);
61
-                }
62
-                $relatedValues = $this->getRelatedValues($object, $fieldNameAndPath, $fieldName);
63
-
64
-                foreach ($values as $value) {
65
-                    $appendOrRemove = $savingBehavior . 'Relations';
66
-                    $relatedValues = $this->$appendOrRemove($value, $relatedValues);
67
-                }
68
-
69
-                $contentData[$fieldName] = $relatedValues;
70
-            }
71
-        }
72
-        return $contentData;
73
-    }
74
-
75
-    /**
76
-     * @param $value
77
-     * @param array $relatedValues
78
-     * @return array
79
-     */
80
-    protected function appendRelations($value, array $relatedValues)
81
-    {
82
-        if (!in_array($value, $relatedValues)) {
83
-            $relatedValues[] = $value;
84
-        }
85
-        return $relatedValues;
86
-    }
87
-
88
-    /**
89
-     * @param $value
90
-     * @param array $relatedValues
91
-     * @return array
92
-     */
93
-    protected function removeRelations($value, array $relatedValues)
94
-    {
95
-        if (in_array($value, $relatedValues)) {
96
-            $key = array_search($value, $relatedValues);
97
-            unset($relatedValues[$key]);
98
-        }
99
-        return $relatedValues;
100
-    }
101
-
102
-    /**
103
-     * @param Content $object
104
-     * @param string $fieldNameAndPath
105
-     * @param string $fieldName
106
-     * @return array
107
-     */
108
-    protected function getRelatedValues(Content $object, $fieldNameAndPath, $fieldName)
109
-    {
110
-        $values = [];
111
-        $relatedContentObjects = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, $fieldName);
112
-
113
-        if (is_array($relatedContentObjects)) {
114
-            /** @var Content $relatedContentObject */
115
-            foreach ($relatedContentObjects as $relatedContentObject) {
116
-                $values[] = $relatedContentObject->getUid();
117
-            }
118
-        }
119
-
120
-        return $values;
121
-    }
122
-
123
-    /**
124
-     * @return ContentObjectResolver|object
125
-     */
126
-    protected function getContentObjectResolver()
127
-    {
128
-        return GeneralUtility::makeInstance(ContentObjectResolver::class);
129
-    }
130
-
131
-    /**
132
-     * @return FieldPathResolver|object
133
-     */
134
-    protected function getFieldPathResolver()
135
-    {
136
-        return GeneralUtility::makeInstance(FieldPathResolver::class);
137
-    }
26
+	/**
27
+	 * @param ProcessContentDataSignalArguments $signalArguments
28
+	 * @return array
29
+	 */
30
+	public function processRelations(ProcessContentDataSignalArguments $signalArguments)
31
+	{
32
+		$contentObject = $signalArguments->getContentObject();
33
+		$fieldNameAndPath = $signalArguments->getFieldNameAndPath();
34
+		$contentData = $signalArguments->getContentData();
35
+		$savingBehavior = $signalArguments->getSavingBehavior();
36
+
37
+		if ($savingBehavior !== SavingBehavior::REPLACE) {
38
+			$contentData = $this->appendOrRemoveRelations($contentObject, $fieldNameAndPath, $contentData, $savingBehavior);
39
+			$signalArguments->setContentData($contentData);
40
+		}
41
+
42
+		return array($signalArguments);
43
+	}
44
+
45
+	/**
46
+	 * @param Content $object
47
+	 * @param $fieldNameAndPath
48
+	 * @param array $contentData
49
+	 * @param string $savingBehavior
50
+	 * @return array
51
+	 */
52
+	protected function appendOrRemoveRelations(Content $object, $fieldNameAndPath, array $contentData, $savingBehavior)
53
+	{
54
+		foreach ($contentData as $fieldName => $values) {
55
+			$resolvedObject = $this->getContentObjectResolver()->getObject($object, $fieldNameAndPath);
56
+
57
+			if (Tca::table($resolvedObject)->field($fieldName)->hasMany()) {
58
+				// true means CSV values must be converted to array.
59
+				if (!is_array($values)) {
60
+					$values = GeneralUtility::trimExplode(',', $values);
61
+				}
62
+				$relatedValues = $this->getRelatedValues($object, $fieldNameAndPath, $fieldName);
63
+
64
+				foreach ($values as $value) {
65
+					$appendOrRemove = $savingBehavior . 'Relations';
66
+					$relatedValues = $this->$appendOrRemove($value, $relatedValues);
67
+				}
68
+
69
+				$contentData[$fieldName] = $relatedValues;
70
+			}
71
+		}
72
+		return $contentData;
73
+	}
74
+
75
+	/**
76
+	 * @param $value
77
+	 * @param array $relatedValues
78
+	 * @return array
79
+	 */
80
+	protected function appendRelations($value, array $relatedValues)
81
+	{
82
+		if (!in_array($value, $relatedValues)) {
83
+			$relatedValues[] = $value;
84
+		}
85
+		return $relatedValues;
86
+	}
87
+
88
+	/**
89
+	 * @param $value
90
+	 * @param array $relatedValues
91
+	 * @return array
92
+	 */
93
+	protected function removeRelations($value, array $relatedValues)
94
+	{
95
+		if (in_array($value, $relatedValues)) {
96
+			$key = array_search($value, $relatedValues);
97
+			unset($relatedValues[$key]);
98
+		}
99
+		return $relatedValues;
100
+	}
101
+
102
+	/**
103
+	 * @param Content $object
104
+	 * @param string $fieldNameAndPath
105
+	 * @param string $fieldName
106
+	 * @return array
107
+	 */
108
+	protected function getRelatedValues(Content $object, $fieldNameAndPath, $fieldName)
109
+	{
110
+		$values = [];
111
+		$relatedContentObjects = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, $fieldName);
112
+
113
+		if (is_array($relatedContentObjects)) {
114
+			/** @var Content $relatedContentObject */
115
+			foreach ($relatedContentObjects as $relatedContentObject) {
116
+				$values[] = $relatedContentObject->getUid();
117
+			}
118
+		}
119
+
120
+		return $values;
121
+	}
122
+
123
+	/**
124
+	 * @return ContentObjectResolver|object
125
+	 */
126
+	protected function getContentObjectResolver()
127
+	{
128
+		return GeneralUtility::makeInstance(ContentObjectResolver::class);
129
+	}
130
+
131
+	/**
132
+	 * @return FieldPathResolver|object
133
+	 */
134
+	protected function getFieldPathResolver()
135
+	{
136
+		return GeneralUtility::makeInstance(FieldPathResolver::class);
137
+	}
138 138
 }
Please login to merge, or discard this patch.
Classes/Processor/MarkerProcessor.php 1 patch
Indentation   +94 added lines, -94 removed lines patch added patch discarded remove patch
@@ -20,109 +20,109 @@
 block discarded – undo
20 20
  */
21 21
 class MarkerProcessor implements SingletonInterface
22 22
 {
23
-    /**
24
-     * @var array
25
-     */
26
-    protected $wellKnownMarkers = array(
27
-        '{*}',
28
-        '{counter}',
29
-        '{date}',
30
-        '{creation_date}'
31
-    );
23
+	/**
24
+	 * @var array
25
+	 */
26
+	protected $wellKnownMarkers = array(
27
+		'{*}',
28
+		'{counter}',
29
+		'{date}',
30
+		'{creation_date}'
31
+	);
32 32
 
33
-    /**
34
-     * @param ProcessContentDataSignalArguments $signalArguments
35
-     * @return array
36
-     */
37
-    public function processMarkers(ProcessContentDataSignalArguments $signalArguments)
38
-    {
39
-        $contentData = $signalArguments->getContentData();
40
-        $creationTime = $this->getCreationTime($signalArguments);
33
+	/**
34
+	 * @param ProcessContentDataSignalArguments $signalArguments
35
+	 * @return array
36
+	 */
37
+	public function processMarkers(ProcessContentDataSignalArguments $signalArguments)
38
+	{
39
+		$contentData = $signalArguments->getContentData();
40
+		$creationTime = $this->getCreationTime($signalArguments);
41 41
 
42
-        // Process markers
43
-        foreach ($signalArguments->getContentData() as $fieldName => $updateValue) {
44
-            if (is_scalar($updateValue)) {
45
-                $currentValue = $this->getContentObjectResolver()->getValue(
46
-                    $signalArguments->getContentObject(),
47
-                    $signalArguments->getFieldNameAndPath(),
48
-                    $fieldName,
49
-                    $signalArguments->getLanguage()
50
-                );
51
-                $counter = $signalArguments->getCounter();
42
+		// Process markers
43
+		foreach ($signalArguments->getContentData() as $fieldName => $updateValue) {
44
+			if (is_scalar($updateValue)) {
45
+				$currentValue = $this->getContentObjectResolver()->getValue(
46
+					$signalArguments->getContentObject(),
47
+					$signalArguments->getFieldNameAndPath(),
48
+					$fieldName,
49
+					$signalArguments->getLanguage()
50
+				);
51
+				$counter = $signalArguments->getCounter();
52 52
 
53
-                $updateValue = $this->searchAndReplace($updateValue, $currentValue);
54
-                $updateValue = $this->replaceWellKnownMarkers($updateValue, $currentValue, $counter, $creationTime);
53
+				$updateValue = $this->searchAndReplace($updateValue, $currentValue);
54
+				$updateValue = $this->replaceWellKnownMarkers($updateValue, $currentValue, $counter, $creationTime);
55 55
 
56
-                $contentData[$fieldName] = $updateValue;
57
-            }
58
-        }
56
+				$contentData[$fieldName] = $updateValue;
57
+			}
58
+		}
59 59
 
60
-        $signalArguments->setContentData($contentData);
61
-        return array($signalArguments);
62
-    }
60
+		$signalArguments->setContentData($contentData);
61
+		return array($signalArguments);
62
+	}
63 63
 
64
-    /**
65
-     * @param string $updateValue
66
-     * @param string $currentValue
67
-     * @param int $counter
68
-     * @param $creationTime
69
-     * @return string
70
-     */
71
-    protected function replaceWellKnownMarkers($updateValue, $currentValue, $counter, $creationTime)
72
-    {
73
-        // Replaces values.
74
-        $replaces = array(
75
-            $currentValue,
76
-            $counter,
77
-            date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']),
78
-            date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $creationTime),
79
-        );
64
+	/**
65
+	 * @param string $updateValue
66
+	 * @param string $currentValue
67
+	 * @param int $counter
68
+	 * @param $creationTime
69
+	 * @return string
70
+	 */
71
+	protected function replaceWellKnownMarkers($updateValue, $currentValue, $counter, $creationTime)
72
+	{
73
+		// Replaces values.
74
+		$replaces = array(
75
+			$currentValue,
76
+			$counter,
77
+			date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']),
78
+			date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $creationTime),
79
+		);
80 80
 
81
-        // Replace me!
82
-        return str_replace($this->wellKnownMarkers, $replaces, $updateValue);
83
-    }
81
+		// Replace me!
82
+		return str_replace($this->wellKnownMarkers, $replaces, $updateValue);
83
+	}
84 84
 
85
-    /**
86
-     * @param string $updateValue
87
-     * @param string $currentValue
88
-     * @return string
89
-     */
90
-    protected function searchAndReplace($updateValue, $currentValue)
91
-    {
92
-        if (strpos($updateValue, 's/') !== false) {
93
-            $structure = explode('/', $updateValue);
94
-            $search = $structure[1];
95
-            $replace = $structure[2];
85
+	/**
86
+	 * @param string $updateValue
87
+	 * @param string $currentValue
88
+	 * @return string
89
+	 */
90
+	protected function searchAndReplace($updateValue, $currentValue)
91
+	{
92
+		if (strpos($updateValue, 's/') !== false) {
93
+			$structure = explode('/', $updateValue);
94
+			$search = $structure[1];
95
+			$replace = $structure[2];
96 96
 
97
-            // Perhaps needs to be improved here if $search contains "/" precisely.
98
-            $updateValue = preg_replace('/' . $search . '/isU', $replace, $currentValue);
99
-        }
100
-        return $updateValue;
101
-    }
97
+			// Perhaps needs to be improved here if $search contains "/" precisely.
98
+			$updateValue = preg_replace('/' . $search . '/isU', $replace, $currentValue);
99
+		}
100
+		return $updateValue;
101
+	}
102 102
 
103
-    /**
104
-     * @param ProcessContentDataSignalArguments $signalArguments
105
-     * @return int
106
-     */
107
-    protected function getCreationTime(ProcessContentDataSignalArguments $signalArguments)
108
-    {
109
-        $creationTime = 0;
110
-        $creationTimeField = Tca::table($signalArguments->getContentObject()->getDataType())->getTimeCreationField();
111
-        if ($creationTimeField) {
112
-            $creationTime = $this->getContentObjectResolver()->getValue(
113
-                $signalArguments->getContentObject(),
114
-                $signalArguments->getFieldNameAndPath(),
115
-                $creationTimeField
116
-            );
117
-        }
118
-        return $creationTime;
119
-    }
103
+	/**
104
+	 * @param ProcessContentDataSignalArguments $signalArguments
105
+	 * @return int
106
+	 */
107
+	protected function getCreationTime(ProcessContentDataSignalArguments $signalArguments)
108
+	{
109
+		$creationTime = 0;
110
+		$creationTimeField = Tca::table($signalArguments->getContentObject()->getDataType())->getTimeCreationField();
111
+		if ($creationTimeField) {
112
+			$creationTime = $this->getContentObjectResolver()->getValue(
113
+				$signalArguments->getContentObject(),
114
+				$signalArguments->getFieldNameAndPath(),
115
+				$creationTimeField
116
+			);
117
+		}
118
+		return $creationTime;
119
+	}
120 120
 
121
-    /**
122
-     * @return ContentObjectResolver
123
-     */
124
-    protected function getContentObjectResolver()
125
-    {
126
-        return GeneralUtility::makeInstance(ContentObjectResolver::class);
127
-    }
121
+	/**
122
+	 * @return ContentObjectResolver
123
+	 */
124
+	protected function getContentObjectResolver()
125
+	{
126
+		return GeneralUtility::makeInstance(ContentObjectResolver::class);
127
+	}
128 128
 }
Please login to merge, or discard this patch.
Classes/Domain/Repository/SelectionRepository.php 1 patch
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -19,62 +19,62 @@
 block discarded – undo
19 19
  */
20 20
 class SelectionRepository extends Repository
21 21
 {
22
-    /**
23
-     * @param string $dataType
24
-     * @return QueryResult
25
-     */
26
-    public function findByDataTypeForCurrentBackendUser($dataType)
27
-    {
28
-        $query = $this->createQuery();
22
+	/**
23
+	 * @param string $dataType
24
+	 * @return QueryResult
25
+	 */
26
+	public function findByDataTypeForCurrentBackendUser($dataType)
27
+	{
28
+		$query = $this->createQuery();
29 29
 
30
-        // Compute the OR part
31
-        if ($this->getBackendUser()->isAdmin()) {
32
-            $logicalOr = $query->logicalOr([$query->equals('visibility', Selection::VISIBILITY_EVERYONE), $query->equals('visibility', Selection::VISIBILITY_ADMIN_ONLY), $query->equals('cruser_id', $this->getBackendUser()->user['uid'])]);
33
-        } else {
34
-            $logicalOr = $query->logicalOr([$query->equals('visibility', Selection::VISIBILITY_EVERYONE), $query->equals('cruser_id', $this->getBackendUser()->user['uid'])]);
35
-        }
30
+		// Compute the OR part
31
+		if ($this->getBackendUser()->isAdmin()) {
32
+			$logicalOr = $query->logicalOr([$query->equals('visibility', Selection::VISIBILITY_EVERYONE), $query->equals('visibility', Selection::VISIBILITY_ADMIN_ONLY), $query->equals('cruser_id', $this->getBackendUser()->user['uid'])]);
33
+		} else {
34
+			$logicalOr = $query->logicalOr([$query->equals('visibility', Selection::VISIBILITY_EVERYONE), $query->equals('cruser_id', $this->getBackendUser()->user['uid'])]);
35
+		}
36 36
 
37
-        // Add matching criteria
38
-        $query->matching(
39
-            $query->logicalAnd([$query->equals('dataType', $dataType), $logicalOr])
40
-        );
37
+		// Add matching criteria
38
+		$query->matching(
39
+			$query->logicalAnd([$query->equals('dataType', $dataType), $logicalOr])
40
+		);
41 41
 
42
-        // Set ordering
43
-        $query->setOrderings(
44
-            array('name' => QueryInterface::ORDER_ASCENDING)
45
-        );
42
+		// Set ordering
43
+		$query->setOrderings(
44
+			array('name' => QueryInterface::ORDER_ASCENDING)
45
+		);
46 46
 
47
-        return $query->execute();
48
-    }
47
+		return $query->execute();
48
+	}
49 49
 
50
-    /**
51
-     * @param string $dataType
52
-     * @return QueryResult
53
-     */
54
-    public function findForEveryone($dataType)
55
-    {
56
-        $query = $this->createQuery();
50
+	/**
51
+	 * @param string $dataType
52
+	 * @return QueryResult
53
+	 */
54
+	public function findForEveryone($dataType)
55
+	{
56
+		$query = $this->createQuery();
57 57
 
58
-        // Add matching criteria
59
-        $query->matching(
60
-            $query->logicalAnd([$query->equals('dataType', $dataType), $query->equals('visibility', Selection::VISIBILITY_EVERYONE)])
61
-        );
58
+		// Add matching criteria
59
+		$query->matching(
60
+			$query->logicalAnd([$query->equals('dataType', $dataType), $query->equals('visibility', Selection::VISIBILITY_EVERYONE)])
61
+		);
62 62
 
63
-        // Set ordering
64
-        $query->setOrderings(
65
-            array('name' => QueryInterface::ORDER_ASCENDING)
66
-        );
63
+		// Set ordering
64
+		$query->setOrderings(
65
+			array('name' => QueryInterface::ORDER_ASCENDING)
66
+		);
67 67
 
68
-        return $query->execute();
69
-    }
68
+		return $query->execute();
69
+	}
70 70
 
71
-    /**
72
-     * Returns an instance of the current Backend User.
73
-     *
74
-     * @return BackendUserAuthentication
75
-     */
76
-    protected function getBackendUser()
77
-    {
78
-        return $GLOBALS['BE_USER'];
79
-    }
71
+	/**
72
+	 * Returns an instance of the current Backend User.
73
+	 *
74
+	 * @return BackendUserAuthentication
75
+	 */
76
+	protected function getBackendUser()
77
+	{
78
+		return $GLOBALS['BE_USER'];
79
+	}
80 80
 }
Please login to merge, or discard this patch.
Classes/Domain/Repository/ContentRepository.php 2 patches
Indentation   +828 added lines, -828 removed lines patch added patch discarded remove patch
@@ -36,832 +36,832 @@
 block discarded – undo
36 36
  */
37 37
 class ContentRepository implements RepositoryInterface
38 38
 {
39
-    /**
40
-     * Tell whether it is a raw result (array) or object being returned.
41
-     *
42
-     * @var bool
43
-     */
44
-    protected $rawResult = false;
45
-
46
-    /**
47
-     * The data type to be returned, e.g fe_users, fe_groups, tt_content, etc...
48
-     *
49
-     * @var string
50
-     */
51
-    protected $dataType;
52
-
53
-    /**
54
-     * The source field is useful in the context of MM relations to know who is the caller
55
-     * e.g findByItems which eventually corresponds to a field name.
56
-     *
57
-     * @var string
58
-     */
59
-    protected $sourceFieldName = '';
60
-
61
-    /**
62
-     * @var array
63
-     */
64
-    protected $errorMessages = [];
65
-
66
-    /**
67
-     * @var QuerySettingsInterface
68
-     */
69
-    protected $defaultQuerySettings;
70
-
71
-    /**
72
-     * @var DataHandler
73
-     */
74
-    protected $dataHandler;
75
-
76
-    /**
77
-     * Constructor
78
-     *
79
-     * @param string $dataType
80
-     */
81
-    public function __construct($dataType)
82
-    {
83
-        $this->dataType = $dataType;
84
-    }
85
-
86
-    /**
87
-     * Returns all objects of this repository.
88
-     *
89
-     * @return Content[]
90
-     */
91
-    public function findAll()
92
-    {
93
-        $query = $this->createQuery();
94
-        return $query->execute();
95
-    }
96
-
97
-    /**
98
-     * Returns all "distinct" values for a given property.
99
-     *
100
-     * @param string $propertyName
101
-     * @param Matcher $matcher
102
-     * @param Order|null $order
103
-     * @return Content[]
104
-     */
105
-    public function findDistinctValues($propertyName, Matcher $matcher = null, Order $order = null): array
106
-    {
107
-        $query = $this->createQuery();
108
-        $query->setDistinct($propertyName);
109
-
110
-        // Remove empty values from selection.
111
-        $constraint = $query->logicalNot($query->equals($propertyName, ''));
112
-
113
-        // Add some additional constraints from the Matcher object.
114
-        $matcherConstraint = null;
115
-        if ($matcher !== null) {
116
-            $matcherConstraint = $this->computeConstraints($query, $matcher);
117
-        }
118
-
119
-        // Assemble the final constraints or not.
120
-        if ($matcherConstraint) {
121
-            $query->logicalAnd([$matcherConstraint, $constraint]);
122
-            $query->matching($query->logicalAnd([$matcherConstraint, $constraint]));
123
-        } else {
124
-            $query->matching($constraint);
125
-        }
126
-
127
-        if ($order) {
128
-            $query->setOrderings($order->getOrderings());
129
-        }
130
-
131
-        return $query->execute();
132
-    }
133
-
134
-    /**
135
-     * Returns all "distinct" values for a given property.
136
-     *
137
-     * @param string $propertyName
138
-     * @param Matcher $matcher
139
-     * @return int
140
-     */
141
-    public function countDistinctValues($propertyName, Matcher $matcher = null): int
142
-    {
143
-        $query = $this->createQuery();
144
-        $query->setDistinct($propertyName);
145
-
146
-        // Remove empty values from selection.
147
-        $constraint = $query->logicalNot($query->equals($propertyName, ''));
148
-
149
-        // Add some additional constraints from the Matcher object.
150
-        $matcherConstraint = null;
151
-        if (!is_null($matcher)) {
152
-            $matcherConstraint = $this->computeConstraints($query, $matcher);
153
-        }
154
-
155
-        // Assemble the final constraints or not.
156
-        if ($matcherConstraint) {
157
-            $query->logicalAnd([$matcherConstraint, $constraint]);
158
-            $query->matching($query->logicalAnd([$matcherConstraint, $constraint]));
159
-        } else {
160
-            $query->matching($constraint);
161
-        }
162
-
163
-        return $query->count();
164
-    }
165
-
166
-    /**
167
-     * Finds an object matching the given identifier.
168
-     *
169
-     * @param int $uid The identifier of the object to find
170
-     * @return Content|null
171
-     * @api
172
-     */
173
-    public function findByUid($uid)
174
-    {
175
-        return $this->findByIdentifier($uid);
176
-    }
177
-
178
-    /**
179
-     * Finds all Contents given specified matches.
180
-     *
181
-     * @param string $propertyName
182
-     * @param array $values
183
-     * @return Content[]
184
-     */
185
-    public function findIn($propertyName, array $values): array
186
-    {
187
-        $query = $this->createQuery();
188
-        $query->matching($query->in($propertyName, $values));
189
-        return $query->execute();
190
-    }
191
-
192
-    /**
193
-     * Finds all Contents given specified matches.
194
-     *
195
-     * @param Matcher $matcher
196
-     * @param Order $order The order
197
-     * @param int $limit
198
-     * @param int $offset
199
-     * @return Content[]
200
-     */
201
-    public function findBy(Matcher $matcher, Order $order = null, $limit = null, $offset = null): array
202
-    {
203
-        $query = $this->createQuery();
204
-
205
-        $limit = (int)$limit; // make sure to cast
206
-        if ($limit > 0) {
207
-            $query->setLimit($limit);
208
-        }
209
-
210
-        if ($order) {
211
-            $query->setOrderings($order->getOrderings());
212
-
213
-            // Loops around the orderings adding if necessary a dummy condition
214
-            // to make sure the relations can be resolved when transforming the query to plain SQL.
215
-            foreach ($order->getOrderings() as $ordering => $direction) {
216
-                if ($this->hasForeignRelationIn($ordering)) {
217
-                    $relationalField = $this->getForeignRelationFrom($ordering);
218
-                    $matcher->like($relationalField . '.uid', '');
219
-                }
220
-            }
221
-        }
222
-
223
-        if ($offset) {
224
-            $query->setOffset($offset);
225
-        }
226
-
227
-        $constraints = $this->computeConstraints($query, $matcher);
228
-
229
-        if ($constraints) {
230
-            $query->matching($constraints);
231
-        }
232
-
233
-        return $query->execute();
234
-    }
235
-
236
-    /**
237
-     * Find one Content object given specified matches.
238
-     *
239
-     * @param Matcher $matcher
240
-     * @return Content
241
-     */
242
-    public function findOneBy(Matcher $matcher): Content
243
-    {
244
-        $query = $this->createQuery();
245
-
246
-        $constraints = $this->computeConstraints($query, $matcher);
247
-
248
-        if ($constraints) {
249
-            $query->matching($constraints);
250
-        }
251
-
252
-        $query->setLimit(1); // only take one!
253
-
254
-        $resultSet = $query->execute();
255
-        if ($resultSet) {
256
-            $resultSet = current($resultSet);
257
-        }
258
-        return $resultSet;
259
-    }
260
-
261
-    /**
262
-     * Count all Contents given specified matches.
263
-     *
264
-     * @param Matcher $matcher
265
-     * @return int
266
-     */
267
-    public function countBy(Matcher $matcher): int
268
-    {
269
-        $query = $this->createQuery();
270
-
271
-        $constraints = $this->computeConstraints($query, $matcher);
272
-
273
-        if ($constraints) {
274
-            $query->matching($constraints);
275
-        }
276
-
277
-        return $query->count();
278
-    }
279
-
280
-    /**
281
-     * Update a content with new information.
282
-     *
283
-     * @param Content $content
284
-     * @param $language
285
-     * @return bool
286
-     */
287
-    public function localize($content, $language): bool
288
-    {
289
-        // Security check
290
-        $this->getContentValidator()->validate($content);
291
-        $this->getLanguageValidator()->validate($language);
292
-
293
-        $dataType = $content->getDataType();
294
-        $handler = $this->getDataHandlerFactory()->action(ProcessAction::LOCALIZE)->forType($dataType)->getDataHandler();
295
-
296
-        $handlerResult = $handler->processLocalize($content, $language);
297
-        $this->errorMessages = $handler->getErrorMessages();
298
-        return $handlerResult;
299
-    }
300
-
301
-    /**
302
-     * Update a content with new information.
303
-     *
304
-     * @param Content $content
305
-     * @return bool
306
-     */
307
-    public function update($content)
308
-    {
309
-        // Security check.
310
-        $this->getContentValidator()->validate($content);
311
-
312
-        $dataType = $content->getDataType();
313
-        $handler = $this->getDataHandlerFactory()->action(ProcessAction::UPDATE)->forType($dataType)->getDataHandler();
314
-
315
-        $handlerResult = $handler->processUpdate($content);
316
-        $this->errorMessages = $handler->getErrorMessages();
317
-        return $handlerResult;
318
-    }
319
-
320
-    /**
321
-     * Removes an object from this repository.
322
-     *
323
-     * @param Content $content
324
-     * @return boolean
325
-     */
326
-    public function remove($content)
327
-    {
328
-        $dataType = $content->getDataType();
329
-        $handler = $this->getDataHandlerFactory()->action(ProcessAction::REMOVE)->forType($dataType)->getDataHandler();
330
-
331
-        $handlerResult = $handler->processRemove($content);
332
-        $this->errorMessages = $handler->getErrorMessages();
333
-        return $handlerResult;
334
-    }
335
-
336
-    /**
337
-     * Move a content within this repository.
338
-     * The $target corresponds to the pid to move the records to.
339
-     * It can also be a negative value in case of sorting. The negative value would be the uid of its predecessor.
340
-     *
341
-     * @param Content $content
342
-     * @param string $target
343
-     * @return bool
344
-     */
345
-    public function move($content, $target): bool
346
-    {
347
-        // Security check.
348
-        $this->getContentValidator()->validate($content);
349
-
350
-        $dataType = $content->getDataType();
351
-        $handler = $this->getDataHandlerFactory()->action(ProcessAction::MOVE)->forType($dataType)->getDataHandler();
352
-
353
-        $handlerResult = $handler->processMove($content, $target);
354
-        $this->errorMessages = $handler->getErrorMessages();
355
-        return $handlerResult;
356
-    }
357
-
358
-    /**
359
-     * Copy a content within this repository.
360
-     *
361
-     * @param Content $content
362
-     * @return bool
363
-     */
364
-    public function copy($content, $target): bool
365
-    {
366
-        // Security check.
367
-        $this->getContentValidator()->validate($content);
368
-
369
-        $dataType = $content->getDataType();
370
-        $handler = $this->getDataHandlerFactory()->action(ProcessAction::COPY)->forType($dataType)->getDataHandler();
371
-
372
-        $handlerResult = $handler->processCopy($content, $target);
373
-        $this->errorMessages = $handler->getErrorMessages();
374
-        return $handlerResult;
375
-    }
376
-
377
-    /**
378
-     * Adds an object to this repository.
379
-     *
380
-     * @param object $object The object to add
381
-     * @return void
382
-     * @api
383
-     */
384
-    public function add($object)
385
-    {
386
-        throw new \BadMethodCallException('Repository does not support the add() method.', 1375805599);
387
-    }
388
-
389
-    /**
390
-     * Returns the total number objects of this repository.
391
-     *
392
-     * @return integer The object count
393
-     * @api
394
-     */
395
-    public function countAll()
396
-    {
397
-        $query = $this->createQuery();
398
-        return $query->count();
399
-    }
400
-
401
-    /**
402
-     * Removes all objects of this repository as if remove() was called for
403
-     * all of them.
404
-     *
405
-     * @return void
406
-     * @api
407
-     */
408
-    public function removeAll()
409
-    {
410
-        // TODO: Implement removeAll() method.
411
-    }
412
-
413
-    /**
414
-     * Finds an object matching the given identifier.
415
-     *
416
-     * @param mixed $identifier The identifier of the object to find
417
-     * @return Content|null
418
-     * @api
419
-     */
420
-    public function findByIdentifier($identifier)
421
-    {
422
-        $query = $this->createQuery();
423
-
424
-        $result = $query->matching(
425
-            $query->equals('uid', $identifier)
426
-        )
427
-            ->execute();
428
-
429
-        if (is_array($result)) {
430
-            $result = current($result);
431
-        }
432
-
433
-        return $result;
434
-    }
435
-
436
-    /**
437
-     * Dispatches magic methods (findBy[Property]())
438
-     *
439
-     * @param string $methodName The name of the magic method
440
-     * @param string $arguments The arguments of the magic method
441
-     * @return mixed
442
-     * @api
443
-     */
444
-    public function __call($methodName, $arguments)
445
-    {
446
-        if (substr($methodName, 0, 6) === 'findBy' && strlen($methodName) > 7) {
447
-            $propertyName = strtolower(substr(substr($methodName, 6), 0, 1)) . substr(substr($methodName, 6), 1);
448
-            $result = $this->processMagicCall($propertyName, $arguments[0]);
449
-        } elseif (substr($methodName, 0, 9) === 'findOneBy' && strlen($methodName) > 10) {
450
-            $propertyName = strtolower(substr(substr($methodName, 9), 0, 1)) . substr(substr($methodName, 9), 1);
451
-            $result = $this->processMagicCall($propertyName, $arguments[0], 'one');
452
-        } elseif (substr($methodName, 0, 7) === 'countBy' && strlen($methodName) > 8) {
453
-            $propertyName = strtolower(substr(substr($methodName, 7), 0, 1)) . substr(substr($methodName, 7), 1);
454
-            $result = $this->processMagicCall($propertyName, $arguments[0], 'count');
455
-        } else {
456
-            throw new UnsupportedMethodException('The method "' . $methodName . '" is not supported by the repository.', 1360838010);
457
-        }
458
-        return $result;
459
-    }
460
-
461
-    /**
462
-     * Returns a query for objects of this repository
463
-     *
464
-     * @return Query
465
-     * @api
466
-     */
467
-    public function createQuery()
468
-    {
469
-        /** @var Query $query */
470
-        $query = GeneralUtility::makeInstance(Query::class, $this->dataType);
471
-        $query->setSourceFieldName($this->sourceFieldName);
472
-
473
-        if ($this->defaultQuerySettings) {
474
-            $query->setTypo3QuerySettings($this->defaultQuerySettings);
475
-        } else {
476
-            // Initialize and pass the query settings at this level.
477
-            $querySettings = GeneralUtility::makeInstance(Typo3QuerySettings::class);
478
-
479
-            // Default choice for the BE.
480
-            if ($this->isBackendMode()) {
481
-                $querySettings->setIgnoreEnableFields(true);
482
-            }
483
-
484
-            $query->setTypo3QuerySettings($querySettings);
485
-        }
486
-
487
-        return $query;
488
-    }
489
-
490
-    /**
491
-     * Sets the property names to order the result by per default.
492
-     * Expected like this:
493
-     * array(
494
-     * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
495
-     * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
496
-     * )
497
-     *
498
-     * @param array $defaultOrderings The property names to order by
499
-     * @return void
500
-     * @api
501
-     */
502
-    public function setDefaultOrderings(array $defaultOrderings)
503
-    {
504
-        throw new \BadMethodCallException('Repository does not support the setDefaultOrderings() method.', 1375805598);
505
-    }
506
-
507
-    /**
508
-     * Sets the default query settings to be used in this repository
509
-     *
510
-     * @param QuerySettingsInterface $defaultQuerySettings The query settings to be used by default
511
-     * @return void
512
-     * @api
513
-     */
514
-    public function setDefaultQuerySettings(QuerySettingsInterface $defaultQuerySettings)
515
-    {
516
-        $this->defaultQuerySettings = $defaultQuerySettings;
517
-    }
518
-
519
-    /**
520
-     * @return void
521
-     */
522
-    public function resetDefaultQuerySettings(): void
523
-    {
524
-        $this->defaultQuerySettings = null;
525
-    }
526
-
527
-
528
-    /**
529
-     * @return array
530
-     */
531
-    public function getErrorMessages(): array
532
-    {
533
-        return $this->errorMessages;
534
-    }
535
-
536
-    /**
537
-     * @param string $sourceFieldName
538
-     * @return $this
539
-     */
540
-    public function setSourceFieldName($sourceFieldName): self
541
-    {
542
-        $this->sourceFieldName = $sourceFieldName;
543
-        return $this;
544
-    }
545
-
546
-    /**
547
-     * @return string
548
-     */
549
-    public function getDataType(): string
550
-    {
551
-        return $this->dataType;
552
-    }
553
-
554
-    /**
555
-     * Tell whether the order has a foreign table in its expression, e.g. "metadata.title".
556
-     *
557
-     * @param string $ordering
558
-     * @return bool
559
-     */
560
-    protected function hasForeignRelationIn($ordering): bool
561
-    {
562
-        return strpos($ordering, '.') !== false;
563
-    }
564
-
565
-    /**
566
-     * Extract the foreign relation of the ordering "metadata.title" -> "metadata"
567
-     *
568
-     * @param string $ordering
569
-     * @return string
570
-     */
571
-    protected function getForeignRelationFrom($ordering): string
572
-    {
573
-        $parts = explode('.', $ordering);
574
-        return $parts[0];
575
-    }
576
-
577
-    /**
578
-     * Get the constraints
579
-     *
580
-     * @param Query $query
581
-     * @param Matcher $matcher
582
-     * @return ConstraintInterface|null
583
-     */
584
-    protected function computeConstraints(Query $query, Matcher $matcher): ?ConstraintInterface
585
-    {
586
-        $constraints = null;
587
-
588
-        $collectedConstraints = [];
589
-
590
-        // Search term
591
-        $constraint = $this->computeSearchTermConstraint($query, $matcher);
592
-        if ($constraint) {
593
-            $collectedConstraints[] = $constraint;
594
-        }
595
-
596
-        foreach ($matcher->getSupportedOperators() as $operator) {
597
-            $constraint = $this->computeConstraint($query, $matcher, $operator);
598
-            if ($constraint) {
599
-                $collectedConstraints[] = $constraint;
600
-            }
601
-        }
602
-
603
-        if (count($collectedConstraints) > 1) {
604
-            $logical = $matcher->getDefaultLogicalSeparator();
605
-            $constraints = $query->$logical($collectedConstraints);
606
-        } elseif (!empty($collectedConstraints)) {
607
-            // true means there is one constraint only and should become the result
608
-            $constraints = current($collectedConstraints);
609
-        }
610
-
611
-        // Trigger signal for post processing the computed constraints object.
612
-        $constraints = $this->emitPostProcessConstraintsSignal($query, $constraints);
613
-
614
-        return $constraints;
615
-    }
616
-
617
-    /**
618
-     * Computes the search constraint and returns it.
619
-     *
620
-     * @param Query $query
621
-     * @param Matcher $matcher
622
-     * @return ConstraintInterface|null
623
-     */
624
-    protected function computeSearchTermConstraint(Query $query, Matcher $matcher): ?ConstraintInterface
625
-    {
626
-        $result = null;
627
-
628
-        // Search term case
629
-        if ($matcher->getSearchTerm()) {
630
-            $fields = GeneralUtility::trimExplode(',', Tca::table($this->dataType)->getSearchFields(), true);
631
-
632
-            $constraints = [];
633
-            $likeClause = sprintf('%%%s%%', $matcher->getSearchTerm());
634
-            foreach ($fields as $fieldNameAndPath) {
635
-                if ($this->isSuitableForLike($fieldNameAndPath, $matcher->getSearchTerm())) {
636
-                    $dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $this->dataType);
637
-                    $fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $this->dataType);
638
-
639
-                    if (Tca::table($dataType)->hasField($fieldName) && Tca::table($dataType)->field($fieldName)->hasRelation()) {
640
-                        $foreignTable = Tca::table($dataType)->field($fieldName)->getForeignTable();
641
-                        $fieldNameAndPath = $fieldNameAndPath . '.' . Tca::table($foreignTable)->getLabelField();
642
-                    }
643
-                    $constraints[] = $query->like($fieldNameAndPath, $likeClause);
644
-                }
645
-            }
646
-            $logical = $matcher->getLogicalSeparatorForSearchTerm();
647
-            $result = $query->$logical($constraints);
648
-        }
649
-
650
-        return $result;
651
-    }
652
-
653
-    /**
654
-     * It does not make sense to have a "like" in presence of numerical field, e.g "uid".
655
-     * Tell whether the given value makes sense for a "like" clause.
656
-     *
657
-     * @param string $fieldNameAndPath
658
-     * @param string $value
659
-     * @return bool
660
-     */
661
-    protected function isSuitableForLike($fieldNameAndPath, $value): bool
662
-    {
663
-        $isSuitable = true;
664
-
665
-        // true means it is a string
666
-        if (!MathUtility::canBeInterpretedAsInteger($value)) {
667
-            $dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $this->dataType);
668
-            $fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $this->dataType);
669
-
670
-            if (Tca::table($dataType)->field($fieldName)->isNumerical()
671
-                && !Tca::table($dataType)->field($fieldName)->hasRelation()
672
-            ) {
673
-                $isSuitable = false;
674
-            }
675
-        }
676
-
677
-        return $isSuitable;
678
-    }
679
-
680
-    /**
681
-     * Computes the constraint for matches and returns it.
682
-     *
683
-     * @param Query $query
684
-     * @param Matcher $matcher
685
-     * @param string $operator
686
-     * @return ConstraintInterface|null
687
-     */
688
-    protected function computeConstraint(Query $query, Matcher $matcher, $operator): ?ConstraintInterface
689
-    {
690
-        $result = null;
691
-
692
-        $operatorName = ucfirst($operator);
693
-        $getCriteria = sprintf('get%s', $operatorName);
694
-        $criteria = $matcher->$getCriteria();
695
-
696
-        if (!empty($criteria)) {
697
-            $constraints = [];
698
-
699
-            foreach ($criteria as $criterion) {
700
-                $fieldNameAndPath = $criterion['fieldNameAndPath'];
701
-                $operand = $criterion['operand'];
702
-
703
-                // Compute a few variables...
704
-                // $dataType is generally equals to $this->dataType but not always... if fieldName is a path.
705
-                $dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $this->dataType);
706
-                $fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $this->dataType);
707
-                $fieldPath = $this->getFieldPathResolver()->stripFieldName($fieldNameAndPath, $this->dataType);
708
-
709
-                if (Tca::table($dataType)->field($fieldName)->hasRelation()) {
710
-                    if (MathUtility::canBeInterpretedAsInteger($operand)) {
711
-                        $fieldNameAndPath = $fieldName . '.uid';
712
-                    } else {
713
-                        $foreignTableName = Tca::table($dataType)->field($fieldName)->getForeignTable();
714
-                        $foreignTable = Tca::table($foreignTableName);
715
-                        $fieldNameAndPath = $fieldName . '.' . $foreignTable->getLabelField();
716
-                    }
717
-
718
-                    // If different means we should restore the prepended path segment for proper SQL parser.
719
-                    // This is true for a composite field, e.g items.sys_file_metadata for categories.
720
-                    if ($fieldName !== $fieldPath) {
721
-                        $fieldNameAndPath = $fieldPath . '.' . $fieldNameAndPath;
722
-                    }
723
-                }
724
-
725
-                if (strpos($operator, 'not') === 0) {
726
-                    $strippedOperator = strtolower(substr($operator, 3));
727
-                    $constraints[] = $query->logicalNot($query->$strippedOperator($fieldNameAndPath, $criterion['operand']));
728
-                } else {
729
-                    $constraints[] = $query->$operator($fieldNameAndPath, $criterion['operand']);
730
-                }
731
-            }
732
-
733
-            $getLogicalSeparator = sprintf('getLogicalSeparatorFor%s', $operatorName);
734
-            $logical = method_exists($matcher, $getLogicalSeparator)
735
-                ? $matcher->$getLogicalSeparator()
736
-                : $matcher->getDefaultLogicalSeparator();
737
-
738
-            $result = $query->$logical($constraints);
739
-        }
740
-
741
-        return $result;
742
-    }
743
-
744
-    /**
745
-     * @return DataHandler
746
-     */
747
-    protected function getDataHandler(): DataHandler
748
-    {
749
-        if (!$this->dataHandler) {
750
-            $this->dataHandler = GeneralUtility::makeInstance(DataHandler::class);
751
-        }
752
-        return $this->dataHandler;
753
-    }
754
-
755
-    /**
756
-     * Handle the magic call by properly creating a Query object and returning its result.
757
-     *
758
-     * @param string $propertyName
759
-     * @param string $value
760
-     * @param string $flag
761
-     * @return mixed
762
-     */
763
-    protected function processMagicCall($propertyName, $value, $flag = '')
764
-    {
765
-        $fieldName = Property::name($propertyName)->of($this->dataType)->toFieldName();
766
-
767
-        /** @var $matcher Matcher */
768
-        $matcher = GeneralUtility::makeInstance(Matcher::class, [], $this->getDataType());
769
-
770
-        $table = Tca::table($this->dataType);
771
-        if ($table->field($fieldName)->isGroup()) {
772
-            $valueParts = explode('.', $value, 2);
773
-            $fieldName = $fieldName . '.' . $valueParts[0];
774
-            $value = $valueParts[1];
775
-        }
776
-
777
-        $matcher->equals($fieldName, $value);
778
-
779
-        if ($flag === 'count') {
780
-            $result = $this->countBy($matcher);
781
-        } else {
782
-            $result = $this->findBy($matcher);
783
-        }
784
-        return $flag === 'one' && !empty($result) ? reset($result) : $result;
785
-    }
786
-
787
-    /**
788
-     * @return DataHandlerFactory|object
789
-     */
790
-    protected function getDataHandlerFactory()
791
-    {
792
-        return GeneralUtility::makeInstance(DataHandlerFactory::class);
793
-    }
794
-
795
-    /**
796
-     * Returns whether the current mode is Backend
797
-     *
798
-     * @return bool
799
-     */
800
-    protected function isBackendMode(): bool
801
-    {
802
-        return ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend();
803
-    }
804
-
805
-    /**
806
-     * @return FieldPathResolver|object
807
-     */
808
-    protected function getFieldPathResolver()
809
-    {
810
-        return GeneralUtility::makeInstance(FieldPathResolver::class);
811
-    }
812
-
813
-    /**
814
-     * @return ContentValidator|object
815
-     */
816
-    protected function getContentValidator(): ContentValidator
817
-    {
818
-        return GeneralUtility::makeInstance(ContentValidator::class);
819
-    }
820
-
821
-    /**
822
-     * @return LanguageValidator|object
823
-     */
824
-    protected function getLanguageValidator(): LanguageValidator
825
-    {
826
-        return GeneralUtility::makeInstance(LanguageValidator::class);
827
-    }
828
-
829
-    /**
830
-     * Signal that is called for post-processing the computed constraints object.
831
-     *
832
-     * @param Query $query
833
-     * @param ConstraintInterface|null $constraints
834
-     * @return ConstraintInterface|null $constraints
835
-     */
836
-    protected function emitPostProcessConstraintsSignal(Query $query, $constraints): ?ConstraintInterface
837
-    {
838
-        /** @var ConstraintContainer $constraintContainer */
839
-        $constraintContainer = GeneralUtility::makeInstance(ConstraintContainer::class);
840
-        $result = $this->getSignalSlotDispatcher()->dispatch(
841
-            self::class,
842
-            'postProcessConstraintsObject',
843
-            [
844
-                $query,
845
-                $constraints,
846
-                $constraintContainer
847
-            ]
848
-        );
849
-
850
-        // Backward compatibility.
851
-        $processedConstraints = $result[1];
852
-
853
-        // New way to transmit the constraints.
854
-        if ($constraintContainer->getConstraint()) {
855
-            $processedConstraints = $constraintContainer->getConstraint();
856
-        }
857
-        return $processedConstraints;
858
-    }
859
-
860
-    /**
861
-     * @return Dispatcher
862
-     */
863
-    protected function getSignalSlotDispatcher(): Dispatcher
864
-    {
865
-        return GeneralUtility::makeInstance(Dispatcher::class);
866
-    }
39
+	/**
40
+	 * Tell whether it is a raw result (array) or object being returned.
41
+	 *
42
+	 * @var bool
43
+	 */
44
+	protected $rawResult = false;
45
+
46
+	/**
47
+	 * The data type to be returned, e.g fe_users, fe_groups, tt_content, etc...
48
+	 *
49
+	 * @var string
50
+	 */
51
+	protected $dataType;
52
+
53
+	/**
54
+	 * The source field is useful in the context of MM relations to know who is the caller
55
+	 * e.g findByItems which eventually corresponds to a field name.
56
+	 *
57
+	 * @var string
58
+	 */
59
+	protected $sourceFieldName = '';
60
+
61
+	/**
62
+	 * @var array
63
+	 */
64
+	protected $errorMessages = [];
65
+
66
+	/**
67
+	 * @var QuerySettingsInterface
68
+	 */
69
+	protected $defaultQuerySettings;
70
+
71
+	/**
72
+	 * @var DataHandler
73
+	 */
74
+	protected $dataHandler;
75
+
76
+	/**
77
+	 * Constructor
78
+	 *
79
+	 * @param string $dataType
80
+	 */
81
+	public function __construct($dataType)
82
+	{
83
+		$this->dataType = $dataType;
84
+	}
85
+
86
+	/**
87
+	 * Returns all objects of this repository.
88
+	 *
89
+	 * @return Content[]
90
+	 */
91
+	public function findAll()
92
+	{
93
+		$query = $this->createQuery();
94
+		return $query->execute();
95
+	}
96
+
97
+	/**
98
+	 * Returns all "distinct" values for a given property.
99
+	 *
100
+	 * @param string $propertyName
101
+	 * @param Matcher $matcher
102
+	 * @param Order|null $order
103
+	 * @return Content[]
104
+	 */
105
+	public function findDistinctValues($propertyName, Matcher $matcher = null, Order $order = null): array
106
+	{
107
+		$query = $this->createQuery();
108
+		$query->setDistinct($propertyName);
109
+
110
+		// Remove empty values from selection.
111
+		$constraint = $query->logicalNot($query->equals($propertyName, ''));
112
+
113
+		// Add some additional constraints from the Matcher object.
114
+		$matcherConstraint = null;
115
+		if ($matcher !== null) {
116
+			$matcherConstraint = $this->computeConstraints($query, $matcher);
117
+		}
118
+
119
+		// Assemble the final constraints or not.
120
+		if ($matcherConstraint) {
121
+			$query->logicalAnd([$matcherConstraint, $constraint]);
122
+			$query->matching($query->logicalAnd([$matcherConstraint, $constraint]));
123
+		} else {
124
+			$query->matching($constraint);
125
+		}
126
+
127
+		if ($order) {
128
+			$query->setOrderings($order->getOrderings());
129
+		}
130
+
131
+		return $query->execute();
132
+	}
133
+
134
+	/**
135
+	 * Returns all "distinct" values for a given property.
136
+	 *
137
+	 * @param string $propertyName
138
+	 * @param Matcher $matcher
139
+	 * @return int
140
+	 */
141
+	public function countDistinctValues($propertyName, Matcher $matcher = null): int
142
+	{
143
+		$query = $this->createQuery();
144
+		$query->setDistinct($propertyName);
145
+
146
+		// Remove empty values from selection.
147
+		$constraint = $query->logicalNot($query->equals($propertyName, ''));
148
+
149
+		// Add some additional constraints from the Matcher object.
150
+		$matcherConstraint = null;
151
+		if (!is_null($matcher)) {
152
+			$matcherConstraint = $this->computeConstraints($query, $matcher);
153
+		}
154
+
155
+		// Assemble the final constraints or not.
156
+		if ($matcherConstraint) {
157
+			$query->logicalAnd([$matcherConstraint, $constraint]);
158
+			$query->matching($query->logicalAnd([$matcherConstraint, $constraint]));
159
+		} else {
160
+			$query->matching($constraint);
161
+		}
162
+
163
+		return $query->count();
164
+	}
165
+
166
+	/**
167
+	 * Finds an object matching the given identifier.
168
+	 *
169
+	 * @param int $uid The identifier of the object to find
170
+	 * @return Content|null
171
+	 * @api
172
+	 */
173
+	public function findByUid($uid)
174
+	{
175
+		return $this->findByIdentifier($uid);
176
+	}
177
+
178
+	/**
179
+	 * Finds all Contents given specified matches.
180
+	 *
181
+	 * @param string $propertyName
182
+	 * @param array $values
183
+	 * @return Content[]
184
+	 */
185
+	public function findIn($propertyName, array $values): array
186
+	{
187
+		$query = $this->createQuery();
188
+		$query->matching($query->in($propertyName, $values));
189
+		return $query->execute();
190
+	}
191
+
192
+	/**
193
+	 * Finds all Contents given specified matches.
194
+	 *
195
+	 * @param Matcher $matcher
196
+	 * @param Order $order The order
197
+	 * @param int $limit
198
+	 * @param int $offset
199
+	 * @return Content[]
200
+	 */
201
+	public function findBy(Matcher $matcher, Order $order = null, $limit = null, $offset = null): array
202
+	{
203
+		$query = $this->createQuery();
204
+
205
+		$limit = (int)$limit; // make sure to cast
206
+		if ($limit > 0) {
207
+			$query->setLimit($limit);
208
+		}
209
+
210
+		if ($order) {
211
+			$query->setOrderings($order->getOrderings());
212
+
213
+			// Loops around the orderings adding if necessary a dummy condition
214
+			// to make sure the relations can be resolved when transforming the query to plain SQL.
215
+			foreach ($order->getOrderings() as $ordering => $direction) {
216
+				if ($this->hasForeignRelationIn($ordering)) {
217
+					$relationalField = $this->getForeignRelationFrom($ordering);
218
+					$matcher->like($relationalField . '.uid', '');
219
+				}
220
+			}
221
+		}
222
+
223
+		if ($offset) {
224
+			$query->setOffset($offset);
225
+		}
226
+
227
+		$constraints = $this->computeConstraints($query, $matcher);
228
+
229
+		if ($constraints) {
230
+			$query->matching($constraints);
231
+		}
232
+
233
+		return $query->execute();
234
+	}
235
+
236
+	/**
237
+	 * Find one Content object given specified matches.
238
+	 *
239
+	 * @param Matcher $matcher
240
+	 * @return Content
241
+	 */
242
+	public function findOneBy(Matcher $matcher): Content
243
+	{
244
+		$query = $this->createQuery();
245
+
246
+		$constraints = $this->computeConstraints($query, $matcher);
247
+
248
+		if ($constraints) {
249
+			$query->matching($constraints);
250
+		}
251
+
252
+		$query->setLimit(1); // only take one!
253
+
254
+		$resultSet = $query->execute();
255
+		if ($resultSet) {
256
+			$resultSet = current($resultSet);
257
+		}
258
+		return $resultSet;
259
+	}
260
+
261
+	/**
262
+	 * Count all Contents given specified matches.
263
+	 *
264
+	 * @param Matcher $matcher
265
+	 * @return int
266
+	 */
267
+	public function countBy(Matcher $matcher): int
268
+	{
269
+		$query = $this->createQuery();
270
+
271
+		$constraints = $this->computeConstraints($query, $matcher);
272
+
273
+		if ($constraints) {
274
+			$query->matching($constraints);
275
+		}
276
+
277
+		return $query->count();
278
+	}
279
+
280
+	/**
281
+	 * Update a content with new information.
282
+	 *
283
+	 * @param Content $content
284
+	 * @param $language
285
+	 * @return bool
286
+	 */
287
+	public function localize($content, $language): bool
288
+	{
289
+		// Security check
290
+		$this->getContentValidator()->validate($content);
291
+		$this->getLanguageValidator()->validate($language);
292
+
293
+		$dataType = $content->getDataType();
294
+		$handler = $this->getDataHandlerFactory()->action(ProcessAction::LOCALIZE)->forType($dataType)->getDataHandler();
295
+
296
+		$handlerResult = $handler->processLocalize($content, $language);
297
+		$this->errorMessages = $handler->getErrorMessages();
298
+		return $handlerResult;
299
+	}
300
+
301
+	/**
302
+	 * Update a content with new information.
303
+	 *
304
+	 * @param Content $content
305
+	 * @return bool
306
+	 */
307
+	public function update($content)
308
+	{
309
+		// Security check.
310
+		$this->getContentValidator()->validate($content);
311
+
312
+		$dataType = $content->getDataType();
313
+		$handler = $this->getDataHandlerFactory()->action(ProcessAction::UPDATE)->forType($dataType)->getDataHandler();
314
+
315
+		$handlerResult = $handler->processUpdate($content);
316
+		$this->errorMessages = $handler->getErrorMessages();
317
+		return $handlerResult;
318
+	}
319
+
320
+	/**
321
+	 * Removes an object from this repository.
322
+	 *
323
+	 * @param Content $content
324
+	 * @return boolean
325
+	 */
326
+	public function remove($content)
327
+	{
328
+		$dataType = $content->getDataType();
329
+		$handler = $this->getDataHandlerFactory()->action(ProcessAction::REMOVE)->forType($dataType)->getDataHandler();
330
+
331
+		$handlerResult = $handler->processRemove($content);
332
+		$this->errorMessages = $handler->getErrorMessages();
333
+		return $handlerResult;
334
+	}
335
+
336
+	/**
337
+	 * Move a content within this repository.
338
+	 * The $target corresponds to the pid to move the records to.
339
+	 * It can also be a negative value in case of sorting. The negative value would be the uid of its predecessor.
340
+	 *
341
+	 * @param Content $content
342
+	 * @param string $target
343
+	 * @return bool
344
+	 */
345
+	public function move($content, $target): bool
346
+	{
347
+		// Security check.
348
+		$this->getContentValidator()->validate($content);
349
+
350
+		$dataType = $content->getDataType();
351
+		$handler = $this->getDataHandlerFactory()->action(ProcessAction::MOVE)->forType($dataType)->getDataHandler();
352
+
353
+		$handlerResult = $handler->processMove($content, $target);
354
+		$this->errorMessages = $handler->getErrorMessages();
355
+		return $handlerResult;
356
+	}
357
+
358
+	/**
359
+	 * Copy a content within this repository.
360
+	 *
361
+	 * @param Content $content
362
+	 * @return bool
363
+	 */
364
+	public function copy($content, $target): bool
365
+	{
366
+		// Security check.
367
+		$this->getContentValidator()->validate($content);
368
+
369
+		$dataType = $content->getDataType();
370
+		$handler = $this->getDataHandlerFactory()->action(ProcessAction::COPY)->forType($dataType)->getDataHandler();
371
+
372
+		$handlerResult = $handler->processCopy($content, $target);
373
+		$this->errorMessages = $handler->getErrorMessages();
374
+		return $handlerResult;
375
+	}
376
+
377
+	/**
378
+	 * Adds an object to this repository.
379
+	 *
380
+	 * @param object $object The object to add
381
+	 * @return void
382
+	 * @api
383
+	 */
384
+	public function add($object)
385
+	{
386
+		throw new \BadMethodCallException('Repository does not support the add() method.', 1375805599);
387
+	}
388
+
389
+	/**
390
+	 * Returns the total number objects of this repository.
391
+	 *
392
+	 * @return integer The object count
393
+	 * @api
394
+	 */
395
+	public function countAll()
396
+	{
397
+		$query = $this->createQuery();
398
+		return $query->count();
399
+	}
400
+
401
+	/**
402
+	 * Removes all objects of this repository as if remove() was called for
403
+	 * all of them.
404
+	 *
405
+	 * @return void
406
+	 * @api
407
+	 */
408
+	public function removeAll()
409
+	{
410
+		// TODO: Implement removeAll() method.
411
+	}
412
+
413
+	/**
414
+	 * Finds an object matching the given identifier.
415
+	 *
416
+	 * @param mixed $identifier The identifier of the object to find
417
+	 * @return Content|null
418
+	 * @api
419
+	 */
420
+	public function findByIdentifier($identifier)
421
+	{
422
+		$query = $this->createQuery();
423
+
424
+		$result = $query->matching(
425
+			$query->equals('uid', $identifier)
426
+		)
427
+			->execute();
428
+
429
+		if (is_array($result)) {
430
+			$result = current($result);
431
+		}
432
+
433
+		return $result;
434
+	}
435
+
436
+	/**
437
+	 * Dispatches magic methods (findBy[Property]())
438
+	 *
439
+	 * @param string $methodName The name of the magic method
440
+	 * @param string $arguments The arguments of the magic method
441
+	 * @return mixed
442
+	 * @api
443
+	 */
444
+	public function __call($methodName, $arguments)
445
+	{
446
+		if (substr($methodName, 0, 6) === 'findBy' && strlen($methodName) > 7) {
447
+			$propertyName = strtolower(substr(substr($methodName, 6), 0, 1)) . substr(substr($methodName, 6), 1);
448
+			$result = $this->processMagicCall($propertyName, $arguments[0]);
449
+		} elseif (substr($methodName, 0, 9) === 'findOneBy' && strlen($methodName) > 10) {
450
+			$propertyName = strtolower(substr(substr($methodName, 9), 0, 1)) . substr(substr($methodName, 9), 1);
451
+			$result = $this->processMagicCall($propertyName, $arguments[0], 'one');
452
+		} elseif (substr($methodName, 0, 7) === 'countBy' && strlen($methodName) > 8) {
453
+			$propertyName = strtolower(substr(substr($methodName, 7), 0, 1)) . substr(substr($methodName, 7), 1);
454
+			$result = $this->processMagicCall($propertyName, $arguments[0], 'count');
455
+		} else {
456
+			throw new UnsupportedMethodException('The method "' . $methodName . '" is not supported by the repository.', 1360838010);
457
+		}
458
+		return $result;
459
+	}
460
+
461
+	/**
462
+	 * Returns a query for objects of this repository
463
+	 *
464
+	 * @return Query
465
+	 * @api
466
+	 */
467
+	public function createQuery()
468
+	{
469
+		/** @var Query $query */
470
+		$query = GeneralUtility::makeInstance(Query::class, $this->dataType);
471
+		$query->setSourceFieldName($this->sourceFieldName);
472
+
473
+		if ($this->defaultQuerySettings) {
474
+			$query->setTypo3QuerySettings($this->defaultQuerySettings);
475
+		} else {
476
+			// Initialize and pass the query settings at this level.
477
+			$querySettings = GeneralUtility::makeInstance(Typo3QuerySettings::class);
478
+
479
+			// Default choice for the BE.
480
+			if ($this->isBackendMode()) {
481
+				$querySettings->setIgnoreEnableFields(true);
482
+			}
483
+
484
+			$query->setTypo3QuerySettings($querySettings);
485
+		}
486
+
487
+		return $query;
488
+	}
489
+
490
+	/**
491
+	 * Sets the property names to order the result by per default.
492
+	 * Expected like this:
493
+	 * array(
494
+	 * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
495
+	 * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
496
+	 * )
497
+	 *
498
+	 * @param array $defaultOrderings The property names to order by
499
+	 * @return void
500
+	 * @api
501
+	 */
502
+	public function setDefaultOrderings(array $defaultOrderings)
503
+	{
504
+		throw new \BadMethodCallException('Repository does not support the setDefaultOrderings() method.', 1375805598);
505
+	}
506
+
507
+	/**
508
+	 * Sets the default query settings to be used in this repository
509
+	 *
510
+	 * @param QuerySettingsInterface $defaultQuerySettings The query settings to be used by default
511
+	 * @return void
512
+	 * @api
513
+	 */
514
+	public function setDefaultQuerySettings(QuerySettingsInterface $defaultQuerySettings)
515
+	{
516
+		$this->defaultQuerySettings = $defaultQuerySettings;
517
+	}
518
+
519
+	/**
520
+	 * @return void
521
+	 */
522
+	public function resetDefaultQuerySettings(): void
523
+	{
524
+		$this->defaultQuerySettings = null;
525
+	}
526
+
527
+
528
+	/**
529
+	 * @return array
530
+	 */
531
+	public function getErrorMessages(): array
532
+	{
533
+		return $this->errorMessages;
534
+	}
535
+
536
+	/**
537
+	 * @param string $sourceFieldName
538
+	 * @return $this
539
+	 */
540
+	public function setSourceFieldName($sourceFieldName): self
541
+	{
542
+		$this->sourceFieldName = $sourceFieldName;
543
+		return $this;
544
+	}
545
+
546
+	/**
547
+	 * @return string
548
+	 */
549
+	public function getDataType(): string
550
+	{
551
+		return $this->dataType;
552
+	}
553
+
554
+	/**
555
+	 * Tell whether the order has a foreign table in its expression, e.g. "metadata.title".
556
+	 *
557
+	 * @param string $ordering
558
+	 * @return bool
559
+	 */
560
+	protected function hasForeignRelationIn($ordering): bool
561
+	{
562
+		return strpos($ordering, '.') !== false;
563
+	}
564
+
565
+	/**
566
+	 * Extract the foreign relation of the ordering "metadata.title" -> "metadata"
567
+	 *
568
+	 * @param string $ordering
569
+	 * @return string
570
+	 */
571
+	protected function getForeignRelationFrom($ordering): string
572
+	{
573
+		$parts = explode('.', $ordering);
574
+		return $parts[0];
575
+	}
576
+
577
+	/**
578
+	 * Get the constraints
579
+	 *
580
+	 * @param Query $query
581
+	 * @param Matcher $matcher
582
+	 * @return ConstraintInterface|null
583
+	 */
584
+	protected function computeConstraints(Query $query, Matcher $matcher): ?ConstraintInterface
585
+	{
586
+		$constraints = null;
587
+
588
+		$collectedConstraints = [];
589
+
590
+		// Search term
591
+		$constraint = $this->computeSearchTermConstraint($query, $matcher);
592
+		if ($constraint) {
593
+			$collectedConstraints[] = $constraint;
594
+		}
595
+
596
+		foreach ($matcher->getSupportedOperators() as $operator) {
597
+			$constraint = $this->computeConstraint($query, $matcher, $operator);
598
+			if ($constraint) {
599
+				$collectedConstraints[] = $constraint;
600
+			}
601
+		}
602
+
603
+		if (count($collectedConstraints) > 1) {
604
+			$logical = $matcher->getDefaultLogicalSeparator();
605
+			$constraints = $query->$logical($collectedConstraints);
606
+		} elseif (!empty($collectedConstraints)) {
607
+			// true means there is one constraint only and should become the result
608
+			$constraints = current($collectedConstraints);
609
+		}
610
+
611
+		// Trigger signal for post processing the computed constraints object.
612
+		$constraints = $this->emitPostProcessConstraintsSignal($query, $constraints);
613
+
614
+		return $constraints;
615
+	}
616
+
617
+	/**
618
+	 * Computes the search constraint and returns it.
619
+	 *
620
+	 * @param Query $query
621
+	 * @param Matcher $matcher
622
+	 * @return ConstraintInterface|null
623
+	 */
624
+	protected function computeSearchTermConstraint(Query $query, Matcher $matcher): ?ConstraintInterface
625
+	{
626
+		$result = null;
627
+
628
+		// Search term case
629
+		if ($matcher->getSearchTerm()) {
630
+			$fields = GeneralUtility::trimExplode(',', Tca::table($this->dataType)->getSearchFields(), true);
631
+
632
+			$constraints = [];
633
+			$likeClause = sprintf('%%%s%%', $matcher->getSearchTerm());
634
+			foreach ($fields as $fieldNameAndPath) {
635
+				if ($this->isSuitableForLike($fieldNameAndPath, $matcher->getSearchTerm())) {
636
+					$dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $this->dataType);
637
+					$fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $this->dataType);
638
+
639
+					if (Tca::table($dataType)->hasField($fieldName) && Tca::table($dataType)->field($fieldName)->hasRelation()) {
640
+						$foreignTable = Tca::table($dataType)->field($fieldName)->getForeignTable();
641
+						$fieldNameAndPath = $fieldNameAndPath . '.' . Tca::table($foreignTable)->getLabelField();
642
+					}
643
+					$constraints[] = $query->like($fieldNameAndPath, $likeClause);
644
+				}
645
+			}
646
+			$logical = $matcher->getLogicalSeparatorForSearchTerm();
647
+			$result = $query->$logical($constraints);
648
+		}
649
+
650
+		return $result;
651
+	}
652
+
653
+	/**
654
+	 * It does not make sense to have a "like" in presence of numerical field, e.g "uid".
655
+	 * Tell whether the given value makes sense for a "like" clause.
656
+	 *
657
+	 * @param string $fieldNameAndPath
658
+	 * @param string $value
659
+	 * @return bool
660
+	 */
661
+	protected function isSuitableForLike($fieldNameAndPath, $value): bool
662
+	{
663
+		$isSuitable = true;
664
+
665
+		// true means it is a string
666
+		if (!MathUtility::canBeInterpretedAsInteger($value)) {
667
+			$dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $this->dataType);
668
+			$fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $this->dataType);
669
+
670
+			if (Tca::table($dataType)->field($fieldName)->isNumerical()
671
+				&& !Tca::table($dataType)->field($fieldName)->hasRelation()
672
+			) {
673
+				$isSuitable = false;
674
+			}
675
+		}
676
+
677
+		return $isSuitable;
678
+	}
679
+
680
+	/**
681
+	 * Computes the constraint for matches and returns it.
682
+	 *
683
+	 * @param Query $query
684
+	 * @param Matcher $matcher
685
+	 * @param string $operator
686
+	 * @return ConstraintInterface|null
687
+	 */
688
+	protected function computeConstraint(Query $query, Matcher $matcher, $operator): ?ConstraintInterface
689
+	{
690
+		$result = null;
691
+
692
+		$operatorName = ucfirst($operator);
693
+		$getCriteria = sprintf('get%s', $operatorName);
694
+		$criteria = $matcher->$getCriteria();
695
+
696
+		if (!empty($criteria)) {
697
+			$constraints = [];
698
+
699
+			foreach ($criteria as $criterion) {
700
+				$fieldNameAndPath = $criterion['fieldNameAndPath'];
701
+				$operand = $criterion['operand'];
702
+
703
+				// Compute a few variables...
704
+				// $dataType is generally equals to $this->dataType but not always... if fieldName is a path.
705
+				$dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $this->dataType);
706
+				$fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $this->dataType);
707
+				$fieldPath = $this->getFieldPathResolver()->stripFieldName($fieldNameAndPath, $this->dataType);
708
+
709
+				if (Tca::table($dataType)->field($fieldName)->hasRelation()) {
710
+					if (MathUtility::canBeInterpretedAsInteger($operand)) {
711
+						$fieldNameAndPath = $fieldName . '.uid';
712
+					} else {
713
+						$foreignTableName = Tca::table($dataType)->field($fieldName)->getForeignTable();
714
+						$foreignTable = Tca::table($foreignTableName);
715
+						$fieldNameAndPath = $fieldName . '.' . $foreignTable->getLabelField();
716
+					}
717
+
718
+					// If different means we should restore the prepended path segment for proper SQL parser.
719
+					// This is true for a composite field, e.g items.sys_file_metadata for categories.
720
+					if ($fieldName !== $fieldPath) {
721
+						$fieldNameAndPath = $fieldPath . '.' . $fieldNameAndPath;
722
+					}
723
+				}
724
+
725
+				if (strpos($operator, 'not') === 0) {
726
+					$strippedOperator = strtolower(substr($operator, 3));
727
+					$constraints[] = $query->logicalNot($query->$strippedOperator($fieldNameAndPath, $criterion['operand']));
728
+				} else {
729
+					$constraints[] = $query->$operator($fieldNameAndPath, $criterion['operand']);
730
+				}
731
+			}
732
+
733
+			$getLogicalSeparator = sprintf('getLogicalSeparatorFor%s', $operatorName);
734
+			$logical = method_exists($matcher, $getLogicalSeparator)
735
+				? $matcher->$getLogicalSeparator()
736
+				: $matcher->getDefaultLogicalSeparator();
737
+
738
+			$result = $query->$logical($constraints);
739
+		}
740
+
741
+		return $result;
742
+	}
743
+
744
+	/**
745
+	 * @return DataHandler
746
+	 */
747
+	protected function getDataHandler(): DataHandler
748
+	{
749
+		if (!$this->dataHandler) {
750
+			$this->dataHandler = GeneralUtility::makeInstance(DataHandler::class);
751
+		}
752
+		return $this->dataHandler;
753
+	}
754
+
755
+	/**
756
+	 * Handle the magic call by properly creating a Query object and returning its result.
757
+	 *
758
+	 * @param string $propertyName
759
+	 * @param string $value
760
+	 * @param string $flag
761
+	 * @return mixed
762
+	 */
763
+	protected function processMagicCall($propertyName, $value, $flag = '')
764
+	{
765
+		$fieldName = Property::name($propertyName)->of($this->dataType)->toFieldName();
766
+
767
+		/** @var $matcher Matcher */
768
+		$matcher = GeneralUtility::makeInstance(Matcher::class, [], $this->getDataType());
769
+
770
+		$table = Tca::table($this->dataType);
771
+		if ($table->field($fieldName)->isGroup()) {
772
+			$valueParts = explode('.', $value, 2);
773
+			$fieldName = $fieldName . '.' . $valueParts[0];
774
+			$value = $valueParts[1];
775
+		}
776
+
777
+		$matcher->equals($fieldName, $value);
778
+
779
+		if ($flag === 'count') {
780
+			$result = $this->countBy($matcher);
781
+		} else {
782
+			$result = $this->findBy($matcher);
783
+		}
784
+		return $flag === 'one' && !empty($result) ? reset($result) : $result;
785
+	}
786
+
787
+	/**
788
+	 * @return DataHandlerFactory|object
789
+	 */
790
+	protected function getDataHandlerFactory()
791
+	{
792
+		return GeneralUtility::makeInstance(DataHandlerFactory::class);
793
+	}
794
+
795
+	/**
796
+	 * Returns whether the current mode is Backend
797
+	 *
798
+	 * @return bool
799
+	 */
800
+	protected function isBackendMode(): bool
801
+	{
802
+		return ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend();
803
+	}
804
+
805
+	/**
806
+	 * @return FieldPathResolver|object
807
+	 */
808
+	protected function getFieldPathResolver()
809
+	{
810
+		return GeneralUtility::makeInstance(FieldPathResolver::class);
811
+	}
812
+
813
+	/**
814
+	 * @return ContentValidator|object
815
+	 */
816
+	protected function getContentValidator(): ContentValidator
817
+	{
818
+		return GeneralUtility::makeInstance(ContentValidator::class);
819
+	}
820
+
821
+	/**
822
+	 * @return LanguageValidator|object
823
+	 */
824
+	protected function getLanguageValidator(): LanguageValidator
825
+	{
826
+		return GeneralUtility::makeInstance(LanguageValidator::class);
827
+	}
828
+
829
+	/**
830
+	 * Signal that is called for post-processing the computed constraints object.
831
+	 *
832
+	 * @param Query $query
833
+	 * @param ConstraintInterface|null $constraints
834
+	 * @return ConstraintInterface|null $constraints
835
+	 */
836
+	protected function emitPostProcessConstraintsSignal(Query $query, $constraints): ?ConstraintInterface
837
+	{
838
+		/** @var ConstraintContainer $constraintContainer */
839
+		$constraintContainer = GeneralUtility::makeInstance(ConstraintContainer::class);
840
+		$result = $this->getSignalSlotDispatcher()->dispatch(
841
+			self::class,
842
+			'postProcessConstraintsObject',
843
+			[
844
+				$query,
845
+				$constraints,
846
+				$constraintContainer
847
+			]
848
+		);
849
+
850
+		// Backward compatibility.
851
+		$processedConstraints = $result[1];
852
+
853
+		// New way to transmit the constraints.
854
+		if ($constraintContainer->getConstraint()) {
855
+			$processedConstraints = $constraintContainer->getConstraint();
856
+		}
857
+		return $processedConstraints;
858
+	}
859
+
860
+	/**
861
+	 * @return Dispatcher
862
+	 */
863
+	protected function getSignalSlotDispatcher(): Dispatcher
864
+	{
865
+		return GeneralUtility::makeInstance(Dispatcher::class);
866
+	}
867 867
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
             foreach ($order->getOrderings() as $ordering => $direction) {
216 216
                 if ($this->hasForeignRelationIn($ordering)) {
217 217
                     $relationalField = $this->getForeignRelationFrom($ordering);
218
-                    $matcher->like($relationalField . '.uid', '');
218
+                    $matcher->like($relationalField.'.uid', '');
219 219
                 }
220 220
             }
221 221
         }
@@ -444,16 +444,16 @@  discard block
 block discarded – undo
444 444
     public function __call($methodName, $arguments)
445 445
     {
446 446
         if (substr($methodName, 0, 6) === 'findBy' && strlen($methodName) > 7) {
447
-            $propertyName = strtolower(substr(substr($methodName, 6), 0, 1)) . substr(substr($methodName, 6), 1);
447
+            $propertyName = strtolower(substr(substr($methodName, 6), 0, 1)).substr(substr($methodName, 6), 1);
448 448
             $result = $this->processMagicCall($propertyName, $arguments[0]);
449 449
         } elseif (substr($methodName, 0, 9) === 'findOneBy' && strlen($methodName) > 10) {
450
-            $propertyName = strtolower(substr(substr($methodName, 9), 0, 1)) . substr(substr($methodName, 9), 1);
450
+            $propertyName = strtolower(substr(substr($methodName, 9), 0, 1)).substr(substr($methodName, 9), 1);
451 451
             $result = $this->processMagicCall($propertyName, $arguments[0], 'one');
452 452
         } elseif (substr($methodName, 0, 7) === 'countBy' && strlen($methodName) > 8) {
453
-            $propertyName = strtolower(substr(substr($methodName, 7), 0, 1)) . substr(substr($methodName, 7), 1);
453
+            $propertyName = strtolower(substr(substr($methodName, 7), 0, 1)).substr(substr($methodName, 7), 1);
454 454
             $result = $this->processMagicCall($propertyName, $arguments[0], 'count');
455 455
         } else {
456
-            throw new UnsupportedMethodException('The method "' . $methodName . '" is not supported by the repository.', 1360838010);
456
+            throw new UnsupportedMethodException('The method "'.$methodName.'" is not supported by the repository.', 1360838010);
457 457
         }
458 458
         return $result;
459 459
     }
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
 
639 639
                     if (Tca::table($dataType)->hasField($fieldName) && Tca::table($dataType)->field($fieldName)->hasRelation()) {
640 640
                         $foreignTable = Tca::table($dataType)->field($fieldName)->getForeignTable();
641
-                        $fieldNameAndPath = $fieldNameAndPath . '.' . Tca::table($foreignTable)->getLabelField();
641
+                        $fieldNameAndPath = $fieldNameAndPath.'.'.Tca::table($foreignTable)->getLabelField();
642 642
                     }
643 643
                     $constraints[] = $query->like($fieldNameAndPath, $likeClause);
644 644
                 }
@@ -708,17 +708,17 @@  discard block
 block discarded – undo
708 708
 
709 709
                 if (Tca::table($dataType)->field($fieldName)->hasRelation()) {
710 710
                     if (MathUtility::canBeInterpretedAsInteger($operand)) {
711
-                        $fieldNameAndPath = $fieldName . '.uid';
711
+                        $fieldNameAndPath = $fieldName.'.uid';
712 712
                     } else {
713 713
                         $foreignTableName = Tca::table($dataType)->field($fieldName)->getForeignTable();
714 714
                         $foreignTable = Tca::table($foreignTableName);
715
-                        $fieldNameAndPath = $fieldName . '.' . $foreignTable->getLabelField();
715
+                        $fieldNameAndPath = $fieldName.'.'.$foreignTable->getLabelField();
716 716
                     }
717 717
 
718 718
                     // If different means we should restore the prepended path segment for proper SQL parser.
719 719
                     // This is true for a composite field, e.g items.sys_file_metadata for categories.
720 720
                     if ($fieldName !== $fieldPath) {
721
-                        $fieldNameAndPath = $fieldPath . '.' . $fieldNameAndPath;
721
+                        $fieldNameAndPath = $fieldPath.'.'.$fieldNameAndPath;
722 722
                     }
723 723
                 }
724 724
 
@@ -770,7 +770,7 @@  discard block
 block discarded – undo
770 770
         $table = Tca::table($this->dataType);
771 771
         if ($table->field($fieldName)->isGroup()) {
772 772
             $valueParts = explode('.', $value, 2);
773
-            $fieldName = $fieldName . '.' . $valueParts[0];
773
+            $fieldName = $fieldName.'.'.$valueParts[0];
774 774
             $value = $valueParts[1];
775 775
         }
776 776
 
Please login to merge, or discard this patch.
Classes/Domain/Repository/ContentRepositoryFactory.php 1 patch
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -17,41 +17,41 @@
 block discarded – undo
17 17
  */
18 18
 class ContentRepositoryFactory implements SingletonInterface
19 19
 {
20
-    /**
21
-     * @var array
22
-     */
23
-    protected static $instances = [];
20
+	/**
21
+	 * @var array
22
+	 */
23
+	protected static $instances = [];
24 24
 
25
-    /**
26
-     * Returns a class instance of a repository.
27
-     * If not data type is given, get the value from the module loader.
28
-     *
29
-     * @param string $dataType
30
-     * @param string $sourceFieldName
31
-     * @return ContentRepository
32
-     */
33
-    public static function getInstance($dataType = null, $sourceFieldName = '')
34
-    {
35
-        /** @var ModuleLoader $moduleLoader */
36
-        if (is_null($dataType)) {
37
-            // Try to get the data type from the module loader.
38
-            $moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
39
-            $dataType = $moduleLoader->getDataType();
40
-        }
25
+	/**
26
+	 * Returns a class instance of a repository.
27
+	 * If not data type is given, get the value from the module loader.
28
+	 *
29
+	 * @param string $dataType
30
+	 * @param string $sourceFieldName
31
+	 * @return ContentRepository
32
+	 */
33
+	public static function getInstance($dataType = null, $sourceFieldName = '')
34
+	{
35
+		/** @var ModuleLoader $moduleLoader */
36
+		if (is_null($dataType)) {
37
+			// Try to get the data type from the module loader.
38
+			$moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
39
+			$dataType = $moduleLoader->getDataType();
40
+		}
41 41
 
42
-        // This should not happen.
43
-        if (!$dataType) {
44
-            throw new \RuntimeException('No data type given nor could be fetched by the module loader.', 1376118278);
45
-        }
42
+		// This should not happen.
43
+		if (!$dataType) {
44
+			throw new \RuntimeException('No data type given nor could be fetched by the module loader.', 1376118278);
45
+		}
46 46
 
47
-        if (empty(self::$instances[$dataType])) {
48
-            $className = 'Fab\Vidi\Domain\Repository\ContentRepository';
49
-            self::$instances[$dataType] = GeneralUtility::makeInstance($className, $dataType, $sourceFieldName);
50
-        }
47
+		if (empty(self::$instances[$dataType])) {
48
+			$className = 'Fab\Vidi\Domain\Repository\ContentRepository';
49
+			self::$instances[$dataType] = GeneralUtility::makeInstance($className, $dataType, $sourceFieldName);
50
+		}
51 51
 
52
-        /** @var ContentRepository $contentRepository */
53
-        $contentRepository = self::$instances[$dataType];
54
-        $contentRepository->setSourceFieldName($sourceFieldName);
55
-        return $contentRepository;
56
-    }
52
+		/** @var ContentRepository $contentRepository */
53
+		$contentRepository = self::$instances[$dataType];
54
+		$contentRepository->setSourceFieldName($sourceFieldName);
55
+		return $contentRepository;
56
+	}
57 57
 }
Please login to merge, or discard this patch.
Classes/Domain/Model/Selection.php 1 patch
Indentation   +141 added lines, -141 removed lines patch added patch discarded remove patch
@@ -16,145 +16,145 @@
 block discarded – undo
16 16
  */
17 17
 class Selection extends AbstractEntity
18 18
 {
19
-    public const VISIBILITY_EVERYONE = 0;
20
-    public const VISIBILITY_PRIVATE = 1;
21
-    public const VISIBILITY_ADMIN_ONLY = 2;
22
-
23
-    /**
24
-     * @var int
25
-     */
26
-    protected $visibility;
27
-
28
-    /**
29
-     * @var string
30
-     */
31
-    protected $name;
32
-
33
-    /**
34
-     * @var string
35
-     */
36
-    protected $dataType;
37
-
38
-    /**
39
-     * @var string
40
-     */
41
-    protected $query;
42
-
43
-    /**
44
-     * @var string
45
-     */
46
-    protected $speakingQuery;
47
-
48
-    /**
49
-     * @var int
50
-     */
51
-    protected $owner;
52
-
53
-    /**
54
-     * @param string $dataType
55
-     * @return $this
56
-     */
57
-    public function setDataType($dataType)
58
-    {
59
-        $this->dataType = $dataType;
60
-        return $this;
61
-    }
62
-
63
-    /**
64
-     * @return string
65
-     */
66
-    public function getDataType()
67
-    {
68
-        return $this->dataType;
69
-    }
70
-
71
-    /**
72
-     * @param string $query
73
-     * @return $this
74
-     */
75
-    public function setQuery($query)
76
-    {
77
-        $this->query = $query;
78
-        return $this;
79
-    }
80
-
81
-    /**
82
-     * @return string
83
-     */
84
-    public function getQuery()
85
-    {
86
-        return $this->query;
87
-    }
88
-
89
-    /**
90
-     * @return string
91
-     */
92
-    public function getSpeakingQuery()
93
-    {
94
-        return $this->speakingQuery;
95
-    }
96
-
97
-    /**
98
-     * @param string $speakingQuery
99
-     * @return $this
100
-     */
101
-    public function setSpeakingQuery($speakingQuery)
102
-    {
103
-        $this->speakingQuery = $speakingQuery;
104
-        return $this;
105
-    }
106
-
107
-    /**
108
-     * @param string $name
109
-     * @return $this
110
-     */
111
-    public function setName($name)
112
-    {
113
-        $this->name = $name;
114
-        return $this;
115
-    }
116
-
117
-    /**
118
-     * @return string
119
-     */
120
-    public function getName()
121
-    {
122
-        return $this->name;
123
-    }
124
-
125
-    /**
126
-     * @param int $visibility
127
-     * @return $this
128
-     */
129
-    public function setVisibility($visibility)
130
-    {
131
-        $this->visibility = $visibility;
132
-        return $this;
133
-    }
134
-
135
-    /**
136
-     * @return int
137
-     */
138
-    public function getVisibility()
139
-    {
140
-        return $this->visibility;
141
-    }
142
-
143
-    /**
144
-     * @return int
145
-     */
146
-    public function getOwner()
147
-    {
148
-        return $this->owner;
149
-    }
150
-
151
-    /**
152
-     * @param int $owner
153
-     * @return $this
154
-     */
155
-    public function setOwner($owner)
156
-    {
157
-        $this->owner = $owner;
158
-        return $this;
159
-    }
19
+	public const VISIBILITY_EVERYONE = 0;
20
+	public const VISIBILITY_PRIVATE = 1;
21
+	public const VISIBILITY_ADMIN_ONLY = 2;
22
+
23
+	/**
24
+	 * @var int
25
+	 */
26
+	protected $visibility;
27
+
28
+	/**
29
+	 * @var string
30
+	 */
31
+	protected $name;
32
+
33
+	/**
34
+	 * @var string
35
+	 */
36
+	protected $dataType;
37
+
38
+	/**
39
+	 * @var string
40
+	 */
41
+	protected $query;
42
+
43
+	/**
44
+	 * @var string
45
+	 */
46
+	protected $speakingQuery;
47
+
48
+	/**
49
+	 * @var int
50
+	 */
51
+	protected $owner;
52
+
53
+	/**
54
+	 * @param string $dataType
55
+	 * @return $this
56
+	 */
57
+	public function setDataType($dataType)
58
+	{
59
+		$this->dataType = $dataType;
60
+		return $this;
61
+	}
62
+
63
+	/**
64
+	 * @return string
65
+	 */
66
+	public function getDataType()
67
+	{
68
+		return $this->dataType;
69
+	}
70
+
71
+	/**
72
+	 * @param string $query
73
+	 * @return $this
74
+	 */
75
+	public function setQuery($query)
76
+	{
77
+		$this->query = $query;
78
+		return $this;
79
+	}
80
+
81
+	/**
82
+	 * @return string
83
+	 */
84
+	public function getQuery()
85
+	{
86
+		return $this->query;
87
+	}
88
+
89
+	/**
90
+	 * @return string
91
+	 */
92
+	public function getSpeakingQuery()
93
+	{
94
+		return $this->speakingQuery;
95
+	}
96
+
97
+	/**
98
+	 * @param string $speakingQuery
99
+	 * @return $this
100
+	 */
101
+	public function setSpeakingQuery($speakingQuery)
102
+	{
103
+		$this->speakingQuery = $speakingQuery;
104
+		return $this;
105
+	}
106
+
107
+	/**
108
+	 * @param string $name
109
+	 * @return $this
110
+	 */
111
+	public function setName($name)
112
+	{
113
+		$this->name = $name;
114
+		return $this;
115
+	}
116
+
117
+	/**
118
+	 * @return string
119
+	 */
120
+	public function getName()
121
+	{
122
+		return $this->name;
123
+	}
124
+
125
+	/**
126
+	 * @param int $visibility
127
+	 * @return $this
128
+	 */
129
+	public function setVisibility($visibility)
130
+	{
131
+		$this->visibility = $visibility;
132
+		return $this;
133
+	}
134
+
135
+	/**
136
+	 * @return int
137
+	 */
138
+	public function getVisibility()
139
+	{
140
+		return $this->visibility;
141
+	}
142
+
143
+	/**
144
+	 * @return int
145
+	 */
146
+	public function getOwner()
147
+	{
148
+		return $this->owner;
149
+	}
150
+
151
+	/**
152
+	 * @param int $owner
153
+	 * @return $this
154
+	 */
155
+	public function setOwner($owner)
156
+	{
157
+		$this->owner = $owner;
158
+		return $this;
159
+	}
160 160
 }
Please login to merge, or discard this patch.
Classes/Domain/Model/Content.php 2 patches
Indentation   +436 added lines, -436 removed lines patch added patch discarded remove patch
@@ -28,440 +28,440 @@
 block discarded – undo
28 28
  */
29 29
 class Content implements \ArrayAccess
30 30
 {
31
-    /**
32
-     * @var int
33
-     */
34
-    protected $uid;
35
-
36
-    /**
37
-     * @var string
38
-     */
39
-    protected $dataType;
40
-
41
-    /**
42
-     * Constructor for a Content object.
43
-     *
44
-     * @param string $dataType will basically correspond to a table name, e.g fe_users, tt_content, ...
45
-     * @param array $contentData
46
-     * @return \Fab\Vidi\Domain\Model\Content
47
-     * @throws \InvalidArgumentException
48
-     * @throws NotExistingClassException
49
-     */
50
-    public function __construct($dataType, array $contentData = array())
51
-    {
52
-        $this->dataType = $dataType;
53
-        $this->uid = empty($contentData['uid']) ? null : (int)$contentData['uid'];
54
-
55
-        /** @var TableService $table */
56
-        $table = Tca::table($dataType);
57
-
58
-        // Initialize the array containing the allowed fields to be filled-in.
59
-        $fields = array('pid');
60
-
61
-        // If a creation time stamp has been defined for this data type.
62
-        if ($table->getTimeCreationField()) {
63
-            $fields[] = $table->getTimeCreationField();
64
-        }
65
-
66
-        // If an update time stamp has been defined for this data type.
67
-        if ($table->getTimeModificationField()) {
68
-            $fields[] = $table->getTimeModificationField();
69
-        }
70
-
71
-        // Merge the other fields allowed for this data type.
72
-        $fields = array_merge($fields, $table->getFields());
73
-
74
-        // Fetch excluded fields from the grid.
75
-        if ($this->isBackendMode()) {
76
-            $fields = $this->filterForConfiguration($fields);
77
-            $fields = $this->filterForBackendUser($fields);
78
-        }
79
-
80
-        // Get column to be displayed
81
-        foreach ($fields as $fieldName) {
82
-            if (array_key_exists($fieldName, $contentData)) {
83
-                $propertyName = Field::name($fieldName)->of($dataType)->toPropertyName();
84
-                $this->$propertyName = $contentData[$fieldName];
85
-            }
86
-        }
87
-    }
88
-
89
-    /**
90
-     * Dispatches magic methods (findBy[Property]())
91
-     *
92
-     * @param string $methodName The name of the magic method
93
-     * @param string $arguments The arguments of the magic method
94
-     * @throws UnsupportedMethodException
95
-     * @return mixed
96
-     * @api
97
-     */
98
-    public function __call($methodName, $arguments)
99
-    {
100
-        $value = null;
101
-        if (substr($methodName, 0, 3) === 'get' && strlen($methodName) > 4) {
102
-            $propertyName = strtolower(substr(substr($methodName, 3), 0, 1)) . substr(substr($methodName, 3), 1);
103
-
104
-            $fieldName = Property::name($propertyName)->of($this)->toFieldName();
105
-            $field = Tca::table($this->dataType)->field($fieldName);
106
-
107
-            $value = $this->$propertyName;
108
-
109
-            // true means it is a relation and it is not yet resolved.
110
-            if ($this->hasRelation($propertyName) && is_scalar($this->$propertyName)) {
111
-                $value = $this->resolveRelation($propertyName);
112
-            } elseif ($field->getType() === FieldType::RADIO || $field->getType() === FieldType::SELECT) {
113
-                // Attempt to convert the value into a label for radio and select fields.
114
-                $label = Tca::table($this->getDataType())->field($fieldName)->getLabelForItem($value);
115
-                if ($label) {
116
-                    $value = $label;
117
-                }
118
-            }
119
-        } elseif (substr($methodName, 0, 3) === 'set' && strlen($methodName) > 4 && isset($arguments[0])) {
120
-            $propertyName = strtolower(substr(substr($methodName, 3), 0, 1)) . substr(substr($methodName, 3), 1);
121
-            $this->$propertyName = $arguments[0];
122
-        }
123
-        return $value;
124
-    }
125
-
126
-    /**
127
-     * Tell whether the property has a relation.
128
-     *
129
-     * @param string $propertyName
130
-     * @return bool
131
-     */
132
-    protected function hasRelation($propertyName)
133
-    {
134
-        $fieldName = Property::name($propertyName)->of($this)->toFieldName();
135
-        return Tca::table($this->dataType)->field($fieldName)->hasRelation();
136
-    }
137
-
138
-    /**
139
-     * Try to "resolve" the property whether it has a relation.
140
-     * If the property has not relation it simply returns the same value.
141
-     *
142
-     * @throws \RuntimeException
143
-     * @param string $propertyName
144
-     * @return mixed
145
-     */
146
-    protected function resolveRelation($propertyName)
147
-    {
148
-        // Convert property name to field name and get the foreign data type.
149
-        $fieldName = Property::name($propertyName)->of($this)->toFieldName();
150
-        $foreignDataType = Tca::table($this->dataType)->field($fieldName)->relationDataType();
151
-
152
-        // Get the foreign repository instance form the factory
153
-        /** @var ContentRepository $foreignContentRepository */
154
-        $foreignContentRepository = ContentRepositoryFactory::getInstance($foreignDataType, $fieldName);
155
-
156
-        if (Tca::table($this->dataType)->field($fieldName)->hasRelationWithCommaSeparatedValues()) {
157
-            // Fetch values from repository
158
-            $values = GeneralUtility::trimExplode(',', $this->$propertyName);
159
-            $this->$propertyName = $foreignContentRepository->findIn('uid', $values);
160
-        } elseif (Tca::table($this->dataType)->field($fieldName)->hasMany()) {
161
-            // Include relation many-to-many and one-to-many
162
-            // Tca::table($this->dataType)->field($fieldName)->hasRelationOneToMany()
163
-            // Tca::table($this->dataType)->field($fieldName)->hasRelationManyToMany()
164
-
165
-            $foreignFieldName = Tca::table($this->dataType)->field($fieldName)->getForeignField();
166
-            if (empty($foreignFieldName)) {
167
-                $message = sprintf(
168
-                    'Missing "foreign_field" key for field "%s" in table "%s".',
169
-                    $fieldName,
170
-                    $this->dataType
171
-                );
172
-                throw new \RuntimeException($message, 1376149186);
173
-            }
174
-
175
-            // Fetch values from repository.
176
-            $foreignPropertyName = Field::name($foreignFieldName)->of($this)->toPropertyName();
177
-            $findByProperty = 'findBy' . ucfirst($foreignPropertyName);
178
-
179
-            // Date picker (type == group) are special fields because property path must contain the table name
180
-            // to determine the relation type. Example for sys_category, property path will look like "items.sys_file"
181
-            $propertyValue = $this->uid;
182
-            if (Tca::table($foreignDataType)->field($foreignFieldName)->isGroup()) {
183
-                $propertyValue = $this->dataType . '.' . $this->uid;
184
-            }
185
-
186
-            $this->$propertyName = $foreignContentRepository->$findByProperty($propertyValue);
187
-        } elseif (Tca::table($this->dataType)->field($fieldName)->hasOne()) {
188
-            $fieldConfiguration = Tca::table($this->dataType)->field($fieldName)->getConfiguration();
189
-
190
-            // First case, we are on the "good side" of the relation, just query the repository
191
-            if (empty($fieldConfiguration['foreign_field'])) {
192
-                $this->$propertyName = $foreignContentRepository->findByUid($this->$propertyName);
193
-            } else {
194
-                // Second case, we are the "bad side" of the relation, query the foreign repository
195
-                // e.g. in case of one-to-one relation.
196
-
197
-                // We must query the opposite side to get the identifier of the foreign object.
198
-                $foreignDataType = Tca::table($this->dataType)->field($fieldName)->getForeignTable();
199
-                $foreignField = Tca::table($this->dataType)->field($fieldName)->getForeignField();
200
-                $foreignContentRepository = ContentRepositoryFactory::getInstance($foreignDataType);
201
-                $find = 'findOneBy' . GeneralUtility::underscoredToUpperCamelCase($foreignField);
202
-
203
-                /** @var Content $foreignObject */
204
-                $this->$propertyName = $foreignContentRepository->$find($this->getUid());
205
-            }
206
-        }
207
-        return $this->$propertyName;
208
-    }
209
-
210
-    /**
211
-     * @return int
212
-     */
213
-    public function getUid()
214
-    {
215
-        return $this->uid;
216
-    }
217
-
218
-    /**
219
-     * @return string
220
-     */
221
-    public function getDataType()
222
-    {
223
-        return $this->dataType;
224
-    }
225
-
226
-    /**
227
-     * Whether a offset exists
228
-     *
229
-     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
230
-     * @param mixed $offset
231
-     * @return boolean true on success or false on failure.
232
-     * @throws \RuntimeException
233
-     * @throws \InvalidArgumentException
234
-     */
235
-    public function offsetExists($offset)
236
-    {
237
-        $offset = Field::name($offset)->of($this)->toPropertyName();
238
-        return isset($this->$offset);
239
-    }
240
-
241
-    /**
242
-     * Offset to retrieve
243
-     *
244
-     * @link http://php.net/manual/en/arrayaccess.offsetget.php
245
-     * @param mixed $offset
246
-     * @return mixed Can return all value types.
247
-     * @throws \RuntimeException
248
-     * @throws \InvalidArgumentException
249
-     */
250
-    public function offsetGet($offset)
251
-    {
252
-        $offset = Field::name($offset)->of($this)->toPropertyName();
253
-        $getter = 'get' . ucfirst($offset);
254
-        return $this->$getter();
255
-    }
256
-
257
-    /**
258
-     * Offset to set
259
-     *
260
-     * @link http://php.net/manual/en/arrayaccess.offsetset.php
261
-     * @param mixed $offset
262
-     * @param mixed $value
263
-     * @return $this
264
-     * @throws \RuntimeException
265
-     * @throws \InvalidArgumentException
266
-     */
267
-    public function offsetSet($offset, $value)
268
-    {
269
-        $offset = Field::name($offset)->of($this)->toPropertyName();
270
-        $setter = 'set' . ucfirst($offset);
271
-        $this->$setter($value);
272
-        return $this;
273
-    }
274
-
275
-    /**
276
-     * Offset to unset
277
-     *
278
-     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
279
-     * @param mixed $offset
280
-     * @throws NotImplementedException
281
-     * @return void
282
-     */
283
-    public function offsetUnset($offset)
284
-    {
285
-        $message = 'Un-setting value for Array object is not supported';
286
-        throw new NotImplementedException($message, 1376132306);
287
-    }
288
-
289
-    /**
290
-     * Convert this to array
291
-     *
292
-     * @return array
293
-     * @throws \InvalidArgumentException
294
-     */
295
-    public function toArray()
296
-    {
297
-        $result['uid'] = $this->uid;
298
-        $propertiesAndValues = json_decode(json_encode($this), true);
299
-
300
-        foreach ($propertiesAndValues as $propertyName => $value) {
301
-            $fieldName = Property::name($propertyName)->of($this)->toFieldName();
302
-            $result[$fieldName] = $value;
303
-        }
304
-
305
-        return $result;
306
-    }
307
-
308
-    /**
309
-     * Convert this object to an array containing the resolved values.
310
-     *
311
-     * @param bool $resolveRelations
312
-     * @return array
313
-     * @throws \Exception
314
-     */
315
-    public function toValues($resolveRelations = true)
316
-    {
317
-        $result['uid'] = $this->uid;
318
-        $propertiesAndValues = json_decode(json_encode($this), true);
319
-
320
-        foreach ($propertiesAndValues as $propertyName => $value) {
321
-            $fieldName = Property::name($propertyName)->of($this)->toFieldName();
322
-
323
-            $result[$fieldName] = $value;
324
-            if ($resolveRelations) {
325
-                $field = Tca::table($this->dataType)->field($fieldName);
326
-
327
-                $resolvedValue = '';
328
-                if ($field->getType() === FieldType::FILE) {
329
-                    if ($field->hasMany()) {
330
-                        $files = FileReferenceService::getInstance()->findReferencedBy($propertyName, $this);
331
-
332
-                        $resolvedValue = [];
333
-                        foreach ($files as $file) {
334
-                            $resolvedValue[] = $file->getIdentifier();
335
-                        }
336
-                    } else {
337
-                        $files = FileReferenceService::getInstance()->findReferencedBy($propertyName, $this);
338
-                        if (!empty($files)) {
339
-                            $resolvedValue = current($files)->getIdentifier();
340
-                        }
341
-                    }
342
-
343
-                    // Reset value
344
-                    $result[$fieldName] = $resolvedValue;
345
-                } elseif (Tca::table($this->dataType)->field($fieldName)->hasRelation()) {
346
-                    $objects = $this[$fieldName];
347
-                    if (is_array($objects)) {
348
-                        $resolvedValue = [];
349
-                        foreach ($objects as $object) {
350
-                            /** @var $object Content */
351
-                            $labelField = Tca::table($object->getDataType())->getLabelField();
352
-                            $resolvedValue[] = $object[$labelField];
353
-                        }
354
-                    } elseif ($objects instanceof Content) {
355
-                        $labelField = Tca::table($objects->getDataType())->getLabelField();
356
-                        $resolvedValue = $objects[$labelField];
357
-                    }
358
-
359
-                    // Reset value
360
-                    $result[$fieldName] = $resolvedValue;
361
-                }
362
-            }
363
-        }
364
-
365
-        return $result;
366
-    }
367
-
368
-    /**
369
-     * Return the properties of this object.
370
-     *
371
-     * @return array
372
-     */
373
-    public function toProperties()
374
-    {
375
-        $result[] = 'uid';
376
-        $propertiesAndValues = json_decode(json_encode($this), true);
377
-
378
-        foreach ($propertiesAndValues as $propertyName => $value) {
379
-            $result[] = $propertyName;
380
-        }
381
-        return $result;
382
-    }
383
-
384
-    /**
385
-     * Return the properties of this object.
386
-     *
387
-     * @return array
388
-     */
389
-    public function toFields()
390
-    {
391
-        $result[] = 'uid';
392
-        $propertiesAndValues = json_decode(json_encode($this), true);
393
-
394
-        foreach ($propertiesAndValues as $propertyName => $value) {
395
-            $result[] = Property::name($propertyName)->of($this)->toFieldName();
396
-        }
397
-
398
-        return $result;
399
-    }
400
-
401
-    /**
402
-     * @return string
403
-     */
404
-    public function __toString()
405
-    {
406
-        $labelField = Tca::table($this->dataType)->getLabelField();
407
-        return $this[$labelField];
408
-    }
409
-
410
-    /**
411
-     * Remove fields according to BE User permission.
412
-     *
413
-     * @param $fields
414
-     * @return array
415
-     * @throws \Exception
416
-     */
417
-    protected function filterForBackendUser($fields)
418
-    {
419
-        if (!$this->getBackendUser()->isAdmin()) {
420
-            foreach ($fields as $key => $fieldName) {
421
-                if (Tca::table($this->dataType)->hasField($fieldName) && !Tca::table($this->dataType)->field($fieldName)->hasAccess()) {
422
-                    unset($fields[$key]);
423
-                }
424
-            }
425
-        }
426
-        return $fields;
427
-    }
428
-
429
-    /**
430
-     * Remove fields according to Grid configuration.
431
-     *
432
-     * @param $fields
433
-     * @return array
434
-     */
435
-    protected function filterForConfiguration($fields)
436
-    {
437
-        $excludedFields = Tca::grid($this->dataType)->getExcludedFields();
438
-        foreach ($fields as $key => $field) {
439
-            if (in_array($field, $excludedFields)) {
440
-                unset($fields[$key]);
441
-            }
442
-        }
443
-
444
-        return $fields;
445
-    }
446
-
447
-    /**
448
-     * Returns an instance of the current Backend User.
449
-     *
450
-     * @return BackendUserAuthentication
451
-     */
452
-    protected function getBackendUser()
453
-    {
454
-        return $GLOBALS['BE_USER'];
455
-    }
456
-
457
-    /**
458
-     * Returns whether the current mode is Backend
459
-     *
460
-     * @return bool
461
-     */
462
-    protected function isBackendMode()
463
-    {
464
-        return ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend();
465
-        ;
466
-    }
31
+	/**
32
+	 * @var int
33
+	 */
34
+	protected $uid;
35
+
36
+	/**
37
+	 * @var string
38
+	 */
39
+	protected $dataType;
40
+
41
+	/**
42
+	 * Constructor for a Content object.
43
+	 *
44
+	 * @param string $dataType will basically correspond to a table name, e.g fe_users, tt_content, ...
45
+	 * @param array $contentData
46
+	 * @return \Fab\Vidi\Domain\Model\Content
47
+	 * @throws \InvalidArgumentException
48
+	 * @throws NotExistingClassException
49
+	 */
50
+	public function __construct($dataType, array $contentData = array())
51
+	{
52
+		$this->dataType = $dataType;
53
+		$this->uid = empty($contentData['uid']) ? null : (int)$contentData['uid'];
54
+
55
+		/** @var TableService $table */
56
+		$table = Tca::table($dataType);
57
+
58
+		// Initialize the array containing the allowed fields to be filled-in.
59
+		$fields = array('pid');
60
+
61
+		// If a creation time stamp has been defined for this data type.
62
+		if ($table->getTimeCreationField()) {
63
+			$fields[] = $table->getTimeCreationField();
64
+		}
65
+
66
+		// If an update time stamp has been defined for this data type.
67
+		if ($table->getTimeModificationField()) {
68
+			$fields[] = $table->getTimeModificationField();
69
+		}
70
+
71
+		// Merge the other fields allowed for this data type.
72
+		$fields = array_merge($fields, $table->getFields());
73
+
74
+		// Fetch excluded fields from the grid.
75
+		if ($this->isBackendMode()) {
76
+			$fields = $this->filterForConfiguration($fields);
77
+			$fields = $this->filterForBackendUser($fields);
78
+		}
79
+
80
+		// Get column to be displayed
81
+		foreach ($fields as $fieldName) {
82
+			if (array_key_exists($fieldName, $contentData)) {
83
+				$propertyName = Field::name($fieldName)->of($dataType)->toPropertyName();
84
+				$this->$propertyName = $contentData[$fieldName];
85
+			}
86
+		}
87
+	}
88
+
89
+	/**
90
+	 * Dispatches magic methods (findBy[Property]())
91
+	 *
92
+	 * @param string $methodName The name of the magic method
93
+	 * @param string $arguments The arguments of the magic method
94
+	 * @throws UnsupportedMethodException
95
+	 * @return mixed
96
+	 * @api
97
+	 */
98
+	public function __call($methodName, $arguments)
99
+	{
100
+		$value = null;
101
+		if (substr($methodName, 0, 3) === 'get' && strlen($methodName) > 4) {
102
+			$propertyName = strtolower(substr(substr($methodName, 3), 0, 1)) . substr(substr($methodName, 3), 1);
103
+
104
+			$fieldName = Property::name($propertyName)->of($this)->toFieldName();
105
+			$field = Tca::table($this->dataType)->field($fieldName);
106
+
107
+			$value = $this->$propertyName;
108
+
109
+			// true means it is a relation and it is not yet resolved.
110
+			if ($this->hasRelation($propertyName) && is_scalar($this->$propertyName)) {
111
+				$value = $this->resolveRelation($propertyName);
112
+			} elseif ($field->getType() === FieldType::RADIO || $field->getType() === FieldType::SELECT) {
113
+				// Attempt to convert the value into a label for radio and select fields.
114
+				$label = Tca::table($this->getDataType())->field($fieldName)->getLabelForItem($value);
115
+				if ($label) {
116
+					$value = $label;
117
+				}
118
+			}
119
+		} elseif (substr($methodName, 0, 3) === 'set' && strlen($methodName) > 4 && isset($arguments[0])) {
120
+			$propertyName = strtolower(substr(substr($methodName, 3), 0, 1)) . substr(substr($methodName, 3), 1);
121
+			$this->$propertyName = $arguments[0];
122
+		}
123
+		return $value;
124
+	}
125
+
126
+	/**
127
+	 * Tell whether the property has a relation.
128
+	 *
129
+	 * @param string $propertyName
130
+	 * @return bool
131
+	 */
132
+	protected function hasRelation($propertyName)
133
+	{
134
+		$fieldName = Property::name($propertyName)->of($this)->toFieldName();
135
+		return Tca::table($this->dataType)->field($fieldName)->hasRelation();
136
+	}
137
+
138
+	/**
139
+	 * Try to "resolve" the property whether it has a relation.
140
+	 * If the property has not relation it simply returns the same value.
141
+	 *
142
+	 * @throws \RuntimeException
143
+	 * @param string $propertyName
144
+	 * @return mixed
145
+	 */
146
+	protected function resolveRelation($propertyName)
147
+	{
148
+		// Convert property name to field name and get the foreign data type.
149
+		$fieldName = Property::name($propertyName)->of($this)->toFieldName();
150
+		$foreignDataType = Tca::table($this->dataType)->field($fieldName)->relationDataType();
151
+
152
+		// Get the foreign repository instance form the factory
153
+		/** @var ContentRepository $foreignContentRepository */
154
+		$foreignContentRepository = ContentRepositoryFactory::getInstance($foreignDataType, $fieldName);
155
+
156
+		if (Tca::table($this->dataType)->field($fieldName)->hasRelationWithCommaSeparatedValues()) {
157
+			// Fetch values from repository
158
+			$values = GeneralUtility::trimExplode(',', $this->$propertyName);
159
+			$this->$propertyName = $foreignContentRepository->findIn('uid', $values);
160
+		} elseif (Tca::table($this->dataType)->field($fieldName)->hasMany()) {
161
+			// Include relation many-to-many and one-to-many
162
+			// Tca::table($this->dataType)->field($fieldName)->hasRelationOneToMany()
163
+			// Tca::table($this->dataType)->field($fieldName)->hasRelationManyToMany()
164
+
165
+			$foreignFieldName = Tca::table($this->dataType)->field($fieldName)->getForeignField();
166
+			if (empty($foreignFieldName)) {
167
+				$message = sprintf(
168
+					'Missing "foreign_field" key for field "%s" in table "%s".',
169
+					$fieldName,
170
+					$this->dataType
171
+				);
172
+				throw new \RuntimeException($message, 1376149186);
173
+			}
174
+
175
+			// Fetch values from repository.
176
+			$foreignPropertyName = Field::name($foreignFieldName)->of($this)->toPropertyName();
177
+			$findByProperty = 'findBy' . ucfirst($foreignPropertyName);
178
+
179
+			// Date picker (type == group) are special fields because property path must contain the table name
180
+			// to determine the relation type. Example for sys_category, property path will look like "items.sys_file"
181
+			$propertyValue = $this->uid;
182
+			if (Tca::table($foreignDataType)->field($foreignFieldName)->isGroup()) {
183
+				$propertyValue = $this->dataType . '.' . $this->uid;
184
+			}
185
+
186
+			$this->$propertyName = $foreignContentRepository->$findByProperty($propertyValue);
187
+		} elseif (Tca::table($this->dataType)->field($fieldName)->hasOne()) {
188
+			$fieldConfiguration = Tca::table($this->dataType)->field($fieldName)->getConfiguration();
189
+
190
+			// First case, we are on the "good side" of the relation, just query the repository
191
+			if (empty($fieldConfiguration['foreign_field'])) {
192
+				$this->$propertyName = $foreignContentRepository->findByUid($this->$propertyName);
193
+			} else {
194
+				// Second case, we are the "bad side" of the relation, query the foreign repository
195
+				// e.g. in case of one-to-one relation.
196
+
197
+				// We must query the opposite side to get the identifier of the foreign object.
198
+				$foreignDataType = Tca::table($this->dataType)->field($fieldName)->getForeignTable();
199
+				$foreignField = Tca::table($this->dataType)->field($fieldName)->getForeignField();
200
+				$foreignContentRepository = ContentRepositoryFactory::getInstance($foreignDataType);
201
+				$find = 'findOneBy' . GeneralUtility::underscoredToUpperCamelCase($foreignField);
202
+
203
+				/** @var Content $foreignObject */
204
+				$this->$propertyName = $foreignContentRepository->$find($this->getUid());
205
+			}
206
+		}
207
+		return $this->$propertyName;
208
+	}
209
+
210
+	/**
211
+	 * @return int
212
+	 */
213
+	public function getUid()
214
+	{
215
+		return $this->uid;
216
+	}
217
+
218
+	/**
219
+	 * @return string
220
+	 */
221
+	public function getDataType()
222
+	{
223
+		return $this->dataType;
224
+	}
225
+
226
+	/**
227
+	 * Whether a offset exists
228
+	 *
229
+	 * @link http://php.net/manual/en/arrayaccess.offsetexists.php
230
+	 * @param mixed $offset
231
+	 * @return boolean true on success or false on failure.
232
+	 * @throws \RuntimeException
233
+	 * @throws \InvalidArgumentException
234
+	 */
235
+	public function offsetExists($offset)
236
+	{
237
+		$offset = Field::name($offset)->of($this)->toPropertyName();
238
+		return isset($this->$offset);
239
+	}
240
+
241
+	/**
242
+	 * Offset to retrieve
243
+	 *
244
+	 * @link http://php.net/manual/en/arrayaccess.offsetget.php
245
+	 * @param mixed $offset
246
+	 * @return mixed Can return all value types.
247
+	 * @throws \RuntimeException
248
+	 * @throws \InvalidArgumentException
249
+	 */
250
+	public function offsetGet($offset)
251
+	{
252
+		$offset = Field::name($offset)->of($this)->toPropertyName();
253
+		$getter = 'get' . ucfirst($offset);
254
+		return $this->$getter();
255
+	}
256
+
257
+	/**
258
+	 * Offset to set
259
+	 *
260
+	 * @link http://php.net/manual/en/arrayaccess.offsetset.php
261
+	 * @param mixed $offset
262
+	 * @param mixed $value
263
+	 * @return $this
264
+	 * @throws \RuntimeException
265
+	 * @throws \InvalidArgumentException
266
+	 */
267
+	public function offsetSet($offset, $value)
268
+	{
269
+		$offset = Field::name($offset)->of($this)->toPropertyName();
270
+		$setter = 'set' . ucfirst($offset);
271
+		$this->$setter($value);
272
+		return $this;
273
+	}
274
+
275
+	/**
276
+	 * Offset to unset
277
+	 *
278
+	 * @link http://php.net/manual/en/arrayaccess.offsetunset.php
279
+	 * @param mixed $offset
280
+	 * @throws NotImplementedException
281
+	 * @return void
282
+	 */
283
+	public function offsetUnset($offset)
284
+	{
285
+		$message = 'Un-setting value for Array object is not supported';
286
+		throw new NotImplementedException($message, 1376132306);
287
+	}
288
+
289
+	/**
290
+	 * Convert this to array
291
+	 *
292
+	 * @return array
293
+	 * @throws \InvalidArgumentException
294
+	 */
295
+	public function toArray()
296
+	{
297
+		$result['uid'] = $this->uid;
298
+		$propertiesAndValues = json_decode(json_encode($this), true);
299
+
300
+		foreach ($propertiesAndValues as $propertyName => $value) {
301
+			$fieldName = Property::name($propertyName)->of($this)->toFieldName();
302
+			$result[$fieldName] = $value;
303
+		}
304
+
305
+		return $result;
306
+	}
307
+
308
+	/**
309
+	 * Convert this object to an array containing the resolved values.
310
+	 *
311
+	 * @param bool $resolveRelations
312
+	 * @return array
313
+	 * @throws \Exception
314
+	 */
315
+	public function toValues($resolveRelations = true)
316
+	{
317
+		$result['uid'] = $this->uid;
318
+		$propertiesAndValues = json_decode(json_encode($this), true);
319
+
320
+		foreach ($propertiesAndValues as $propertyName => $value) {
321
+			$fieldName = Property::name($propertyName)->of($this)->toFieldName();
322
+
323
+			$result[$fieldName] = $value;
324
+			if ($resolveRelations) {
325
+				$field = Tca::table($this->dataType)->field($fieldName);
326
+
327
+				$resolvedValue = '';
328
+				if ($field->getType() === FieldType::FILE) {
329
+					if ($field->hasMany()) {
330
+						$files = FileReferenceService::getInstance()->findReferencedBy($propertyName, $this);
331
+
332
+						$resolvedValue = [];
333
+						foreach ($files as $file) {
334
+							$resolvedValue[] = $file->getIdentifier();
335
+						}
336
+					} else {
337
+						$files = FileReferenceService::getInstance()->findReferencedBy($propertyName, $this);
338
+						if (!empty($files)) {
339
+							$resolvedValue = current($files)->getIdentifier();
340
+						}
341
+					}
342
+
343
+					// Reset value
344
+					$result[$fieldName] = $resolvedValue;
345
+				} elseif (Tca::table($this->dataType)->field($fieldName)->hasRelation()) {
346
+					$objects = $this[$fieldName];
347
+					if (is_array($objects)) {
348
+						$resolvedValue = [];
349
+						foreach ($objects as $object) {
350
+							/** @var $object Content */
351
+							$labelField = Tca::table($object->getDataType())->getLabelField();
352
+							$resolvedValue[] = $object[$labelField];
353
+						}
354
+					} elseif ($objects instanceof Content) {
355
+						$labelField = Tca::table($objects->getDataType())->getLabelField();
356
+						$resolvedValue = $objects[$labelField];
357
+					}
358
+
359
+					// Reset value
360
+					$result[$fieldName] = $resolvedValue;
361
+				}
362
+			}
363
+		}
364
+
365
+		return $result;
366
+	}
367
+
368
+	/**
369
+	 * Return the properties of this object.
370
+	 *
371
+	 * @return array
372
+	 */
373
+	public function toProperties()
374
+	{
375
+		$result[] = 'uid';
376
+		$propertiesAndValues = json_decode(json_encode($this), true);
377
+
378
+		foreach ($propertiesAndValues as $propertyName => $value) {
379
+			$result[] = $propertyName;
380
+		}
381
+		return $result;
382
+	}
383
+
384
+	/**
385
+	 * Return the properties of this object.
386
+	 *
387
+	 * @return array
388
+	 */
389
+	public function toFields()
390
+	{
391
+		$result[] = 'uid';
392
+		$propertiesAndValues = json_decode(json_encode($this), true);
393
+
394
+		foreach ($propertiesAndValues as $propertyName => $value) {
395
+			$result[] = Property::name($propertyName)->of($this)->toFieldName();
396
+		}
397
+
398
+		return $result;
399
+	}
400
+
401
+	/**
402
+	 * @return string
403
+	 */
404
+	public function __toString()
405
+	{
406
+		$labelField = Tca::table($this->dataType)->getLabelField();
407
+		return $this[$labelField];
408
+	}
409
+
410
+	/**
411
+	 * Remove fields according to BE User permission.
412
+	 *
413
+	 * @param $fields
414
+	 * @return array
415
+	 * @throws \Exception
416
+	 */
417
+	protected function filterForBackendUser($fields)
418
+	{
419
+		if (!$this->getBackendUser()->isAdmin()) {
420
+			foreach ($fields as $key => $fieldName) {
421
+				if (Tca::table($this->dataType)->hasField($fieldName) && !Tca::table($this->dataType)->field($fieldName)->hasAccess()) {
422
+					unset($fields[$key]);
423
+				}
424
+			}
425
+		}
426
+		return $fields;
427
+	}
428
+
429
+	/**
430
+	 * Remove fields according to Grid configuration.
431
+	 *
432
+	 * @param $fields
433
+	 * @return array
434
+	 */
435
+	protected function filterForConfiguration($fields)
436
+	{
437
+		$excludedFields = Tca::grid($this->dataType)->getExcludedFields();
438
+		foreach ($fields as $key => $field) {
439
+			if (in_array($field, $excludedFields)) {
440
+				unset($fields[$key]);
441
+			}
442
+		}
443
+
444
+		return $fields;
445
+	}
446
+
447
+	/**
448
+	 * Returns an instance of the current Backend User.
449
+	 *
450
+	 * @return BackendUserAuthentication
451
+	 */
452
+	protected function getBackendUser()
453
+	{
454
+		return $GLOBALS['BE_USER'];
455
+	}
456
+
457
+	/**
458
+	 * Returns whether the current mode is Backend
459
+	 *
460
+	 * @return bool
461
+	 */
462
+	protected function isBackendMode()
463
+	{
464
+		return ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend();
465
+		;
466
+	}
467 467
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
     {
100 100
         $value = null;
101 101
         if (substr($methodName, 0, 3) === 'get' && strlen($methodName) > 4) {
102
-            $propertyName = strtolower(substr(substr($methodName, 3), 0, 1)) . substr(substr($methodName, 3), 1);
102
+            $propertyName = strtolower(substr(substr($methodName, 3), 0, 1)).substr(substr($methodName, 3), 1);
103 103
 
104 104
             $fieldName = Property::name($propertyName)->of($this)->toFieldName();
105 105
             $field = Tca::table($this->dataType)->field($fieldName);
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
                 }
118 118
             }
119 119
         } elseif (substr($methodName, 0, 3) === 'set' && strlen($methodName) > 4 && isset($arguments[0])) {
120
-            $propertyName = strtolower(substr(substr($methodName, 3), 0, 1)) . substr(substr($methodName, 3), 1);
120
+            $propertyName = strtolower(substr(substr($methodName, 3), 0, 1)).substr(substr($methodName, 3), 1);
121 121
             $this->$propertyName = $arguments[0];
122 122
         }
123 123
         return $value;
@@ -174,13 +174,13 @@  discard block
 block discarded – undo
174 174
 
175 175
             // Fetch values from repository.
176 176
             $foreignPropertyName = Field::name($foreignFieldName)->of($this)->toPropertyName();
177
-            $findByProperty = 'findBy' . ucfirst($foreignPropertyName);
177
+            $findByProperty = 'findBy'.ucfirst($foreignPropertyName);
178 178
 
179 179
             // Date picker (type == group) are special fields because property path must contain the table name
180 180
             // to determine the relation type. Example for sys_category, property path will look like "items.sys_file"
181 181
             $propertyValue = $this->uid;
182 182
             if (Tca::table($foreignDataType)->field($foreignFieldName)->isGroup()) {
183
-                $propertyValue = $this->dataType . '.' . $this->uid;
183
+                $propertyValue = $this->dataType.'.'.$this->uid;
184 184
             }
185 185
 
186 186
             $this->$propertyName = $foreignContentRepository->$findByProperty($propertyValue);
@@ -198,7 +198,7 @@  discard block
 block discarded – undo
198 198
                 $foreignDataType = Tca::table($this->dataType)->field($fieldName)->getForeignTable();
199 199
                 $foreignField = Tca::table($this->dataType)->field($fieldName)->getForeignField();
200 200
                 $foreignContentRepository = ContentRepositoryFactory::getInstance($foreignDataType);
201
-                $find = 'findOneBy' . GeneralUtility::underscoredToUpperCamelCase($foreignField);
201
+                $find = 'findOneBy'.GeneralUtility::underscoredToUpperCamelCase($foreignField);
202 202
 
203 203
                 /** @var Content $foreignObject */
204 204
                 $this->$propertyName = $foreignContentRepository->$find($this->getUid());
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
     public function offsetGet($offset)
251 251
     {
252 252
         $offset = Field::name($offset)->of($this)->toPropertyName();
253
-        $getter = 'get' . ucfirst($offset);
253
+        $getter = 'get'.ucfirst($offset);
254 254
         return $this->$getter();
255 255
     }
256 256
 
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
     public function offsetSet($offset, $value)
268 268
     {
269 269
         $offset = Field::name($offset)->of($this)->toPropertyName();
270
-        $setter = 'set' . ucfirst($offset);
270
+        $setter = 'set'.ucfirst($offset);
271 271
         $this->$setter($value);
272 272
         return $this;
273 273
     }
Please login to merge, or discard this patch.
Classes/Domain/Validator/LanguageValidator.php 2 patches
Indentation   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -16,25 +16,25 @@
 block discarded – undo
16 16
  */
17 17
 class LanguageValidator
18 18
 {
19
-    /**
20
-     * Check whether the $language is valid.
21
-     *
22
-     * @param int $language
23
-     * @throws \Exception
24
-     * @return void
25
-     */
26
-    public function validate($language)
27
-    {
28
-        if (!$this->getLanguageService()->languageExists((int)$language)) {
29
-            throw new \Exception('The language "' . $language . '" does not exist', 1351605542);
30
-        }
31
-    }
19
+	/**
20
+	 * Check whether the $language is valid.
21
+	 *
22
+	 * @param int $language
23
+	 * @throws \Exception
24
+	 * @return void
25
+	 */
26
+	public function validate($language)
27
+	{
28
+		if (!$this->getLanguageService()->languageExists((int)$language)) {
29
+			throw new \Exception('The language "' . $language . '" does not exist', 1351605542);
30
+		}
31
+	}
32 32
 
33
-    /**
34
-     * @return LanguageService|object
35
-     */
36
-    protected function getLanguageService()
37
-    {
38
-        return GeneralUtility::makeInstance(LanguageService::class);
39
-    }
33
+	/**
34
+	 * @return LanguageService|object
35
+	 */
36
+	protected function getLanguageService()
37
+	{
38
+		return GeneralUtility::makeInstance(LanguageService::class);
39
+	}
40 40
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@
 block discarded – undo
26 26
     public function validate($language)
27 27
     {
28 28
         if (!$this->getLanguageService()->languageExists((int)$language)) {
29
-            throw new \Exception('The language "' . $language . '" does not exist', 1351605542);
29
+            throw new \Exception('The language "'.$language.'" does not exist', 1351605542);
30 30
         }
31 31
     }
32 32
 
Please login to merge, or discard this patch.
Classes/Domain/Validator/MatchesValidator.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -17,19 +17,19 @@
 block discarded – undo
17 17
  */
18 18
 class MatchesValidator extends AbstractValidator
19 19
 {
20
-    /**
21
-     * Check if $matches is valid. If it is not valid, throw an exception.
22
-     *
23
-     * @param mixed $matches
24
-     * @return void
25
-     */
26
-    public function isValid($matches)
27
-    {
28
-        foreach ($matches as $fieldName => $value) {
29
-            if (!Tca::table()->hasField($fieldName)) {
30
-                $message = sprintf('Field "%s" is not allowed. Actually, it is not configured in the TCA.', $fieldName);
31
-                $this->addError($message, 1380019718);
32
-            }
33
-        }
34
-    }
20
+	/**
21
+	 * Check if $matches is valid. If it is not valid, throw an exception.
22
+	 *
23
+	 * @param mixed $matches
24
+	 * @return void
25
+	 */
26
+	public function isValid($matches)
27
+	{
28
+		foreach ($matches as $fieldName => $value) {
29
+			if (!Tca::table()->hasField($fieldName)) {
30
+				$message = sprintf('Field "%s" is not allowed. Actually, it is not configured in the TCA.', $fieldName);
31
+				$this->addError($message, 1380019718);
32
+			}
33
+		}
34
+	}
35 35
 }
Please login to merge, or discard this patch.