Completed
Push — master ( e35e6f...5d201a )
by Fabien
53:19
created
Classes/ViewHelpers/Grid/Column/ConfigurationViewHelper.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -47,7 +47,7 @@
 block discarded – undo
47 47
             // -------------------
48 48
             // mData: internal name of DataTable plugin and can not contains a path, e.g. metadata.title
49 49
             // columnName: whole field name with path
50
-            $output .= sprintf('Vidi._columns.push({ "data": "%s", "sortable": %s, "visible": %s, "width": "%s", "class": "%s", "columnName": "%s" });' . PHP_EOL,
50
+            $output .= sprintf('Vidi._columns.push({ "data": "%s", "sortable": %s, "visible": %s, "width": "%s", "class": "%s", "columnName": "%s" });'.PHP_EOL,
51 51
                 $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath), // Suitable field name for the DataTable plugin.
52 52
                 Tca::grid()->isSortable($fieldNameAndPath) ? 'true' : 'false',
53 53
                 Tca::grid()->isVisible($fieldNameAndPath) ? 'true' : 'false',
Please login to merge, or discard this patch.
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -19,67 +19,67 @@
 block discarded – undo
19 19
 class ConfigurationViewHelper extends AbstractViewHelper
20 20
 {
21 21
 
22
-    /**
23
-     * Render the columns of the grid.
24
-     *
25
-     * @throws NotExistingFieldException
26
-     * @return string
27
-     */
28
-    public function render()
29
-    {
30
-        $output = '';
22
+	/**
23
+	 * Render the columns of the grid.
24
+	 *
25
+	 * @throws NotExistingFieldException
26
+	 * @return string
27
+	 */
28
+	public function render()
29
+	{
30
+		$output = '';
31 31
 
32
-        foreach (Tca::grid()->getFields() as $fieldNameAndPath => $configuration) {
32
+		foreach (Tca::grid()->getFields() as $fieldNameAndPath => $configuration) {
33 33
 
34
-            // Early failure if field does not exist.
35
-            if (!$this->isAllowed($fieldNameAndPath)) {
36
-                $message = sprintf('Property "%s" does not exist!', $fieldNameAndPath);
37
-                throw new NotExistingFieldException($message, 1375369594);
38
-            }
34
+			// Early failure if field does not exist.
35
+			if (!$this->isAllowed($fieldNameAndPath)) {
36
+				$message = sprintf('Property "%s" does not exist!', $fieldNameAndPath);
37
+				throw new NotExistingFieldException($message, 1375369594);
38
+			}
39 39
 
40
-            // mData vs columnName
41
-            // -------------------
42
-            // mData: internal name of DataTable plugin and can not contains a path, e.g. metadata.title
43
-            // columnName: whole field name with path
44
-            $output .= sprintf('Vidi._columns.push({ "data": "%s", "sortable": %s, "visible": %s, "width": "%s", "class": "%s", "columnName": "%s" });' . PHP_EOL,
45
-                $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath), // Suitable field name for the DataTable plugin.
46
-                Tca::grid()->isSortable($fieldNameAndPath) ? 'true' : 'false',
47
-                Tca::grid()->isVisible($fieldNameAndPath) ? 'true' : 'false',
48
-                Tca::grid()->getWidth($fieldNameAndPath),
49
-                Tca::grid()->getClass($fieldNameAndPath),
50
-                $fieldNameAndPath
51
-            );
52
-        }
40
+			// mData vs columnName
41
+			// -------------------
42
+			// mData: internal name of DataTable plugin and can not contains a path, e.g. metadata.title
43
+			// columnName: whole field name with path
44
+			$output .= sprintf('Vidi._columns.push({ "data": "%s", "sortable": %s, "visible": %s, "width": "%s", "class": "%s", "columnName": "%s" });' . PHP_EOL,
45
+				$this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath), // Suitable field name for the DataTable plugin.
46
+				Tca::grid()->isSortable($fieldNameAndPath) ? 'true' : 'false',
47
+				Tca::grid()->isVisible($fieldNameAndPath) ? 'true' : 'false',
48
+				Tca::grid()->getWidth($fieldNameAndPath),
49
+				Tca::grid()->getClass($fieldNameAndPath),
50
+				$fieldNameAndPath
51
+			);
52
+		}
53 53
 
54
-        return $output;
55
-    }
54
+		return $output;
55
+	}
56 56
 
57
-    /**
58
-     * Tell whether the field looks ok to be displayed within the Grid.
59
-     *
60
-     * @param string $fieldNameAndPath
61
-     * @return boolean
62
-     */
63
-    protected function isAllowed($fieldNameAndPath)
64
-    {
65
-        $dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath);
66
-        $fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
57
+	/**
58
+	 * Tell whether the field looks ok to be displayed within the Grid.
59
+	 *
60
+	 * @param string $fieldNameAndPath
61
+	 * @return boolean
62
+	 */
63
+	protected function isAllowed($fieldNameAndPath)
64
+	{
65
+		$dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath);
66
+		$fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
67 67
 
68
-        $isAllowed = false;
69
-        if (Tca::grid()->hasRenderers($fieldNameAndPath)) {
70
-            $isAllowed = true;
71
-        } elseif (Tca::table()->field($fieldNameAndPath)->isSystem() || Tca::table($dataType)->hasField($fieldName)) {
72
-            $isAllowed = true;
73
-        }
68
+		$isAllowed = false;
69
+		if (Tca::grid()->hasRenderers($fieldNameAndPath)) {
70
+			$isAllowed = true;
71
+		} elseif (Tca::table()->field($fieldNameAndPath)->isSystem() || Tca::table($dataType)->hasField($fieldName)) {
72
+			$isAllowed = true;
73
+		}
74 74
 
75
-        return $isAllowed;
76
-    }
75
+		return $isAllowed;
76
+	}
77 77
 
78
-    /**
79
-     * @return \Fab\Vidi\Resolver\FieldPathResolver|object
80
-     */
81
-    protected function getFieldPathResolver()
82
-    {
83
-        return GeneralUtility::makeInstance(\Fab\Vidi\Resolver\FieldPathResolver::class);
84
-    }
78
+	/**
79
+	 * @return \Fab\Vidi\Resolver\FieldPathResolver|object
80
+	 */
81
+	protected function getFieldPathResolver()
82
+	{
83
+		return GeneralUtility::makeInstance(\Fab\Vidi\Resolver\FieldPathResolver::class);
84
+	}
85 85
 }
Please login to merge, or discard this patch.
Classes/ViewHelpers/Content/AbstractContentViewHelper.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@
 block discarded – undo
57 57
     {
58 58
         $serializedMatches = serialize($matches);
59 59
         $serializedOrderings = serialize($orderings);
60
-        return md5($dataType . $serializedMatches . $serializedOrderings . $limit . $offset);
60
+        return md5($dataType.$serializedMatches.$serializedOrderings.$limit.$offset);
61 61
     }
62 62
 
63 63
     /**
Please login to merge, or discard this patch.
Indentation   +209 added lines, -209 removed lines patch added patch discarded remove patch
@@ -25,214 +25,214 @@
 block discarded – undo
25 25
 abstract class AbstractContentViewHelper extends AbstractViewHelper
26 26
 {
27 27
 
28
-    /**
29
-     * @return void
30
-     * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
31
-     */
32
-    public function initializeArguments()
33
-    {
34
-        $this->registerArgument('type', 'string', 'Corresponds to the type of data to be fetched. It will basically be a table name e.g. fe_users.', false, '');
35
-        $this->registerArgument('matches', 'array', 'Key / value array to be used as filter. The key corresponds to a field name.', false, array());
36
-        $this->registerArgument('selection', 'int', 'A possible selection defined in the BE and stored in the database.', false, 0);
37
-        $this->registerArgument('ignoreEnableFields', 'bool', 'Whether to ignore enable fields or not (AKA hidden, deleted, starttime, ...).', false, false);
38
-        $this->registerArgument('aliases', 'array', 'Attribute "matches" does not support certain character such as "." in field name. Use this to create aliases.', false, array());
39
-    }
40
-
41
-    /**
42
-     * Generate a signature to be used for storing the result set.
43
-     *
44
-     * @param string $dataType
45
-     * @param array $matches
46
-     * @param array $orderings
47
-     * @param $limit
48
-     * @param $offset
49
-     * @return string
50
-     */
51
-    protected function getQuerySignature($dataType, array $matches, array $orderings, $limit, $offset)
52
-    {
53
-        $serializedMatches = serialize($matches);
54
-        $serializedOrderings = serialize($orderings);
55
-        return md5($dataType . $serializedMatches . $serializedOrderings . $limit . $offset);
56
-    }
57
-
58
-    /**
59
-     * Returns a matcher object.
60
-     *
61
-     * @param string $dataType
62
-     * @param array $matches
63
-     * @return Matcher
64
-     * @throws \Fab\Vidi\Exception\NotExistingClassException
65
-     * @throws \InvalidArgumentException
66
-     */
67
-    protected function getMatcher($dataType, $matches = array())
68
-    {
69
-
70
-        /** @var $matcher Matcher */
71
-        $matcher = GeneralUtility::makeInstance(Matcher::class, [], $dataType);
72
-
73
-        // @todo implement advanced selection parsing {or: {usergroup.title: {like: foo}}, {tstamp: {greaterThan: 1234}}}
74
-        foreach ($matches as $fieldNameAndPath => $value) {
75
-
76
-            // CSV values should be considered as "in" operator in Query, otherwise "equals".
77
-            $explodedValues = GeneralUtility::trimExplode(',', $value, true);
78
-
79
-            // The matching value contains a "1,2" as example
80
-            if (count($explodedValues) > 1) {
81
-
82
-                $resolvedDataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $dataType);
83
-                $resolvedFieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $dataType);
84
-
85
-                // "equals" if in presence of a relation.
86
-                // "in" if not a relation.
87
-                if (Tca::table($resolvedDataType)->field($resolvedFieldName)->hasRelation()) {
88
-                    foreach ($explodedValues as $explodedValue) {
89
-                        $matcher->equals($fieldNameAndPath, $explodedValue);
90
-                    }
91
-                } else {
92
-                    $matcher->in($fieldNameAndPath, $explodedValues);
93
-                }
94
-            } else {
95
-                $matcher->equals($fieldNameAndPath, $explodedValues[0]);
96
-            }
97
-        }
98
-
99
-        // Trigger signal for post processing Matcher Object.
100
-        $this->emitPostProcessMatcherObjectSignal($matcher->getDataType(), $matcher);
101
-
102
-        return $matcher;
103
-    }
104
-
105
-    /**
106
-     * Replace possible aliases.
107
-     *
108
-     * @param array $values
109
-     * @return array
110
-     */
111
-    protected function replacesAliases(array $values)
112
-    {
113
-
114
-        $aliases = $this->arguments['aliases'];
115
-
116
-        foreach ($aliases as $aliasName => $aliasValue) {
117
-            if (isset($values[$aliasName])) {
118
-                $values[$aliasValue] = $values[$aliasName];
119
-                unset($values[$aliasName]); // remove the alias.
120
-            }
121
-        }
122
-
123
-        return $values;
124
-    }
125
-
126
-    /**
127
-     * Returns an order object.
128
-     *
129
-     * @param string $dataType
130
-     * @param array $order
131
-     * @return Order
132
-     */
133
-    public function getOrder($dataType, array $order = array())
134
-    {
135
-        // Default orderings in case order is empty.
136
-        if (empty($order)) {
137
-            $order = Tca::table($dataType)->getDefaultOrderings();
138
-        }
139
-
140
-        $order = GeneralUtility::makeInstance(Order::class, $order);
141
-
142
-        // Trigger signal for post processing Order Object.
143
-        $this->emitPostProcessOrderObjectSignal($dataType, $order);
144
-
145
-        return $order;
146
-    }
147
-
148
-    /**
149
-     * @return ResultSetStorage
150
-     */
151
-    public function getResultSetStorage()
152
-    {
153
-        return GeneralUtility::makeInstance(ResultSetStorage::class);
154
-    }
155
-
156
-    /**
157
-     * Signal that is called for post-processing a "order" object.
158
-     *
159
-     * @param string $dataType
160
-     * @param Order $order
161
-     */
162
-    protected function emitPostProcessOrderObjectSignal($dataType, Order $order)
163
-    {
164
-        $this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\ViewHelper\Content\AbstractContentViewHelper', 'postProcessOrderObject', array($order, $dataType));
165
-    }
166
-
167
-    /**
168
-     * Signal that is called for post-processing a "matcher" object.
169
-     *
170
-     * @param string $dataType
171
-     * @param Matcher $matcher
172
-     */
173
-    protected function emitPostProcessMatcherObjectSignal($dataType, Matcher $matcher)
174
-    {
175
-        $this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\ViewHelper\Content\AbstractContentViewHelper', 'postProcessMatcherObject', array($matcher, $dataType));
176
-    }
177
-
178
-    /**
179
-     * Signal that is called for post-processing a "limit".
180
-     *
181
-     * @param string $dataType
182
-     * @param int $limit
183
-     */
184
-    protected function emitPostProcessLimitSignal($dataType, $limit)
185
-    {
186
-        $this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\ViewHelper\Content\AbstractContentViewHelper', 'postProcessLimit', array($limit, $dataType));
187
-    }
188
-
189
-    /**
190
-     * Signal that is called for post-processing a "offset".
191
-     *
192
-     * @param string $dataType
193
-     * @param int $offset
194
-     */
195
-    protected function emitPostProcessOffsetSignal($dataType, $offset)
196
-    {
197
-        $this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\ViewHelper\Content\AbstractContentViewHelper', 'postProcessLimit', array($offset, $dataType));
198
-    }
199
-
200
-    /**
201
-     * Get the SignalSlot dispatcher
202
-     *
203
-     * @return Dispatcher
204
-     */
205
-    protected function getSignalSlotDispatcher()
206
-    {
207
-        return $this->getObjectManager()->get(Dispatcher::class);
208
-    }
209
-
210
-    /**
211
-     * @return ObjectManager
212
-     */
213
-    protected function getObjectManager()
214
-    {
215
-        return GeneralUtility::makeInstance(ObjectManager::class);
216
-    }
217
-
218
-    /**
219
-     * @param $ignoreEnableFields
220
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface
221
-     */
222
-    protected function getDefaultQuerySettings($ignoreEnableFields)
223
-    {
224
-        /** @var QuerySettings $defaultQuerySettings */
225
-        $defaultQuerySettings = GeneralUtility::makeInstance(QuerySettings::class);
226
-        $defaultQuerySettings->setIgnoreEnableFields($ignoreEnableFields);
227
-        return $defaultQuerySettings;
228
-    }
229
-
230
-    /**
231
-     * @return FieldPathResolver
232
-     */
233
-    protected function getFieldPathResolver()
234
-    {
235
-        return GeneralUtility::makeInstance(FieldPathResolver::class);
236
-    }
28
+	/**
29
+	 * @return void
30
+	 * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
31
+	 */
32
+	public function initializeArguments()
33
+	{
34
+		$this->registerArgument('type', 'string', 'Corresponds to the type of data to be fetched. It will basically be a table name e.g. fe_users.', false, '');
35
+		$this->registerArgument('matches', 'array', 'Key / value array to be used as filter. The key corresponds to a field name.', false, array());
36
+		$this->registerArgument('selection', 'int', 'A possible selection defined in the BE and stored in the database.', false, 0);
37
+		$this->registerArgument('ignoreEnableFields', 'bool', 'Whether to ignore enable fields or not (AKA hidden, deleted, starttime, ...).', false, false);
38
+		$this->registerArgument('aliases', 'array', 'Attribute "matches" does not support certain character such as "." in field name. Use this to create aliases.', false, array());
39
+	}
40
+
41
+	/**
42
+	 * Generate a signature to be used for storing the result set.
43
+	 *
44
+	 * @param string $dataType
45
+	 * @param array $matches
46
+	 * @param array $orderings
47
+	 * @param $limit
48
+	 * @param $offset
49
+	 * @return string
50
+	 */
51
+	protected function getQuerySignature($dataType, array $matches, array $orderings, $limit, $offset)
52
+	{
53
+		$serializedMatches = serialize($matches);
54
+		$serializedOrderings = serialize($orderings);
55
+		return md5($dataType . $serializedMatches . $serializedOrderings . $limit . $offset);
56
+	}
57
+
58
+	/**
59
+	 * Returns a matcher object.
60
+	 *
61
+	 * @param string $dataType
62
+	 * @param array $matches
63
+	 * @return Matcher
64
+	 * @throws \Fab\Vidi\Exception\NotExistingClassException
65
+	 * @throws \InvalidArgumentException
66
+	 */
67
+	protected function getMatcher($dataType, $matches = array())
68
+	{
69
+
70
+		/** @var $matcher Matcher */
71
+		$matcher = GeneralUtility::makeInstance(Matcher::class, [], $dataType);
72
+
73
+		// @todo implement advanced selection parsing {or: {usergroup.title: {like: foo}}, {tstamp: {greaterThan: 1234}}}
74
+		foreach ($matches as $fieldNameAndPath => $value) {
75
+
76
+			// CSV values should be considered as "in" operator in Query, otherwise "equals".
77
+			$explodedValues = GeneralUtility::trimExplode(',', $value, true);
78
+
79
+			// The matching value contains a "1,2" as example
80
+			if (count($explodedValues) > 1) {
81
+
82
+				$resolvedDataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath, $dataType);
83
+				$resolvedFieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath, $dataType);
84
+
85
+				// "equals" if in presence of a relation.
86
+				// "in" if not a relation.
87
+				if (Tca::table($resolvedDataType)->field($resolvedFieldName)->hasRelation()) {
88
+					foreach ($explodedValues as $explodedValue) {
89
+						$matcher->equals($fieldNameAndPath, $explodedValue);
90
+					}
91
+				} else {
92
+					$matcher->in($fieldNameAndPath, $explodedValues);
93
+				}
94
+			} else {
95
+				$matcher->equals($fieldNameAndPath, $explodedValues[0]);
96
+			}
97
+		}
98
+
99
+		// Trigger signal for post processing Matcher Object.
100
+		$this->emitPostProcessMatcherObjectSignal($matcher->getDataType(), $matcher);
101
+
102
+		return $matcher;
103
+	}
104
+
105
+	/**
106
+	 * Replace possible aliases.
107
+	 *
108
+	 * @param array $values
109
+	 * @return array
110
+	 */
111
+	protected function replacesAliases(array $values)
112
+	{
113
+
114
+		$aliases = $this->arguments['aliases'];
115
+
116
+		foreach ($aliases as $aliasName => $aliasValue) {
117
+			if (isset($values[$aliasName])) {
118
+				$values[$aliasValue] = $values[$aliasName];
119
+				unset($values[$aliasName]); // remove the alias.
120
+			}
121
+		}
122
+
123
+		return $values;
124
+	}
125
+
126
+	/**
127
+	 * Returns an order object.
128
+	 *
129
+	 * @param string $dataType
130
+	 * @param array $order
131
+	 * @return Order
132
+	 */
133
+	public function getOrder($dataType, array $order = array())
134
+	{
135
+		// Default orderings in case order is empty.
136
+		if (empty($order)) {
137
+			$order = Tca::table($dataType)->getDefaultOrderings();
138
+		}
139
+
140
+		$order = GeneralUtility::makeInstance(Order::class, $order);
141
+
142
+		// Trigger signal for post processing Order Object.
143
+		$this->emitPostProcessOrderObjectSignal($dataType, $order);
144
+
145
+		return $order;
146
+	}
147
+
148
+	/**
149
+	 * @return ResultSetStorage
150
+	 */
151
+	public function getResultSetStorage()
152
+	{
153
+		return GeneralUtility::makeInstance(ResultSetStorage::class);
154
+	}
155
+
156
+	/**
157
+	 * Signal that is called for post-processing a "order" object.
158
+	 *
159
+	 * @param string $dataType
160
+	 * @param Order $order
161
+	 */
162
+	protected function emitPostProcessOrderObjectSignal($dataType, Order $order)
163
+	{
164
+		$this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\ViewHelper\Content\AbstractContentViewHelper', 'postProcessOrderObject', array($order, $dataType));
165
+	}
166
+
167
+	/**
168
+	 * Signal that is called for post-processing a "matcher" object.
169
+	 *
170
+	 * @param string $dataType
171
+	 * @param Matcher $matcher
172
+	 */
173
+	protected function emitPostProcessMatcherObjectSignal($dataType, Matcher $matcher)
174
+	{
175
+		$this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\ViewHelper\Content\AbstractContentViewHelper', 'postProcessMatcherObject', array($matcher, $dataType));
176
+	}
177
+
178
+	/**
179
+	 * Signal that is called for post-processing a "limit".
180
+	 *
181
+	 * @param string $dataType
182
+	 * @param int $limit
183
+	 */
184
+	protected function emitPostProcessLimitSignal($dataType, $limit)
185
+	{
186
+		$this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\ViewHelper\Content\AbstractContentViewHelper', 'postProcessLimit', array($limit, $dataType));
187
+	}
188
+
189
+	/**
190
+	 * Signal that is called for post-processing a "offset".
191
+	 *
192
+	 * @param string $dataType
193
+	 * @param int $offset
194
+	 */
195
+	protected function emitPostProcessOffsetSignal($dataType, $offset)
196
+	{
197
+		$this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\ViewHelper\Content\AbstractContentViewHelper', 'postProcessLimit', array($offset, $dataType));
198
+	}
199
+
200
+	/**
201
+	 * Get the SignalSlot dispatcher
202
+	 *
203
+	 * @return Dispatcher
204
+	 */
205
+	protected function getSignalSlotDispatcher()
206
+	{
207
+		return $this->getObjectManager()->get(Dispatcher::class);
208
+	}
209
+
210
+	/**
211
+	 * @return ObjectManager
212
+	 */
213
+	protected function getObjectManager()
214
+	{
215
+		return GeneralUtility::makeInstance(ObjectManager::class);
216
+	}
217
+
218
+	/**
219
+	 * @param $ignoreEnableFields
220
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface
221
+	 */
222
+	protected function getDefaultQuerySettings($ignoreEnableFields)
223
+	{
224
+		/** @var QuerySettings $defaultQuerySettings */
225
+		$defaultQuerySettings = GeneralUtility::makeInstance(QuerySettings::class);
226
+		$defaultQuerySettings->setIgnoreEnableFields($ignoreEnableFields);
227
+		return $defaultQuerySettings;
228
+	}
229
+
230
+	/**
231
+	 * @return FieldPathResolver
232
+	 */
233
+	protected function getFieldPathResolver()
234
+	{
235
+		return GeneralUtility::makeInstance(FieldPathResolver::class);
236
+	}
237 237
 
238 238
 }
Please login to merge, or discard this patch.
Classes/Grid/VisibilityRenderer.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -50,7 +50,7 @@
 block discarded – undo
50 50
                 ->setDataAttributes([
51 51
                     'toggle' => 'tooltip',
52 52
                 ])
53
-                ->setTitle($this->getLabelService()->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:' . $label))
53
+                ->setTitle($this->getLabelService()->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:'.$label))
54 54
                 ->setIcon($this->getIconFactory()->getIcon($spriteName, Icon::SIZE_SMALL))
55 55
                 ->render();
56 56
         }
Please login to merge, or discard this patch.
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -21,83 +21,83 @@
 block discarded – undo
21 21
 class VisibilityRenderer extends ColumnRendererAbstract
22 22
 {
23 23
 
24
-    /**
25
-     * Render visibility for the Grid.
26
-     *
27
-     * @return string
28
-     */
29
-    public function render()
30
-    {
31
-
32
-        $output = '';
33
-        $hiddenField = Tca::table()->getHiddenField();
34
-
35
-        if ($hiddenField) {
36
-
37
-            $spriteName = $this->object[$hiddenField] ? 'actions-edit-unhide' : 'actions-edit-hide';
38
-
39
-            $label = $this->object[$hiddenField] ? 'unHide' : 'hide';
40
-
41
-            $output = $this->makeLinkButton()
42
-                ->setHref($this->getEditUri($this->object))
43
-                ->setClasses('btn-visibility-toggle')
44
-                ->setDataAttributes([
45
-                    'toggle' => 'tooltip',
46
-                ])
47
-                ->setTitle($this->getLabelService()->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:' . $label))
48
-                ->setIcon($this->getIconFactory()->getIcon($spriteName, Icon::SIZE_SMALL))
49
-                ->render();
50
-        }
51
-        return $output;
52
-    }
53
-
54
-    /**
55
-     * @param Content $object
56
-     * @return string
57
-     */
58
-    protected function getEditUri(Content $object)
59
-    {
60
-        $hiddenField = Tca::table()->getHiddenField();
61
-
62
-        $additionalParameters = array(
63
-            $this->getModuleLoader()->getParameterPrefix() => [
64
-                'controller' => 'Content',
65
-                'action' => 'update',
66
-                'format' => 'json',
67
-                'fieldNameAndPath' => Tca::table()->getHiddenField(),
68
-                'matches' => [
69
-                    'uid' => $object->getUid(),
70
-                ],
71
-                'content' => [$hiddenField => (int)!$this->object[$hiddenField]],
72
-            ],
73
-        );
74
-
75
-        return $this->getModuleLoader()->getModuleUrl($additionalParameters);
76
-    }
77
-
78
-    /**
79
-     * @return LinkButton
80
-     */
81
-    protected function makeLinkButton()
82
-    {
83
-        return GeneralUtility::makeInstance(LinkButton::class);
84
-    }
85
-
86
-
87
-    /**
88
-     * @return IconFactory
89
-     */
90
-    protected function getIconFactory()
91
-    {
92
-        return GeneralUtility::makeInstance(IconFactory::class);
93
-    }
94
-
95
-    /**
96
-     * @return \TYPO3\CMS\Core\Localization\LanguageService
97
-     */
98
-    protected function getLabelService()
99
-    {
100
-        return $GLOBALS['LANG'];
101
-    }
24
+	/**
25
+	 * Render visibility for the Grid.
26
+	 *
27
+	 * @return string
28
+	 */
29
+	public function render()
30
+	{
31
+
32
+		$output = '';
33
+		$hiddenField = Tca::table()->getHiddenField();
34
+
35
+		if ($hiddenField) {
36
+
37
+			$spriteName = $this->object[$hiddenField] ? 'actions-edit-unhide' : 'actions-edit-hide';
38
+
39
+			$label = $this->object[$hiddenField] ? 'unHide' : 'hide';
40
+
41
+			$output = $this->makeLinkButton()
42
+				->setHref($this->getEditUri($this->object))
43
+				->setClasses('btn-visibility-toggle')
44
+				->setDataAttributes([
45
+					'toggle' => 'tooltip',
46
+				])
47
+				->setTitle($this->getLabelService()->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:' . $label))
48
+				->setIcon($this->getIconFactory()->getIcon($spriteName, Icon::SIZE_SMALL))
49
+				->render();
50
+		}
51
+		return $output;
52
+	}
53
+
54
+	/**
55
+	 * @param Content $object
56
+	 * @return string
57
+	 */
58
+	protected function getEditUri(Content $object)
59
+	{
60
+		$hiddenField = Tca::table()->getHiddenField();
61
+
62
+		$additionalParameters = array(
63
+			$this->getModuleLoader()->getParameterPrefix() => [
64
+				'controller' => 'Content',
65
+				'action' => 'update',
66
+				'format' => 'json',
67
+				'fieldNameAndPath' => Tca::table()->getHiddenField(),
68
+				'matches' => [
69
+					'uid' => $object->getUid(),
70
+				],
71
+				'content' => [$hiddenField => (int)!$this->object[$hiddenField]],
72
+			],
73
+		);
74
+
75
+		return $this->getModuleLoader()->getModuleUrl($additionalParameters);
76
+	}
77
+
78
+	/**
79
+	 * @return LinkButton
80
+	 */
81
+	protected function makeLinkButton()
82
+	{
83
+		return GeneralUtility::makeInstance(LinkButton::class);
84
+	}
85
+
86
+
87
+	/**
88
+	 * @return IconFactory
89
+	 */
90
+	protected function getIconFactory()
91
+	{
92
+		return GeneralUtility::makeInstance(IconFactory::class);
93
+	}
94
+
95
+	/**
96
+	 * @return \TYPO3\CMS\Core\Localization\LanguageService
97
+	 */
98
+	protected function getLabelService()
99
+	{
100
+		return $GLOBALS['LANG'];
101
+	}
102 102
 
103 103
 }
Please login to merge, or discard this patch.
Classes/Persistence/Query.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -193,8 +193,8 @@
 block discarded – undo
193 193
             $configuration = $backendConfigurationManager->getTypoScriptSetup();
194 194
             $querySettings = array('respectSysLanguage');
195 195
             foreach ($querySettings as $setting) {
196
-                if (isset($configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting])) {
197
-                    $value = (bool)$configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting];
196
+                if (isset($configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type.'.'][$setting])) {
197
+                    $value = (bool)$configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type.'.'][$setting];
198 198
                     ObjectAccess::setProperty($this->querySettings, $setting, $value);
199 199
                 }
200 200
             }
Please login to merge, or discard this patch.
Indentation   +637 added lines, -637 removed lines patch added patch discarded remove patch
@@ -26,642 +26,642 @@
 block discarded – undo
26 26
 class Query implements QueryInterface
27 27
 {
28 28
 
29
-    /**
30
-     * An inner join.
31
-     */
32
-    const JCR_JOIN_TYPE_INNER = '{http://www.jcp.org/jcr/1.0}joinTypeInner';
33
-
34
-    /**
35
-     * A left-outer join.
36
-     */
37
-    const JCR_JOIN_TYPE_LEFT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeLeftOuter';
38
-
39
-    /**
40
-     * A right-outer join.
41
-     */
42
-    const JCR_JOIN_TYPE_RIGHT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeRightOuter';
43
-
44
-    /**
45
-     * Charset of strings in QOM
46
-     */
47
-    const CHARSET = 'utf-8';
48
-
49
-    /**
50
-     * @var string
51
-     */
52
-    protected $sourceFieldName;
53
-
54
-    /**
55
-     * @var string
56
-     */
57
-    protected $type;
58
-
59
-    /**
60
-     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
61
-     */
62
-    protected $persistenceManager;
63
-
64
-    /**
65
-     * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory
66
-     */
67
-    protected $qomFactory;
68
-
69
-    /**
70
-     * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface
71
-     */
72
-    protected $source;
73
-
74
-    /**
75
-     * @var ConstraintInterface
76
-     */
77
-    protected $constraint;
78
-
79
-    /**
80
-     * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
81
-     */
82
-    protected $statement;
83
-
84
-    /**
85
-     * @var array
86
-     */
87
-    protected $orderings = [];
88
-
89
-    /**
90
-     * @var int
91
-     */
92
-    protected $limit;
93
-
94
-    /**
95
-     * @var int
96
-     */
97
-    protected $offset;
98
-
99
-    /**
100
-     * Apply DISTINCT upon property.
101
-     *
102
-     * @var string
103
-     */
104
-    protected $distinct;
105
-
106
-    /**
107
-     * The query settings.
108
-     *
109
-     * @var \Fab\Vidi\Persistence\QuerySettings
110
-     * @Inject
111
-     */
112
-    public $querySettings;
113
-
114
-    /**
115
-     * Constructs a query object working on the given class name
116
-     *
117
-     * @param string $type
118
-     */
119
-    public function __construct($type)
120
-    {
121
-        $this->type = $type;
122
-    }
123
-
124
-    /**
125
-     * Injects the persistence manager, used to fetch the CR session
126
-     *
127
-     * @param \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager
128
-     * @return void
129
-     */
130
-    public function injectPersistenceManager(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager)
131
-    {
132
-        $this->persistenceManager = $persistenceManager;
133
-    }
134
-
135
-    /**
136
-     * Injects the Query Object Model Factory
137
-     *
138
-     * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory
139
-     * @return void
140
-     */
141
-    public function injectQomFactory(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory)
142
-    {
143
-        $this->qomFactory = $qomFactory;
144
-    }
145
-
146
-    /**
147
-     * Sets the Query Settings. These Query settings must match the settings expected by
148
-     * the specific Storage Backend.
149
-     *
150
-     * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings The Query Settings
151
-     * @return void
152
-     * @api This method is not part of FLOW3 API
153
-     */
154
-    public function setQuerySettings(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings)
155
-    {
156
-        $this->querySettings = $querySettings;
157
-    }
158
-
159
-    /**
160
-     * Returns the Query Settings.
161
-     *
162
-     * @throws \Exception
163
-     * @return \Fab\Vidi\Persistence\QuerySettings $querySettings The Query Settings
164
-     * @api This method is not part of FLOW3 API
165
-     */
166
-    public function getQuerySettings()
167
-    {
168
-        if (!$this->querySettings instanceof \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface) {
169
-            throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception('Tried to get the query settings without setting them before.', 1248689115);
170
-        }
171
-
172
-        // Apply possible settings to the query.
173
-        if ($this->isBackendMode()) {
174
-            /** @var \TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager $backendConfigurationManager */
175
-            $backendConfigurationManager = $this->getObjectManager()->get('TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager');
176
-            $configuration = $backendConfigurationManager->getTypoScriptSetup();
177
-            $querySettings = array('respectSysLanguage');
178
-            foreach ($querySettings as $setting) {
179
-                if (isset($configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting])) {
180
-                    $value = (bool)$configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting];
181
-                    ObjectAccess::setProperty($this->querySettings, $setting, $value);
182
-                }
183
-            }
184
-        }
185
-
186
-        return $this->querySettings;
187
-    }
188
-
189
-    /**
190
-     * Returns the type this query cares for.
191
-     *
192
-     * @return string
193
-     * @api
194
-     */
195
-    public function getType()
196
-    {
197
-        return $this->type;
198
-    }
199
-
200
-    /**
201
-     * Sets the source to fetch the result from
202
-     *
203
-     * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source
204
-     */
205
-    public function setSource(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source)
206
-    {
207
-        $this->source = $source;
208
-    }
209
-
210
-    /**
211
-     * Returns the selectorn name or an empty string, if the source is not a selector
212
-     * TODO This has to be checked at another place
213
-     *
214
-     * @return string The selector name
215
-     */
216
-    protected function getSelectorName()
217
-    {
218
-        if ($this->getSource() instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface) {
219
-            return $this->source->getSelectorName();
220
-        } else {
221
-            return '';
222
-        }
223
-    }
224
-
225
-    /**
226
-     * Gets the node-tuple source for this query.
227
-     *
228
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface the node-tuple source; non-null
229
-     */
230
-    public function getSource()
231
-    {
232
-        if ($this->source === null) {
233
-            $this->source = $this->qomFactory->selector($this->getType());
234
-        }
235
-        return $this->source;
236
-    }
237
-
238
-    /**
239
-     * Executes the query against the database and returns the result
240
-     *
241
-     * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array The query result object or an array if $this->getQuerySettings()->getReturnRawQueryResult() is true
242
-     * @api
243
-     */
244
-    public function execute($returnRawQueryResult = false)
245
-    {
246
-        /** @var VidiDbBackend $backend */
247
-        $backend = $this->getObjectManager()->get(VidiDbBackend::class, $this);
248
-        return $backend->fetchResult();
249
-    }
250
-
251
-    /**
252
-     * Sets the property names to order the result by. Expected like this:
253
-     * array(
254
-     * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
255
-     * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
256
-     * )
257
-     * where 'foo' and 'bar' are property names.
258
-     *
259
-     * @param array $orderings The property names to order by
260
-     * @return QueryInterface
261
-     * @api
262
-     */
263
-    public function setOrderings(array $orderings)
264
-    {
265
-        $this->orderings = $orderings;
266
-        return $this;
267
-    }
268
-
269
-    /**
270
-     * Returns the property names to order the result by. Like this:
271
-     * array(
272
-     * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
273
-     * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
274
-     * )
275
-     *
276
-     * @return array
277
-     */
278
-    public function getOrderings()
279
-    {
280
-        return $this->orderings;
281
-    }
282
-
283
-    /**
284
-     * Sets the maximum size of the result set to limit. Returns $this to allow
285
-     * for chaining (fluid interface)
286
-     *
287
-     * @param integer $limit
288
-     * @throws \InvalidArgumentException
289
-     * @return QueryInterface
290
-     * @api
291
-     */
292
-    public function setLimit($limit)
293
-    {
294
-        if (!is_int($limit) || $limit < 1) {
295
-            throw new \InvalidArgumentException('The limit must be an integer >= 1', 1245071870);
296
-        }
297
-        $this->limit = $limit;
298
-        return $this;
299
-    }
300
-
301
-    /**
302
-     * Resets a previously set maximum size of the result set. Returns $this to allow
303
-     * for chaining (fluid interface)
304
-     *
305
-     * @return QueryInterface
306
-     * @api
307
-     */
308
-    public function unsetLimit()
309
-    {
310
-        unset($this->limit);
311
-        return $this;
312
-    }
313
-
314
-    /**
315
-     * Returns the maximum size of the result set to limit.
316
-     *
317
-     * @return integer
318
-     * @api
319
-     */
320
-    public function getLimit()
321
-    {
322
-        return $this->limit;
323
-    }
324
-
325
-    /**
326
-     * Sets the start offset of the result set to offset. Returns $this to
327
-     * allow for chaining (fluid interface)
328
-     *
329
-     * @param integer $offset
330
-     * @throws \InvalidArgumentException
331
-     * @return QueryInterface
332
-     * @api
333
-     */
334
-    public function setOffset($offset)
335
-    {
336
-        if (!is_int($offset) || $offset < 0) {
337
-            throw new \InvalidArgumentException('The offset must be a positive integer', 1245071872);
338
-        }
339
-        $this->offset = $offset;
340
-        return $this;
341
-    }
342
-
343
-    /**
344
-     * Returns the start offset of the result set.
345
-     *
346
-     * @return integer
347
-     * @api
348
-     */
349
-    public function getOffset()
350
-    {
351
-        return $this->offset;
352
-    }
353
-
354
-    /**
355
-     * The constraint used to limit the result set. Returns $this to allow
356
-     * for chaining (fluid interface)
357
-     *
358
-     * @param ConstraintInterface $constraint
359
-     * @return QueryInterface
360
-     * @api
361
-     */
362
-    public function matching($constraint)
363
-    {
364
-        $this->constraint = $constraint;
365
-        return $this;
366
-    }
367
-
368
-    /**
369
-     * Gets the constraint for this query.
370
-     *
371
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface the constraint, or null if none
372
-     * @api
373
-     */
374
-    public function getConstraint()
375
-    {
376
-        return $this->constraint;
377
-    }
378
-
379
-    /**
380
-     * Performs a logical conjunction of the given constraints. The method takes one or more contraints and concatenates them with a boolean AND.
381
-     * It also scepts a single array of constraints to be concatenated.
382
-     *
383
-     * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
384
-     * @throws InvalidNumberOfConstraintsException
385
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\AndInterface
386
-     * @api
387
-     */
388
-    public function logicalAnd($constraint1)
389
-    {
390
-        if (is_array($constraint1)) {
391
-            $resultingConstraint = array_shift($constraint1);
392
-            $constraints = $constraint1;
393
-        } else {
394
-            $constraints = func_get_args();
395
-            $resultingConstraint = array_shift($constraints);
396
-        }
397
-        if ($resultingConstraint === null) {
398
-            throw new InvalidNumberOfConstraintsException('There must be at least one constraint or a non-empty array of constraints given.', 1401289500);
399
-        }
400
-        foreach ($constraints as $constraint) {
401
-            $resultingConstraint = $this->qomFactory->_and($resultingConstraint, $constraint);
402
-        }
403
-        return $resultingConstraint;
404
-    }
405
-
406
-    /**
407
-     * Performs a logical disjunction of the two given constraints
408
-     *
409
-     * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
410
-     * @throws InvalidNumberOfConstraintsException
411
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\OrInterface
412
-     * @api
413
-     */
414
-    public function logicalOr($constraint1)
415
-    {
416
-        if (is_array($constraint1)) {
417
-            $resultingConstraint = array_shift($constraint1);
418
-            $constraints = $constraint1;
419
-        } else {
420
-            $constraints = func_get_args();
421
-            $resultingConstraint = array_shift($constraints);
422
-        }
423
-        if ($resultingConstraint === null) {
424
-            throw new InvalidNumberOfConstraintsException('There must be at least one constraint or a non-empty array of constraints given.', 1401289501);
425
-        }
426
-        foreach ($constraints as $constraint) {
427
-            $resultingConstraint = $this->qomFactory->_or($resultingConstraint, $constraint);
428
-        }
429
-        return $resultingConstraint;
430
-    }
431
-
432
-    /**
433
-     * Performs a logical negation of the given constraint
434
-     *
435
-     * @param ConstraintInterface $constraint Constraint to negate
436
-     * @throws \RuntimeException
437
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\NotInterface
438
-     * @api
439
-     */
440
-    public function logicalNot(ConstraintInterface $constraint)
441
-    {
442
-        return $this->qomFactory->not($constraint);
443
-    }
444
-
445
-    /**
446
-     * Returns an equals criterion used for matching objects against a query
447
-     *
448
-     * @param string $propertyName The name of the property to compare against
449
-     * @param mixed $operand The value to compare with
450
-     * @param boolean $caseSensitive Whether the equality test should be done case-sensitive
451
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
452
-     * @api
453
-     */
454
-    public function equals($propertyName, $operand, $caseSensitive = true)
455
-    {
456
-        if (is_object($operand) || $caseSensitive) {
457
-            $comparison = $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_EQUAL_TO, $operand);
458
-        } else {
459
-            $comparison = $this->qomFactory->comparison($this->qomFactory->lowerCase($this->qomFactory->propertyValue($propertyName, $this->getSelectorName())), QueryInterface::OPERATOR_EQUAL_TO, \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Charset\CharsetConverter::class)->conv_case(\TYPO3\CMS\Extbase\Persistence\Generic\Query::CHARSET, $operand, 'toLower'));
460
-        }
461
-        return $comparison;
462
-    }
463
-
464
-    /**
465
-     * Returns a like criterion used for matching objects against a query
466
-     *
467
-     * @param string $propertyName The name of the property to compare against
468
-     * @param mixed $operand The value to compare with
469
-     * @param boolean $caseSensitive Whether the matching should be done case-sensitive
470
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
471
-     * @api
472
-     */
473
-    public function like($propertyName, $operand, $caseSensitive = true)
474
-    {
475
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LIKE, $operand);
476
-    }
477
-
478
-    /**
479
-     * Returns a "contains" criterion used for matching objects against a query.
480
-     * It matches if the multivalued property contains the given operand.
481
-     *
482
-     * @param string $propertyName The name of the (multivalued) property to compare against
483
-     * @param mixed $operand The value to compare with
484
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
485
-     * @api
486
-     */
487
-    public function contains($propertyName, $operand)
488
-    {
489
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_CONTAINS, $operand);
490
-    }
491
-
492
-    /**
493
-     * Returns an "in" criterion used for matching objects against a query. It
494
-     * matches if the property's value is contained in the multivalued operand.
495
-     *
496
-     * @param string $propertyName The name of the property to compare against
497
-     * @param mixed $operand The value to compare with, multivalued
498
-     * @throws UnexpectedTypeException
499
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
500
-     * @api
501
-     */
502
-    public function in($propertyName, $operand)
503
-    {
504
-        if (!is_array($operand) && !$operand instanceof \ArrayAccess && !$operand instanceof \Traversable) {
505
-            throw new UnexpectedTypeException('The "in" operator must be given a mutlivalued operand (array, ArrayAccess, Traversable).', 1264678095);
506
-        }
507
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_IN, $operand);
508
-    }
509
-
510
-    /**
511
-     * Returns a less than criterion used for matching objects against a query
512
-     *
513
-     * @param string $propertyName The name of the property to compare against
514
-     * @param mixed $operand The value to compare with
515
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
516
-     * @api
517
-     */
518
-    public function lessThan($propertyName, $operand)
519
-    {
520
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LESS_THAN, $operand);
521
-    }
522
-
523
-    /**
524
-     * Returns a less or equal than criterion used for matching objects against a query
525
-     *
526
-     * @param string $propertyName The name of the property to compare against
527
-     * @param mixed $operand The value to compare with
528
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
529
-     * @api
530
-     */
531
-    public function lessThanOrEqual($propertyName, $operand)
532
-    {
533
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LESS_THAN_OR_EQUAL_TO, $operand);
534
-    }
535
-
536
-    /**
537
-     * Returns a greater than criterion used for matching objects against a query
538
-     *
539
-     * @param string $propertyName The name of the property to compare against
540
-     * @param mixed $operand The value to compare with
541
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
542
-     * @api
543
-     */
544
-    public function greaterThan($propertyName, $operand)
545
-    {
546
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_GREATER_THAN, $operand);
547
-    }
548
-
549
-    /**
550
-     * Returns a greater than or equal criterion used for matching objects against a query
551
-     *
552
-     * @param string $propertyName The name of the property to compare against
553
-     * @param mixed $operand The value to compare with
554
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
555
-     * @api
556
-     */
557
-    public function greaterThanOrEqual($propertyName, $operand)
558
-    {
559
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_GREATER_THAN_OR_EQUAL_TO, $operand);
560
-    }
561
-
562
-    /**
563
-     * Returns the query result count.
564
-     *
565
-     * @return integer The query result count
566
-     * @api
567
-     */
568
-    public function count()
569
-    {
570
-        /** @var VidiDbBackend $backend */
571
-        $backend = $this->getObjectManager()->get(VidiDbBackend::class, $this);
572
-        return $backend->countResult();
573
-    }
574
-
575
-    /**
576
-     * Returns an "isEmpty" criterion used for matching objects against a query.
577
-     * It matches if the multivalued property contains no values or is null.
578
-     *
579
-     * @param string $propertyName The name of the multivalued property to compare against
580
-     * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
581
-     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException if used on a single-valued property
582
-     * @api
583
-     */
584
-    public function isEmpty($propertyName)
585
-    {
586
-        throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
587
-    }
588
-
589
-    /**
590
-     * @return string
591
-     */
592
-    public function getDistinct()
593
-    {
594
-        return $this->distinct;
595
-    }
596
-
597
-    /**
598
-     * @param string $distinct
599
-     * @return $this
600
-     */
601
-    public function setDistinct($distinct)
602
-    {
603
-        $this->distinct = $distinct;
604
-        return $this;
605
-    }
606
-
607
-    /**
608
-     * Sets the statement of this query. If you use this, you will lose the abstraction from a concrete storage
609
-     * backend (database).
610
-     *
611
-     * @param string|\TYPO3\CMS\Core\Database\PreparedStatement $statement The statement
612
-     * @param array $parameters An array of parameters. These will be bound to placeholders '?' in the $statement.
613
-     * @return QueryInterface
614
-     */
615
-    public function statement($statement, array $parameters = array())
616
-    {
617
-        $this->statement = $this->qomFactory->statement($statement, $parameters);
618
-        return $this;
619
-    }
620
-
621
-    /**
622
-     * Returns the statement of this query.
623
-     *
624
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
625
-     */
626
-    public function getStatement()
627
-    {
628
-        return $this->statement;
629
-    }
630
-
631
-    /**
632
-     * Returns whether the current mode is Backend.
633
-     *
634
-     * @return bool
635
-     */
636
-    protected function isBackendMode()
637
-    {
638
-        return ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend();
639
-    }
640
-
641
-    /**
642
-     * @return string
643
-     */
644
-    public function getSourceFieldName()
645
-    {
646
-        return $this->sourceFieldName;
647
-    }
648
-
649
-    /**
650
-     * @param string $sourceFieldName
651
-     * @return $this
652
-     */
653
-    public function setSourceFieldName($sourceFieldName)
654
-    {
655
-        $this->sourceFieldName = $sourceFieldName;
656
-        return $this;
657
-    }
658
-
659
-    /**
660
-     * @return object|\TYPO3\CMS\Extbase\Object\ObjectManager
661
-     */
662
-    protected function getObjectManager()
663
-    {
664
-        return GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
665
-    }
29
+	/**
30
+	 * An inner join.
31
+	 */
32
+	const JCR_JOIN_TYPE_INNER = '{http://www.jcp.org/jcr/1.0}joinTypeInner';
33
+
34
+	/**
35
+	 * A left-outer join.
36
+	 */
37
+	const JCR_JOIN_TYPE_LEFT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeLeftOuter';
38
+
39
+	/**
40
+	 * A right-outer join.
41
+	 */
42
+	const JCR_JOIN_TYPE_RIGHT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeRightOuter';
43
+
44
+	/**
45
+	 * Charset of strings in QOM
46
+	 */
47
+	const CHARSET = 'utf-8';
48
+
49
+	/**
50
+	 * @var string
51
+	 */
52
+	protected $sourceFieldName;
53
+
54
+	/**
55
+	 * @var string
56
+	 */
57
+	protected $type;
58
+
59
+	/**
60
+	 * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
61
+	 */
62
+	protected $persistenceManager;
63
+
64
+	/**
65
+	 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory
66
+	 */
67
+	protected $qomFactory;
68
+
69
+	/**
70
+	 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface
71
+	 */
72
+	protected $source;
73
+
74
+	/**
75
+	 * @var ConstraintInterface
76
+	 */
77
+	protected $constraint;
78
+
79
+	/**
80
+	 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
81
+	 */
82
+	protected $statement;
83
+
84
+	/**
85
+	 * @var array
86
+	 */
87
+	protected $orderings = [];
88
+
89
+	/**
90
+	 * @var int
91
+	 */
92
+	protected $limit;
93
+
94
+	/**
95
+	 * @var int
96
+	 */
97
+	protected $offset;
98
+
99
+	/**
100
+	 * Apply DISTINCT upon property.
101
+	 *
102
+	 * @var string
103
+	 */
104
+	protected $distinct;
105
+
106
+	/**
107
+	 * The query settings.
108
+	 *
109
+	 * @var \Fab\Vidi\Persistence\QuerySettings
110
+	 * @Inject
111
+	 */
112
+	public $querySettings;
113
+
114
+	/**
115
+	 * Constructs a query object working on the given class name
116
+	 *
117
+	 * @param string $type
118
+	 */
119
+	public function __construct($type)
120
+	{
121
+		$this->type = $type;
122
+	}
123
+
124
+	/**
125
+	 * Injects the persistence manager, used to fetch the CR session
126
+	 *
127
+	 * @param \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager
128
+	 * @return void
129
+	 */
130
+	public function injectPersistenceManager(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager)
131
+	{
132
+		$this->persistenceManager = $persistenceManager;
133
+	}
134
+
135
+	/**
136
+	 * Injects the Query Object Model Factory
137
+	 *
138
+	 * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory
139
+	 * @return void
140
+	 */
141
+	public function injectQomFactory(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory)
142
+	{
143
+		$this->qomFactory = $qomFactory;
144
+	}
145
+
146
+	/**
147
+	 * Sets the Query Settings. These Query settings must match the settings expected by
148
+	 * the specific Storage Backend.
149
+	 *
150
+	 * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings The Query Settings
151
+	 * @return void
152
+	 * @api This method is not part of FLOW3 API
153
+	 */
154
+	public function setQuerySettings(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings)
155
+	{
156
+		$this->querySettings = $querySettings;
157
+	}
158
+
159
+	/**
160
+	 * Returns the Query Settings.
161
+	 *
162
+	 * @throws \Exception
163
+	 * @return \Fab\Vidi\Persistence\QuerySettings $querySettings The Query Settings
164
+	 * @api This method is not part of FLOW3 API
165
+	 */
166
+	public function getQuerySettings()
167
+	{
168
+		if (!$this->querySettings instanceof \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface) {
169
+			throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception('Tried to get the query settings without setting them before.', 1248689115);
170
+		}
171
+
172
+		// Apply possible settings to the query.
173
+		if ($this->isBackendMode()) {
174
+			/** @var \TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager $backendConfigurationManager */
175
+			$backendConfigurationManager = $this->getObjectManager()->get('TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager');
176
+			$configuration = $backendConfigurationManager->getTypoScriptSetup();
177
+			$querySettings = array('respectSysLanguage');
178
+			foreach ($querySettings as $setting) {
179
+				if (isset($configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting])) {
180
+					$value = (bool)$configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting];
181
+					ObjectAccess::setProperty($this->querySettings, $setting, $value);
182
+				}
183
+			}
184
+		}
185
+
186
+		return $this->querySettings;
187
+	}
188
+
189
+	/**
190
+	 * Returns the type this query cares for.
191
+	 *
192
+	 * @return string
193
+	 * @api
194
+	 */
195
+	public function getType()
196
+	{
197
+		return $this->type;
198
+	}
199
+
200
+	/**
201
+	 * Sets the source to fetch the result from
202
+	 *
203
+	 * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source
204
+	 */
205
+	public function setSource(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source)
206
+	{
207
+		$this->source = $source;
208
+	}
209
+
210
+	/**
211
+	 * Returns the selectorn name or an empty string, if the source is not a selector
212
+	 * TODO This has to be checked at another place
213
+	 *
214
+	 * @return string The selector name
215
+	 */
216
+	protected function getSelectorName()
217
+	{
218
+		if ($this->getSource() instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface) {
219
+			return $this->source->getSelectorName();
220
+		} else {
221
+			return '';
222
+		}
223
+	}
224
+
225
+	/**
226
+	 * Gets the node-tuple source for this query.
227
+	 *
228
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface the node-tuple source; non-null
229
+	 */
230
+	public function getSource()
231
+	{
232
+		if ($this->source === null) {
233
+			$this->source = $this->qomFactory->selector($this->getType());
234
+		}
235
+		return $this->source;
236
+	}
237
+
238
+	/**
239
+	 * Executes the query against the database and returns the result
240
+	 *
241
+	 * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array The query result object or an array if $this->getQuerySettings()->getReturnRawQueryResult() is true
242
+	 * @api
243
+	 */
244
+	public function execute($returnRawQueryResult = false)
245
+	{
246
+		/** @var VidiDbBackend $backend */
247
+		$backend = $this->getObjectManager()->get(VidiDbBackend::class, $this);
248
+		return $backend->fetchResult();
249
+	}
250
+
251
+	/**
252
+	 * Sets the property names to order the result by. Expected like this:
253
+	 * array(
254
+	 * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
255
+	 * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
256
+	 * )
257
+	 * where 'foo' and 'bar' are property names.
258
+	 *
259
+	 * @param array $orderings The property names to order by
260
+	 * @return QueryInterface
261
+	 * @api
262
+	 */
263
+	public function setOrderings(array $orderings)
264
+	{
265
+		$this->orderings = $orderings;
266
+		return $this;
267
+	}
268
+
269
+	/**
270
+	 * Returns the property names to order the result by. Like this:
271
+	 * array(
272
+	 * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
273
+	 * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
274
+	 * )
275
+	 *
276
+	 * @return array
277
+	 */
278
+	public function getOrderings()
279
+	{
280
+		return $this->orderings;
281
+	}
282
+
283
+	/**
284
+	 * Sets the maximum size of the result set to limit. Returns $this to allow
285
+	 * for chaining (fluid interface)
286
+	 *
287
+	 * @param integer $limit
288
+	 * @throws \InvalidArgumentException
289
+	 * @return QueryInterface
290
+	 * @api
291
+	 */
292
+	public function setLimit($limit)
293
+	{
294
+		if (!is_int($limit) || $limit < 1) {
295
+			throw new \InvalidArgumentException('The limit must be an integer >= 1', 1245071870);
296
+		}
297
+		$this->limit = $limit;
298
+		return $this;
299
+	}
300
+
301
+	/**
302
+	 * Resets a previously set maximum size of the result set. Returns $this to allow
303
+	 * for chaining (fluid interface)
304
+	 *
305
+	 * @return QueryInterface
306
+	 * @api
307
+	 */
308
+	public function unsetLimit()
309
+	{
310
+		unset($this->limit);
311
+		return $this;
312
+	}
313
+
314
+	/**
315
+	 * Returns the maximum size of the result set to limit.
316
+	 *
317
+	 * @return integer
318
+	 * @api
319
+	 */
320
+	public function getLimit()
321
+	{
322
+		return $this->limit;
323
+	}
324
+
325
+	/**
326
+	 * Sets the start offset of the result set to offset. Returns $this to
327
+	 * allow for chaining (fluid interface)
328
+	 *
329
+	 * @param integer $offset
330
+	 * @throws \InvalidArgumentException
331
+	 * @return QueryInterface
332
+	 * @api
333
+	 */
334
+	public function setOffset($offset)
335
+	{
336
+		if (!is_int($offset) || $offset < 0) {
337
+			throw new \InvalidArgumentException('The offset must be a positive integer', 1245071872);
338
+		}
339
+		$this->offset = $offset;
340
+		return $this;
341
+	}
342
+
343
+	/**
344
+	 * Returns the start offset of the result set.
345
+	 *
346
+	 * @return integer
347
+	 * @api
348
+	 */
349
+	public function getOffset()
350
+	{
351
+		return $this->offset;
352
+	}
353
+
354
+	/**
355
+	 * The constraint used to limit the result set. Returns $this to allow
356
+	 * for chaining (fluid interface)
357
+	 *
358
+	 * @param ConstraintInterface $constraint
359
+	 * @return QueryInterface
360
+	 * @api
361
+	 */
362
+	public function matching($constraint)
363
+	{
364
+		$this->constraint = $constraint;
365
+		return $this;
366
+	}
367
+
368
+	/**
369
+	 * Gets the constraint for this query.
370
+	 *
371
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface the constraint, or null if none
372
+	 * @api
373
+	 */
374
+	public function getConstraint()
375
+	{
376
+		return $this->constraint;
377
+	}
378
+
379
+	/**
380
+	 * Performs a logical conjunction of the given constraints. The method takes one or more contraints and concatenates them with a boolean AND.
381
+	 * It also scepts a single array of constraints to be concatenated.
382
+	 *
383
+	 * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
384
+	 * @throws InvalidNumberOfConstraintsException
385
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\AndInterface
386
+	 * @api
387
+	 */
388
+	public function logicalAnd($constraint1)
389
+	{
390
+		if (is_array($constraint1)) {
391
+			$resultingConstraint = array_shift($constraint1);
392
+			$constraints = $constraint1;
393
+		} else {
394
+			$constraints = func_get_args();
395
+			$resultingConstraint = array_shift($constraints);
396
+		}
397
+		if ($resultingConstraint === null) {
398
+			throw new InvalidNumberOfConstraintsException('There must be at least one constraint or a non-empty array of constraints given.', 1401289500);
399
+		}
400
+		foreach ($constraints as $constraint) {
401
+			$resultingConstraint = $this->qomFactory->_and($resultingConstraint, $constraint);
402
+		}
403
+		return $resultingConstraint;
404
+	}
405
+
406
+	/**
407
+	 * Performs a logical disjunction of the two given constraints
408
+	 *
409
+	 * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
410
+	 * @throws InvalidNumberOfConstraintsException
411
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\OrInterface
412
+	 * @api
413
+	 */
414
+	public function logicalOr($constraint1)
415
+	{
416
+		if (is_array($constraint1)) {
417
+			$resultingConstraint = array_shift($constraint1);
418
+			$constraints = $constraint1;
419
+		} else {
420
+			$constraints = func_get_args();
421
+			$resultingConstraint = array_shift($constraints);
422
+		}
423
+		if ($resultingConstraint === null) {
424
+			throw new InvalidNumberOfConstraintsException('There must be at least one constraint or a non-empty array of constraints given.', 1401289501);
425
+		}
426
+		foreach ($constraints as $constraint) {
427
+			$resultingConstraint = $this->qomFactory->_or($resultingConstraint, $constraint);
428
+		}
429
+		return $resultingConstraint;
430
+	}
431
+
432
+	/**
433
+	 * Performs a logical negation of the given constraint
434
+	 *
435
+	 * @param ConstraintInterface $constraint Constraint to negate
436
+	 * @throws \RuntimeException
437
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\NotInterface
438
+	 * @api
439
+	 */
440
+	public function logicalNot(ConstraintInterface $constraint)
441
+	{
442
+		return $this->qomFactory->not($constraint);
443
+	}
444
+
445
+	/**
446
+	 * Returns an equals criterion used for matching objects against a query
447
+	 *
448
+	 * @param string $propertyName The name of the property to compare against
449
+	 * @param mixed $operand The value to compare with
450
+	 * @param boolean $caseSensitive Whether the equality test should be done case-sensitive
451
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
452
+	 * @api
453
+	 */
454
+	public function equals($propertyName, $operand, $caseSensitive = true)
455
+	{
456
+		if (is_object($operand) || $caseSensitive) {
457
+			$comparison = $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_EQUAL_TO, $operand);
458
+		} else {
459
+			$comparison = $this->qomFactory->comparison($this->qomFactory->lowerCase($this->qomFactory->propertyValue($propertyName, $this->getSelectorName())), QueryInterface::OPERATOR_EQUAL_TO, \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Charset\CharsetConverter::class)->conv_case(\TYPO3\CMS\Extbase\Persistence\Generic\Query::CHARSET, $operand, 'toLower'));
460
+		}
461
+		return $comparison;
462
+	}
463
+
464
+	/**
465
+	 * Returns a like criterion used for matching objects against a query
466
+	 *
467
+	 * @param string $propertyName The name of the property to compare against
468
+	 * @param mixed $operand The value to compare with
469
+	 * @param boolean $caseSensitive Whether the matching should be done case-sensitive
470
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
471
+	 * @api
472
+	 */
473
+	public function like($propertyName, $operand, $caseSensitive = true)
474
+	{
475
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LIKE, $operand);
476
+	}
477
+
478
+	/**
479
+	 * Returns a "contains" criterion used for matching objects against a query.
480
+	 * It matches if the multivalued property contains the given operand.
481
+	 *
482
+	 * @param string $propertyName The name of the (multivalued) property to compare against
483
+	 * @param mixed $operand The value to compare with
484
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
485
+	 * @api
486
+	 */
487
+	public function contains($propertyName, $operand)
488
+	{
489
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_CONTAINS, $operand);
490
+	}
491
+
492
+	/**
493
+	 * Returns an "in" criterion used for matching objects against a query. It
494
+	 * matches if the property's value is contained in the multivalued operand.
495
+	 *
496
+	 * @param string $propertyName The name of the property to compare against
497
+	 * @param mixed $operand The value to compare with, multivalued
498
+	 * @throws UnexpectedTypeException
499
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
500
+	 * @api
501
+	 */
502
+	public function in($propertyName, $operand)
503
+	{
504
+		if (!is_array($operand) && !$operand instanceof \ArrayAccess && !$operand instanceof \Traversable) {
505
+			throw new UnexpectedTypeException('The "in" operator must be given a mutlivalued operand (array, ArrayAccess, Traversable).', 1264678095);
506
+		}
507
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_IN, $operand);
508
+	}
509
+
510
+	/**
511
+	 * Returns a less than criterion used for matching objects against a query
512
+	 *
513
+	 * @param string $propertyName The name of the property to compare against
514
+	 * @param mixed $operand The value to compare with
515
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
516
+	 * @api
517
+	 */
518
+	public function lessThan($propertyName, $operand)
519
+	{
520
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LESS_THAN, $operand);
521
+	}
522
+
523
+	/**
524
+	 * Returns a less or equal than criterion used for matching objects against a query
525
+	 *
526
+	 * @param string $propertyName The name of the property to compare against
527
+	 * @param mixed $operand The value to compare with
528
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
529
+	 * @api
530
+	 */
531
+	public function lessThanOrEqual($propertyName, $operand)
532
+	{
533
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LESS_THAN_OR_EQUAL_TO, $operand);
534
+	}
535
+
536
+	/**
537
+	 * Returns a greater than criterion used for matching objects against a query
538
+	 *
539
+	 * @param string $propertyName The name of the property to compare against
540
+	 * @param mixed $operand The value to compare with
541
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
542
+	 * @api
543
+	 */
544
+	public function greaterThan($propertyName, $operand)
545
+	{
546
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_GREATER_THAN, $operand);
547
+	}
548
+
549
+	/**
550
+	 * Returns a greater than or equal criterion used for matching objects against a query
551
+	 *
552
+	 * @param string $propertyName The name of the property to compare against
553
+	 * @param mixed $operand The value to compare with
554
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
555
+	 * @api
556
+	 */
557
+	public function greaterThanOrEqual($propertyName, $operand)
558
+	{
559
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_GREATER_THAN_OR_EQUAL_TO, $operand);
560
+	}
561
+
562
+	/**
563
+	 * Returns the query result count.
564
+	 *
565
+	 * @return integer The query result count
566
+	 * @api
567
+	 */
568
+	public function count()
569
+	{
570
+		/** @var VidiDbBackend $backend */
571
+		$backend = $this->getObjectManager()->get(VidiDbBackend::class, $this);
572
+		return $backend->countResult();
573
+	}
574
+
575
+	/**
576
+	 * Returns an "isEmpty" criterion used for matching objects against a query.
577
+	 * It matches if the multivalued property contains no values or is null.
578
+	 *
579
+	 * @param string $propertyName The name of the multivalued property to compare against
580
+	 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
581
+	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException if used on a single-valued property
582
+	 * @api
583
+	 */
584
+	public function isEmpty($propertyName)
585
+	{
586
+		throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
587
+	}
588
+
589
+	/**
590
+	 * @return string
591
+	 */
592
+	public function getDistinct()
593
+	{
594
+		return $this->distinct;
595
+	}
596
+
597
+	/**
598
+	 * @param string $distinct
599
+	 * @return $this
600
+	 */
601
+	public function setDistinct($distinct)
602
+	{
603
+		$this->distinct = $distinct;
604
+		return $this;
605
+	}
606
+
607
+	/**
608
+	 * Sets the statement of this query. If you use this, you will lose the abstraction from a concrete storage
609
+	 * backend (database).
610
+	 *
611
+	 * @param string|\TYPO3\CMS\Core\Database\PreparedStatement $statement The statement
612
+	 * @param array $parameters An array of parameters. These will be bound to placeholders '?' in the $statement.
613
+	 * @return QueryInterface
614
+	 */
615
+	public function statement($statement, array $parameters = array())
616
+	{
617
+		$this->statement = $this->qomFactory->statement($statement, $parameters);
618
+		return $this;
619
+	}
620
+
621
+	/**
622
+	 * Returns the statement of this query.
623
+	 *
624
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
625
+	 */
626
+	public function getStatement()
627
+	{
628
+		return $this->statement;
629
+	}
630
+
631
+	/**
632
+	 * Returns whether the current mode is Backend.
633
+	 *
634
+	 * @return bool
635
+	 */
636
+	protected function isBackendMode()
637
+	{
638
+		return ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend();
639
+	}
640
+
641
+	/**
642
+	 * @return string
643
+	 */
644
+	public function getSourceFieldName()
645
+	{
646
+		return $this->sourceFieldName;
647
+	}
648
+
649
+	/**
650
+	 * @param string $sourceFieldName
651
+	 * @return $this
652
+	 */
653
+	public function setSourceFieldName($sourceFieldName)
654
+	{
655
+		$this->sourceFieldName = $sourceFieldName;
656
+		return $this;
657
+	}
658
+
659
+	/**
660
+	 * @return object|\TYPO3\CMS\Extbase\Object\ObjectManager
661
+	 */
662
+	protected function getObjectManager()
663
+	{
664
+		return GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
665
+	}
666 666
 
667 667
 }
Please login to merge, or discard this patch.
Classes/Service/ClipboardService.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -81,7 +81,7 @@
 block discarded – undo
81 81
      */
82 82
     protected function getDataKey()
83 83
     {
84
-        return 'vidi_clipboard_' . $this->getModuleLoader()->getDataType();
84
+        return 'vidi_clipboard_'.$this->getModuleLoader()->getDataType();
85 85
     }
86 86
 
87 87
     /**
Please login to merge, or discard this patch.
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -18,83 +18,83 @@
 block discarded – undo
18 18
 class ClipboardService implements SingletonInterface
19 19
 {
20 20
 
21
-    /**
22
-     * Get the Matcher object of the clipboard.
23
-     *
24
-     * @return Matcher
25
-     */
26
-    public function getMatcher()
27
-    {
28
-        $matcher = $this->getBackendUser()->getModuleData($this->getDataKey());
29
-        if (!$matcher) {
30
-            /** @var $matcher Matcher */
31
-            $matcher = GeneralUtility::makeInstance(\Fab\Vidi\Persistence\Matcher::class);
32
-        }
33
-        return $matcher;
34
-    }
21
+	/**
22
+	 * Get the Matcher object of the clipboard.
23
+	 *
24
+	 * @return Matcher
25
+	 */
26
+	public function getMatcher()
27
+	{
28
+		$matcher = $this->getBackendUser()->getModuleData($this->getDataKey());
29
+		if (!$matcher) {
30
+			/** @var $matcher Matcher */
31
+			$matcher = GeneralUtility::makeInstance(\Fab\Vidi\Persistence\Matcher::class);
32
+		}
33
+		return $matcher;
34
+	}
35 35
 
36
-    /**
37
-     * Tell whether the clipboard has items or not.
38
-     *
39
-     * @return bool
40
-     */
41
-    public function hasItems()
42
-    {
43
-        $matcher = $this->getMatcher();
36
+	/**
37
+	 * Tell whether the clipboard has items or not.
38
+	 *
39
+	 * @return bool
40
+	 */
41
+	public function hasItems()
42
+	{
43
+		$matcher = $this->getMatcher();
44 44
 
45
-        $inCriteria = $matcher->getIn();
46
-        $likeCriteria = $matcher->getLike();
47
-        $searchTerm = $matcher->getSearchTerm();
45
+		$inCriteria = $matcher->getIn();
46
+		$likeCriteria = $matcher->getLike();
47
+		$searchTerm = $matcher->getSearchTerm();
48 48
 
49
-        $hasItems = !empty($inCriteria) || !empty($likeCriteria) || !empty($searchTerm);
50
-        return $hasItems;
51
-    }
49
+		$hasItems = !empty($inCriteria) || !empty($likeCriteria) || !empty($searchTerm);
50
+		return $hasItems;
51
+	}
52 52
 
53
-    /**
54
-     * Save data into the clipboard.
55
-     *
56
-     * @param Matcher $matches
57
-     */
58
-    public function save(Matcher $matches)
59
-    {
60
-        $this->getBackendUser()->pushModuleData($this->getDataKey(), $matches);
61
-    }
53
+	/**
54
+	 * Save data into the clipboard.
55
+	 *
56
+	 * @param Matcher $matches
57
+	 */
58
+	public function save(Matcher $matches)
59
+	{
60
+		$this->getBackendUser()->pushModuleData($this->getDataKey(), $matches);
61
+	}
62 62
 
63
-    /**
64
-     * Completely empty the clipboard for a data type.
65
-     *
66
-     * @return void
67
-     */
68
-    public function flush()
69
-    {
70
-        $this->getBackendUser()->pushModuleData($this->getDataKey(), null);
71
-    }
63
+	/**
64
+	 * Completely empty the clipboard for a data type.
65
+	 *
66
+	 * @return void
67
+	 */
68
+	public function flush()
69
+	{
70
+		$this->getBackendUser()->pushModuleData($this->getDataKey(), null);
71
+	}
72 72
 
73
-    /**
74
-     * @return string
75
-     */
76
-    protected function getDataKey()
77
-    {
78
-        return 'vidi_clipboard_' . $this->getModuleLoader()->getDataType();
79
-    }
73
+	/**
74
+	 * @return string
75
+	 */
76
+	protected function getDataKey()
77
+	{
78
+		return 'vidi_clipboard_' . $this->getModuleLoader()->getDataType();
79
+	}
80 80
 
81
-    /**
82
-     * Get the Vidi Module Loader.
83
-     *
84
-     * @return \Fab\Vidi\Module\ModuleLoader|object
85
-     */
86
-    protected function getModuleLoader()
87
-    {
88
-        return GeneralUtility::makeInstance(\Fab\Vidi\Module\ModuleLoader::class);
89
-    }
81
+	/**
82
+	 * Get the Vidi Module Loader.
83
+	 *
84
+	 * @return \Fab\Vidi\Module\ModuleLoader|object
85
+	 */
86
+	protected function getModuleLoader()
87
+	{
88
+		return GeneralUtility::makeInstance(\Fab\Vidi\Module\ModuleLoader::class);
89
+	}
90 90
 
91
-    /**
92
-     * Returns an instance of the current Backend User.
93
-     *
94
-     * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
95
-     */
96
-    protected function getBackendUser()
97
-    {
98
-        return $GLOBALS['BE_USER'];
99
-    }
91
+	/**
92
+	 * Returns an instance of the current Backend User.
93
+	 *
94
+	 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
95
+	 */
96
+	protected function getBackendUser()
97
+	{
98
+		return $GLOBALS['BE_USER'];
99
+	}
100 100
 }
Please login to merge, or discard this patch.
Classes/View/Grid/Row.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
             $output[$this->getFieldName()] = $value;
127 127
         }
128 128
 
129
-        $output['DT_RowId'] = 'row-' . $object->getUid();
129
+        $output['DT_RowId'] = 'row-'.$object->getUid();
130 130
         $output['DT_RowClass'] = sprintf('%s_%s', $object->getDataType(), $object->getUid());
131 131
 
132 132
         return $output;
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
         foreach ($localizedStructure as $index => $structure) {
328 328
 
329 329
             $localizedStructure[$index]['value'] = sprintf('<span>%s %s</span>',
330
-                empty($structure['languageFlag']) ? '' : $this->getIconFactory()->getIcon('flags-' . $structure['languageFlag'], Icon::SIZE_SMALL),
330
+                empty($structure['languageFlag']) ? '' : $this->getIconFactory()->getIcon('flags-'.$structure['languageFlag'], Icon::SIZE_SMALL),
331 331
                 $structure['value']
332 332
             );
333 333
         }
@@ -352,7 +352,7 @@  discard block
 block discarded – undo
352 352
             $enablesMethods = array('Hidden', 'Deleted', 'StartTime', 'EndTime');
353 353
             foreach ($enablesMethods as $enableMethod) {
354 354
 
355
-                $methodName = 'get' . $enableMethod . 'Field';
355
+                $methodName = 'get'.$enableMethod.'Field';
356 356
 
357 357
                 // Fetch possible hidden filed.
358 358
                 $enableField = Tca::table($object)->$methodName();
Please login to merge, or discard this patch.
Indentation   +623 added lines, -623 removed lines patch added patch discarded remove patch
@@ -25,628 +25,628 @@
 block discarded – undo
25 25
 class Row extends AbstractComponentView
26 26
 {
27 27
 
28
-    /**
29
-     * @var array
30
-     */
31
-    protected $columns = [];
32
-
33
-    /**
34
-     * Registry for storing variable values and speed up the processing.
35
-     *
36
-     * @var array
37
-     */
38
-    protected $variables = [];
39
-
40
-    /**
41
-     * @param array $columns
42
-     */
43
-    public function __construct(array $columns = [])
44
-    {
45
-        $this->columns = $columns;
46
-    }
47
-
48
-    /**
49
-     * Render a row to be displayed in the Grid given an Content Object.
50
-     *
51
-     * @param \Fab\Vidi\Domain\Model\Content $object
52
-     * @param int $rowIndex
53
-     * @return array
54
-     * @throws \Exception
55
-     */
56
-    public function render(Content $object = null, $rowIndex = 0)
57
-    {
58
-
59
-        // Initialize returned array
60
-        $output = [];
61
-
62
-        foreach (Tca::grid()->getFields() as $fieldNameAndPath => $configuration) {
63
-
64
-            $value = ''; // default is empty at first.
65
-
66
-            $this->computeVariables($object, $fieldNameAndPath);
67
-
68
-            // Only compute the value if it is going to be shown in the Grid. Lost of time otherwise!
69
-            if (in_array($fieldNameAndPath, $this->columns)) {
70
-
71
-                // Fetch value
72
-                if (Tca::grid()->hasRenderers($fieldNameAndPath)) {
73
-
74
-                    $value = '';
75
-                    $renderers = Tca::grid()->getRenderers($fieldNameAndPath);
76
-
77
-                    // if is relation has one
78
-                    foreach ($renderers as $rendererClassName => $rendererConfiguration) {
79
-
80
-                        /** @var $rendererObject \Fab\Vidi\Grid\ColumnRendererInterface */
81
-                        $rendererObject = GeneralUtility::makeInstance($rendererClassName);
82
-                        $value .= $rendererObject
83
-                            ->setObject($object)
84
-                            ->setFieldName($fieldNameAndPath)
85
-                            ->setRowIndex($rowIndex)
86
-                            ->setFieldConfiguration($configuration)
87
-                            ->setGridRendererConfiguration($rendererConfiguration)
88
-                            ->render();
89
-                    }
90
-                } else {
91
-                    $value = $this->resolveValue($object, $fieldNameAndPath);
92
-                    $value = $this->processValue($value, $object, $fieldNameAndPath); // post resolve processing.
93
-                }
94
-
95
-                // Possible formatting given by configuration. @see TCA['grid']
96
-                $value = $this->formatValue($value, $configuration);
97
-
98
-                // Here, there is the chance to further "decorate" the value for inline editing, localization, ...
99
-                if ($this->willBeEnriched()) {
100
-
101
-                    $localizedStructure = $this->initializeLocalizedStructure($value);
102
-
103
-                    if ($this->isEditable()) {
104
-                        $localizedStructure = $this->addEditableMarkup($localizedStructure);
105
-                    }
106
-
107
-                    if ($this->isLocalized()) {
108
-                        $localizedStructure = $this->addLocalizationMarkup($localizedStructure);
109
-                    }
110
-
111
-                    if ($this->hasIcon()) {
112
-                        $localizedStructure = $this->addSpriteIconMarkup($localizedStructure);
113
-                    }
114
-
115
-                    $value = $this->flattenStructure($localizedStructure);
116
-                }
117
-
118
-                // Final wrap given by configuration. @see TCA['grid']
119
-                $value = $this->wrapValue($value, $configuration);
120
-            }
121
-
122
-            $output[$this->getFieldName()] = $value;
123
-        }
124
-
125
-        $output['DT_RowId'] = 'row-' . $object->getUid();
126
-        $output['DT_RowClass'] = sprintf('%s_%s', $object->getDataType(), $object->getUid());
127
-
128
-        return $output;
129
-    }
130
-
131
-    /**
132
-     * Flatten the localized structure to render the final value
133
-     *
134
-     * @param array $localizedStructure
135
-     * @return string
136
-     */
137
-    protected function flattenStructure(array $localizedStructure)
138
-    {
139
-
140
-        // Flatten the structure.
141
-        $value = '';
142
-        foreach ($localizedStructure as $structure) {
143
-            $value .= sprintf('<div class="%s">%s</div>',
144
-                $structure['status'] !== LocalizationStatus::LOCALIZED ? 'invisible' : '',
145
-                $structure['value']
146
-            );
147
-        }
148
-        return $value;
149
-    }
150
-
151
-    /**
152
-     * Store some often used variable values and speed up the processing.
153
-     *
154
-     * @param \Fab\Vidi\Domain\Model\Content $object
155
-     * @param string $fieldNameAndPath
156
-     * @return void
157
-     */
158
-    protected function computeVariables(Content $object, $fieldNameAndPath)
159
-    {
160
-        $this->variables = [];
161
-        $this->variables['dataType'] = $this->getFieldPathResolver()->getDataType($fieldNameAndPath);
162
-        $this->variables['fieldName'] = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
163
-        $this->variables['fieldNameAndPath'] = $fieldNameAndPath;
164
-        $this->variables['object'] = $object;
165
-    }
166
-
167
-    /**
168
-     * Tell whether the object will be decorated / wrapped such as
169
-     *
170
-     * @param string $value
171
-     * @return array
172
-     */
173
-    protected function initializeLocalizedStructure($value)
174
-    {
175
-
176
-        $localizedStructure[] = [
177
-            'value' => empty($value) && $this->isEditable() ? $this->getEmptyValuePlaceholder() : $value,
178
-            'status' => empty($value) ? LocalizationStatus::EMPTY_VALUE : LocalizationStatus::LOCALIZED,
179
-            'language' => 0,
180
-            'languageFlag' => $defaultLanguage = $this->getLanguageService()->getDefaultFlag(),
181
-        ];
182
-
183
-        if ($this->isLocalized()) {
184
-
185
-            foreach ($this->getLanguageService()->getLanguages() as $language) {
186
-
187
-                // Make sure the language is allowed for the current Backend User.
188
-                if ($this->isLanguageAllowedForBackendUser($language)) {
189
-
190
-                    $resolvedObject = $this->getResolvedObject();
191
-                    $fieldName = $this->getFieldName();
192
-
193
-                    if ($this->getLanguageService()->hasLocalization($resolvedObject, $language['uid'])) {
194
-                        $localizedValue = $this->getLanguageService()->getLocalizedFieldName($resolvedObject, $language['uid'], $fieldName);
195
-                        $status = LocalizationStatus::LOCALIZED;
196
-
197
-                        // Replace blank value by something more meaningful for the End User.
198
-                        if (empty($localizedValue)) {
199
-                            $status = LocalizationStatus::EMPTY_VALUE;
200
-                            $localizedValue = $this->isEditable() ? $this->getEmptyValuePlaceholder() : '';
201
-                        }
202
-                    } else {
203
-                        $localizedValue = sprintf('<a href="%s" style="color: black">%s</a>',
204
-                            $this->getLocalizedUri($language['uid']),
205
-                            $this->getLabelService()->sL('LLL:EXT:vidi/Resources/Private/Language/locallang.xlf:create_translation')
206
-                        );
207
-                        $status = LocalizationStatus::NOT_YET_LOCALIZED;
208
-                    }
209
-
210
-                    // Feed structure.
211
-                    $localizedStructure[] = [
212
-                        'value' => $localizedValue,
213
-                        'status' => $status,
214
-                        'language' => (int)$language['uid'],
215
-                        'languageFlag' => $language['flag'],
216
-                    ];
217
-                }
218
-            }
219
-        }
220
-
221
-        return $localizedStructure;
222
-    }
223
-
224
-    /**
225
-     * @param array $language
226
-     * @return bool
227
-     */
228
-    protected function isLanguageAllowedForBackendUser(array $language)
229
-    {
230
-        return $this->getBackendUser()->checkLanguageAccess($language['uid']);
231
-    }
232
-
233
-    /**
234
-     * Returns a placeholder when the value is empty.
235
-     *
236
-     * @return string
237
-     */
238
-    protected function getEmptyValuePlaceholder()
239
-    {
240
-        return sprintf('<i>%s</i>',
241
-            $this->getLabelService()->sL('LLL:EXT:vidi/Resources/Private/Language/locallang.xlf:start_editing')
242
-        );
243
-    }
244
-
245
-    /**
246
-     * Tell whether the object will be decorated (or wrapped) for inline editing, localization purpose.
247
-     *
248
-     * @return bool
249
-     */
250
-    protected function willBeEnriched()
251
-    {
252
-
253
-        $willBeEnriched = false;
254
-
255
-        if ($this->fieldExists()) {
256
-            $willBeEnriched = $this->isEditable() || $this->hasIcon() || $this->isLocalized();
257
-        }
258
-
259
-        return $willBeEnriched;
260
-    }
261
-
262
-    /**
263
-     * Tell whether the field in the context will be prepended by an icon.
264
-     *
265
-     * @return bool
266
-     */
267
-    protected function hasIcon()
268
-    {
269
-        $dataType = $this->getDataType();
270
-        return Tca::table($dataType)->getLabelField() === $this->getFieldName();
271
-    }
272
-
273
-    /**
274
-     * Tell whether the field in the context will be prepended by an icon.
275
-     *
276
-     * @return bool
277
-     */
278
-    protected function isLocalized()
279
-    {
280
-        $object = $this->getObject();
281
-        $fieldName = $this->getFieldName();
282
-        $dataType = $this->getDataType();
283
-        $fieldNameAndPath = $this->getFieldNameAndPath();
284
-
285
-        return $this->getLanguageService()->hasLanguages()
286
-        && Tca::grid($object)->isLocalized($fieldNameAndPath)
287
-        && Tca::table($dataType)->field($fieldName)->isLocalized();
288
-    }
289
-
290
-    /**
291
-     * Add some markup to have the content editable in the Grid.
292
-     *
293
-     * @param array $localizedStructure
294
-     * @return array
295
-     */
296
-    protected function addEditableMarkup(array $localizedStructure)
297
-    {
298
-
299
-        $dataType = $this->getDataType();
300
-        $fieldName = $this->getFieldName();
301
-
302
-        foreach ($localizedStructure as $index => $structure) {
303
-            if ($structure['status'] !== LocalizationStatus::NOT_YET_LOCALIZED) {
304
-                $localizedStructure[$index]['value'] = sprintf('<span class="%s" data-language="%s">%s</span>',
305
-                    Tca::table($dataType)->field($fieldName)->isTextArea() ? 'editable-textarea' : 'editable-textfield',
306
-                    $structure['language'],
307
-                    $structure['value']
308
-                );
309
-            }
310
-        }
311
-        return $localizedStructure;
312
-    }
313
-
314
-    /**
315
-     * Add some markup related to the localization.
316
-     *
317
-     * @param array $localizedStructure
318
-     * @return array
319
-     */
320
-    protected function addLocalizationMarkup(array $localizedStructure)
321
-    {
322
-
323
-        foreach ($localizedStructure as $index => $structure) {
324
-
325
-            $localizedStructure[$index]['value'] = sprintf('<span>%s %s</span>',
326
-                empty($structure['languageFlag']) ? '' : $this->getIconFactory()->getIcon('flags-' . $structure['languageFlag'], Icon::SIZE_SMALL),
327
-                $structure['value']
328
-            );
329
-        }
330
-        return $localizedStructure;
331
-    }
332
-
333
-    /**
334
-     * Add some markup related to the prepended icon.
335
-     *
336
-     * @param array $localizedStructure
337
-     * @return array
338
-     */
339
-    protected function addSpriteIconMarkup(array $localizedStructure)
340
-    {
341
-
342
-        $object = $this->getObject();
343
-
344
-        foreach ($localizedStructure as $index => $structure) {
345
-
346
-            $recordData = [];
347
-
348
-            $enablesMethods = array('Hidden', 'Deleted', 'StartTime', 'EndTime');
349
-            foreach ($enablesMethods as $enableMethod) {
350
-
351
-                $methodName = 'get' . $enableMethod . 'Field';
352
-
353
-                // Fetch possible hidden filed.
354
-                $enableField = Tca::table($object)->$methodName();
355
-                if ($enableField) {
356
-                    $recordData[$enableField] = $object[$enableField];
357
-                }
358
-            }
359
-
360
-            // Get Enable Fields of the object to render the sprite with overlays.
361
-            $localizedStructure[$index]['value'] = sprintf('%s %s',
362
-                $this->getIconFactory()->getIconForRecord($object->getDataType(), $recordData, Icon::SIZE_SMALL),
363
-                $structure['value']
364
-            );
365
-        }
366
-
367
-        return $localizedStructure;
368
-    }
369
-
370
-    /**
371
-     * Return whether the field given by the context is editable.
372
-     *
373
-     * @return boolean
374
-     */
375
-    protected function isEditable()
376
-    {
377
-        $fieldNameAndPath = $this->getFieldNameAndPath();
378
-        $dataType = $this->getDataType();
379
-        $fieldName = $this->getFieldName();
380
-
381
-        return Tca::grid()->isEditable($fieldNameAndPath)
382
-        && Tca::table($dataType)->hasField($fieldName)
383
-        && Tca::table($dataType)->field($fieldName)->hasNoRelation(); // relation are editable through Renderers only.
384
-    }
385
-
386
-    /**
387
-     * Return the appropriate URI to create the translation.
388
-     *
389
-     * @param int $language
390
-     * @return string
391
-     */
392
-    protected function getLocalizedUri($language)
393
-    {
394
-
395
-        // Transmit recursive selection parameter.
396
-        $parameterPrefix = $this->getModuleLoader()->getParameterPrefix();
397
-        $parameters = GeneralUtility::_GP($parameterPrefix);
398
-
399
-        $additionalParameters = array(
400
-            $this->getModuleLoader()->getParameterPrefix() => array(
401
-                'controller' => 'Content',
402
-                'action' => 'localize',
403
-                'format' => 'json',
404
-                'hasRecursiveSelection' => isset($parameters['hasRecursiveSelection']) ? (int)$parameters['hasRecursiveSelection'] : 0,
405
-                'fieldNameAndPath' => $this->getFieldNameAndPath(),
406
-                'language' => $language,
407
-                'matches' => array(
408
-                    'uid' => $this->getObject()->getUid(),
409
-                ),
410
-            ),
411
-        );
412
-
413
-        return $this->getModuleLoader()->getModuleUrl($additionalParameters);
414
-    }
415
-
416
-    /**
417
-     * Compute the value for the Content object according to a field name.
418
-     *
419
-     * @param \Fab\Vidi\Domain\Model\Content $object
420
-     * @param string $fieldNameAndPath
421
-     * @return string
422
-     */
423
-    protected function resolveValue(Content $object, $fieldNameAndPath)
424
-    {
425
-
426
-        // Get the first part of the field name and
427
-        $fieldName = $this->getFieldPathResolver()->stripFieldName($fieldNameAndPath);
428
-
429
-        $value = $object[$fieldName];
430
-
431
-        // Relation but contains no data.
432
-        if (is_array($value) && empty($value)) {
433
-            $value = '';
434
-        } elseif ($value instanceof Content) {
435
-
436
-            $fieldNameOfForeignTable = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
437
-
438
-            // true means the field name does not contains a path. "title" vs "metadata.title"
439
-            // Fetch the default label
440
-            if ($fieldNameOfForeignTable === $fieldName) {
441
-                $foreignTable = Tca::table($object->getDataType())->field($fieldName)->getForeignTable();
442
-                $fieldNameOfForeignTable = Tca::table($foreignTable)->getLabelField();
443
-            }
444
-
445
-            $value = $object[$fieldName][$fieldNameOfForeignTable];
446
-        }
447
-
448
-        return $value;
449
-    }
450
-
451
-    /**
452
-     * Check whether a string contains HTML tags.
453
-     *
454
-     * @param string $string the content to be analyzed
455
-     * @return boolean
456
-     */
457
-    protected function hasHtml($string)
458
-    {
459
-        $result = false;
460
-
461
-        // We compare the length of the string with html tags and without html tags.
462
-        if (strlen($string) !== strlen(strip_tags($string))) {
463
-            $result = true;
464
-        }
465
-        return $result;
466
-    }
467
-
468
-    /**
469
-     * Check whether a string contains potential XSS.
470
-     *
471
-     * @param string $string the content to be analyzed
472
-     * @return boolean
473
-     */
474
-    protected function isClean($string)
475
-    {
476
-
477
-        // @todo implement me!
478
-        $result = true;
479
-        return $result;
480
-    }
481
-
482
-    /**
483
-     * Process the value
484
-     *
485
-     * @todo implement me as a processor chain to be cleaner implementation wise. Look out at the performance however!
486
-     *       e.g DefaultValueGridProcessor, TextAreaGridProcessor, ...
487
-     *
488
-     * @param string $value
489
-     * @param \Fab\Vidi\Domain\Model\Content $object
490
-     * @param string $fieldNameAndPath
491
-     * @return string
492
-     * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
493
-     */
494
-    protected function processValue($value, Content $object, $fieldNameAndPath)
495
-    {
496
-
497
-        // Set default value if $field name correspond to the label of the table
498
-        $fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
499
-        if (Tca::table($object->getDataType())->getLabelField() === $fieldName && empty($value)) {
500
-            $value = sprintf('[%s]', $this->getLabelService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.no_title'));
501
-        }
502
-
503
-        // Sanitize the value in case of "select" or "radio button".
504
-        if (is_scalar($value)) {
505
-            $fieldType = Tca::table($object->getDataType())->field($fieldNameAndPath)->getType();
506
-            if ($fieldType !== FieldType::TEXTAREA) {
507
-                $value = htmlspecialchars($value);
508
-            } elseif ($fieldType === FieldType::TEXTAREA && !$this->isClean($value)) {
509
-                $value = htmlspecialchars($value); // Avoid bad surprise, converts characters to HTML.
510
-            } elseif ($fieldType === FieldType::TEXTAREA && !$this->hasHtml($value)) {
511
-                $value = nl2br($value);
512
-            }
513
-        }
514
-
515
-        return $value;
516
-    }
517
-
518
-    /**
519
-     * Possible value formatting.
520
-     *
521
-     * @param string $value
522
-     * @param array $configuration
523
-     * @return string
524
-     * @throws \InvalidArgumentException
525
-     */
526
-    protected function formatValue($value, array $configuration)
527
-    {
528
-        if (empty($configuration['format'])) {
529
-            return $value;
530
-        }
531
-        $className = $configuration['format'];
532
-
533
-        /** @var \Fab\Vidi\Formatter\FormatterInterface $formatter */
534
-        $formatter = GeneralUtility::makeInstance($className);
535
-        $value = $formatter->format($value);
536
-
537
-        return $value;
538
-    }
539
-
540
-    /**
541
-     * Possible value wrapping.
542
-     *
543
-     * @param string $value
544
-     * @param array $configuration
545
-     * @return string
546
-     */
547
-    protected function wrapValue($value, array $configuration)
548
-    {
549
-        if (!empty($configuration['wrap'])) {
550
-            $parts = explode('|', $configuration['wrap']);
551
-            $value = implode($value, $parts);
552
-        }
553
-        return $value;
554
-    }
555
-
556
-    /**
557
-     * Tell whether the field in the context really exists.
558
-     *
559
-     * @return bool
560
-     */
561
-    protected function fieldExists()
562
-    {
563
-        if ($this->variables['hasField'] === null) {
564
-            $dataType = $this->getDataType();
565
-            $fieldName = $this->getFieldName();
566
-            $this->variables['hasField'] = Tca::table($dataType)->hasField($fieldName);
567
-        }
568
-        return $this->variables['hasField'];
569
-    }
570
-
571
-    /**
572
-     * @return string
573
-     */
574
-    protected function getDataType()
575
-    {
576
-        return $this->variables['dataType'];
577
-    }
578
-
579
-    /**
580
-     * @return string
581
-     */
582
-    protected function getFieldName()
583
-    {
584
-        return $this->variables['fieldName'];
585
-    }
586
-
587
-    /**
588
-     * @return string
589
-     */
590
-    protected function getFieldNameAndPath()
591
-    {
592
-        return $this->variables['fieldNameAndPath'];
593
-    }
594
-
595
-    /**
596
-     * @return Content
597
-     */
598
-    protected function getObject()
599
-    {
600
-        return $this->variables['object'];
601
-    }
602
-
603
-    /**
604
-     * @return Content
605
-     * @throws \InvalidArgumentException
606
-     */
607
-    protected function getResolvedObject()
608
-    {
609
-        if (empty($this->variables['resolvedObject'])) {
610
-            $object = $this->getObject();
611
-            $fieldNameAndPath = $this->getFieldNameAndPath();
612
-            $this->variables['resolvedObject'] = $this->getContentObjectResolver()->getObject($object, $fieldNameAndPath);
613
-        }
614
-        return $this->variables['resolvedObject'];
615
-    }
616
-
617
-    /**
618
-     * @return FieldPathResolver|object
619
-     * @throws \InvalidArgumentException
620
-     */
621
-    protected function getFieldPathResolver()
622
-    {
623
-        return GeneralUtility::makeInstance(FieldPathResolver::class);
624
-    }
625
-
626
-    /**
627
-     * @return ContentObjectResolver|object
628
-     * @throws \InvalidArgumentException
629
-     */
630
-    protected function getContentObjectResolver()
631
-    {
632
-        return GeneralUtility::makeInstance(ContentObjectResolver::class);
633
-    }
634
-
635
-    /**
636
-     * @return \TYPO3\CMS\Core\Localization\LanguageService
637
-     */
638
-    protected function getLabelService()
639
-    {
640
-        return $GLOBALS['LANG'];
641
-    }
642
-
643
-    /**
644
-     * @return LanguageService|object
645
-     * @throws \InvalidArgumentException
646
-     */
647
-    protected function getLanguageService()
648
-    {
649
-        return GeneralUtility::makeInstance(LanguageService::class);
650
-    }
28
+	/**
29
+	 * @var array
30
+	 */
31
+	protected $columns = [];
32
+
33
+	/**
34
+	 * Registry for storing variable values and speed up the processing.
35
+	 *
36
+	 * @var array
37
+	 */
38
+	protected $variables = [];
39
+
40
+	/**
41
+	 * @param array $columns
42
+	 */
43
+	public function __construct(array $columns = [])
44
+	{
45
+		$this->columns = $columns;
46
+	}
47
+
48
+	/**
49
+	 * Render a row to be displayed in the Grid given an Content Object.
50
+	 *
51
+	 * @param \Fab\Vidi\Domain\Model\Content $object
52
+	 * @param int $rowIndex
53
+	 * @return array
54
+	 * @throws \Exception
55
+	 */
56
+	public function render(Content $object = null, $rowIndex = 0)
57
+	{
58
+
59
+		// Initialize returned array
60
+		$output = [];
61
+
62
+		foreach (Tca::grid()->getFields() as $fieldNameAndPath => $configuration) {
63
+
64
+			$value = ''; // default is empty at first.
65
+
66
+			$this->computeVariables($object, $fieldNameAndPath);
67
+
68
+			// Only compute the value if it is going to be shown in the Grid. Lost of time otherwise!
69
+			if (in_array($fieldNameAndPath, $this->columns)) {
70
+
71
+				// Fetch value
72
+				if (Tca::grid()->hasRenderers($fieldNameAndPath)) {
73
+
74
+					$value = '';
75
+					$renderers = Tca::grid()->getRenderers($fieldNameAndPath);
76
+
77
+					// if is relation has one
78
+					foreach ($renderers as $rendererClassName => $rendererConfiguration) {
79
+
80
+						/** @var $rendererObject \Fab\Vidi\Grid\ColumnRendererInterface */
81
+						$rendererObject = GeneralUtility::makeInstance($rendererClassName);
82
+						$value .= $rendererObject
83
+							->setObject($object)
84
+							->setFieldName($fieldNameAndPath)
85
+							->setRowIndex($rowIndex)
86
+							->setFieldConfiguration($configuration)
87
+							->setGridRendererConfiguration($rendererConfiguration)
88
+							->render();
89
+					}
90
+				} else {
91
+					$value = $this->resolveValue($object, $fieldNameAndPath);
92
+					$value = $this->processValue($value, $object, $fieldNameAndPath); // post resolve processing.
93
+				}
94
+
95
+				// Possible formatting given by configuration. @see TCA['grid']
96
+				$value = $this->formatValue($value, $configuration);
97
+
98
+				// Here, there is the chance to further "decorate" the value for inline editing, localization, ...
99
+				if ($this->willBeEnriched()) {
100
+
101
+					$localizedStructure = $this->initializeLocalizedStructure($value);
102
+
103
+					if ($this->isEditable()) {
104
+						$localizedStructure = $this->addEditableMarkup($localizedStructure);
105
+					}
106
+
107
+					if ($this->isLocalized()) {
108
+						$localizedStructure = $this->addLocalizationMarkup($localizedStructure);
109
+					}
110
+
111
+					if ($this->hasIcon()) {
112
+						$localizedStructure = $this->addSpriteIconMarkup($localizedStructure);
113
+					}
114
+
115
+					$value = $this->flattenStructure($localizedStructure);
116
+				}
117
+
118
+				// Final wrap given by configuration. @see TCA['grid']
119
+				$value = $this->wrapValue($value, $configuration);
120
+			}
121
+
122
+			$output[$this->getFieldName()] = $value;
123
+		}
124
+
125
+		$output['DT_RowId'] = 'row-' . $object->getUid();
126
+		$output['DT_RowClass'] = sprintf('%s_%s', $object->getDataType(), $object->getUid());
127
+
128
+		return $output;
129
+	}
130
+
131
+	/**
132
+	 * Flatten the localized structure to render the final value
133
+	 *
134
+	 * @param array $localizedStructure
135
+	 * @return string
136
+	 */
137
+	protected function flattenStructure(array $localizedStructure)
138
+	{
139
+
140
+		// Flatten the structure.
141
+		$value = '';
142
+		foreach ($localizedStructure as $structure) {
143
+			$value .= sprintf('<div class="%s">%s</div>',
144
+				$structure['status'] !== LocalizationStatus::LOCALIZED ? 'invisible' : '',
145
+				$structure['value']
146
+			);
147
+		}
148
+		return $value;
149
+	}
150
+
151
+	/**
152
+	 * Store some often used variable values and speed up the processing.
153
+	 *
154
+	 * @param \Fab\Vidi\Domain\Model\Content $object
155
+	 * @param string $fieldNameAndPath
156
+	 * @return void
157
+	 */
158
+	protected function computeVariables(Content $object, $fieldNameAndPath)
159
+	{
160
+		$this->variables = [];
161
+		$this->variables['dataType'] = $this->getFieldPathResolver()->getDataType($fieldNameAndPath);
162
+		$this->variables['fieldName'] = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
163
+		$this->variables['fieldNameAndPath'] = $fieldNameAndPath;
164
+		$this->variables['object'] = $object;
165
+	}
166
+
167
+	/**
168
+	 * Tell whether the object will be decorated / wrapped such as
169
+	 *
170
+	 * @param string $value
171
+	 * @return array
172
+	 */
173
+	protected function initializeLocalizedStructure($value)
174
+	{
175
+
176
+		$localizedStructure[] = [
177
+			'value' => empty($value) && $this->isEditable() ? $this->getEmptyValuePlaceholder() : $value,
178
+			'status' => empty($value) ? LocalizationStatus::EMPTY_VALUE : LocalizationStatus::LOCALIZED,
179
+			'language' => 0,
180
+			'languageFlag' => $defaultLanguage = $this->getLanguageService()->getDefaultFlag(),
181
+		];
182
+
183
+		if ($this->isLocalized()) {
184
+
185
+			foreach ($this->getLanguageService()->getLanguages() as $language) {
186
+
187
+				// Make sure the language is allowed for the current Backend User.
188
+				if ($this->isLanguageAllowedForBackendUser($language)) {
189
+
190
+					$resolvedObject = $this->getResolvedObject();
191
+					$fieldName = $this->getFieldName();
192
+
193
+					if ($this->getLanguageService()->hasLocalization($resolvedObject, $language['uid'])) {
194
+						$localizedValue = $this->getLanguageService()->getLocalizedFieldName($resolvedObject, $language['uid'], $fieldName);
195
+						$status = LocalizationStatus::LOCALIZED;
196
+
197
+						// Replace blank value by something more meaningful for the End User.
198
+						if (empty($localizedValue)) {
199
+							$status = LocalizationStatus::EMPTY_VALUE;
200
+							$localizedValue = $this->isEditable() ? $this->getEmptyValuePlaceholder() : '';
201
+						}
202
+					} else {
203
+						$localizedValue = sprintf('<a href="%s" style="color: black">%s</a>',
204
+							$this->getLocalizedUri($language['uid']),
205
+							$this->getLabelService()->sL('LLL:EXT:vidi/Resources/Private/Language/locallang.xlf:create_translation')
206
+						);
207
+						$status = LocalizationStatus::NOT_YET_LOCALIZED;
208
+					}
209
+
210
+					// Feed structure.
211
+					$localizedStructure[] = [
212
+						'value' => $localizedValue,
213
+						'status' => $status,
214
+						'language' => (int)$language['uid'],
215
+						'languageFlag' => $language['flag'],
216
+					];
217
+				}
218
+			}
219
+		}
220
+
221
+		return $localizedStructure;
222
+	}
223
+
224
+	/**
225
+	 * @param array $language
226
+	 * @return bool
227
+	 */
228
+	protected function isLanguageAllowedForBackendUser(array $language)
229
+	{
230
+		return $this->getBackendUser()->checkLanguageAccess($language['uid']);
231
+	}
232
+
233
+	/**
234
+	 * Returns a placeholder when the value is empty.
235
+	 *
236
+	 * @return string
237
+	 */
238
+	protected function getEmptyValuePlaceholder()
239
+	{
240
+		return sprintf('<i>%s</i>',
241
+			$this->getLabelService()->sL('LLL:EXT:vidi/Resources/Private/Language/locallang.xlf:start_editing')
242
+		);
243
+	}
244
+
245
+	/**
246
+	 * Tell whether the object will be decorated (or wrapped) for inline editing, localization purpose.
247
+	 *
248
+	 * @return bool
249
+	 */
250
+	protected function willBeEnriched()
251
+	{
252
+
253
+		$willBeEnriched = false;
254
+
255
+		if ($this->fieldExists()) {
256
+			$willBeEnriched = $this->isEditable() || $this->hasIcon() || $this->isLocalized();
257
+		}
258
+
259
+		return $willBeEnriched;
260
+	}
261
+
262
+	/**
263
+	 * Tell whether the field in the context will be prepended by an icon.
264
+	 *
265
+	 * @return bool
266
+	 */
267
+	protected function hasIcon()
268
+	{
269
+		$dataType = $this->getDataType();
270
+		return Tca::table($dataType)->getLabelField() === $this->getFieldName();
271
+	}
272
+
273
+	/**
274
+	 * Tell whether the field in the context will be prepended by an icon.
275
+	 *
276
+	 * @return bool
277
+	 */
278
+	protected function isLocalized()
279
+	{
280
+		$object = $this->getObject();
281
+		$fieldName = $this->getFieldName();
282
+		$dataType = $this->getDataType();
283
+		$fieldNameAndPath = $this->getFieldNameAndPath();
284
+
285
+		return $this->getLanguageService()->hasLanguages()
286
+		&& Tca::grid($object)->isLocalized($fieldNameAndPath)
287
+		&& Tca::table($dataType)->field($fieldName)->isLocalized();
288
+	}
289
+
290
+	/**
291
+	 * Add some markup to have the content editable in the Grid.
292
+	 *
293
+	 * @param array $localizedStructure
294
+	 * @return array
295
+	 */
296
+	protected function addEditableMarkup(array $localizedStructure)
297
+	{
298
+
299
+		$dataType = $this->getDataType();
300
+		$fieldName = $this->getFieldName();
301
+
302
+		foreach ($localizedStructure as $index => $structure) {
303
+			if ($structure['status'] !== LocalizationStatus::NOT_YET_LOCALIZED) {
304
+				$localizedStructure[$index]['value'] = sprintf('<span class="%s" data-language="%s">%s</span>',
305
+					Tca::table($dataType)->field($fieldName)->isTextArea() ? 'editable-textarea' : 'editable-textfield',
306
+					$structure['language'],
307
+					$structure['value']
308
+				);
309
+			}
310
+		}
311
+		return $localizedStructure;
312
+	}
313
+
314
+	/**
315
+	 * Add some markup related to the localization.
316
+	 *
317
+	 * @param array $localizedStructure
318
+	 * @return array
319
+	 */
320
+	protected function addLocalizationMarkup(array $localizedStructure)
321
+	{
322
+
323
+		foreach ($localizedStructure as $index => $structure) {
324
+
325
+			$localizedStructure[$index]['value'] = sprintf('<span>%s %s</span>',
326
+				empty($structure['languageFlag']) ? '' : $this->getIconFactory()->getIcon('flags-' . $structure['languageFlag'], Icon::SIZE_SMALL),
327
+				$structure['value']
328
+			);
329
+		}
330
+		return $localizedStructure;
331
+	}
332
+
333
+	/**
334
+	 * Add some markup related to the prepended icon.
335
+	 *
336
+	 * @param array $localizedStructure
337
+	 * @return array
338
+	 */
339
+	protected function addSpriteIconMarkup(array $localizedStructure)
340
+	{
341
+
342
+		$object = $this->getObject();
343
+
344
+		foreach ($localizedStructure as $index => $structure) {
345
+
346
+			$recordData = [];
347
+
348
+			$enablesMethods = array('Hidden', 'Deleted', 'StartTime', 'EndTime');
349
+			foreach ($enablesMethods as $enableMethod) {
350
+
351
+				$methodName = 'get' . $enableMethod . 'Field';
352
+
353
+				// Fetch possible hidden filed.
354
+				$enableField = Tca::table($object)->$methodName();
355
+				if ($enableField) {
356
+					$recordData[$enableField] = $object[$enableField];
357
+				}
358
+			}
359
+
360
+			// Get Enable Fields of the object to render the sprite with overlays.
361
+			$localizedStructure[$index]['value'] = sprintf('%s %s',
362
+				$this->getIconFactory()->getIconForRecord($object->getDataType(), $recordData, Icon::SIZE_SMALL),
363
+				$structure['value']
364
+			);
365
+		}
366
+
367
+		return $localizedStructure;
368
+	}
369
+
370
+	/**
371
+	 * Return whether the field given by the context is editable.
372
+	 *
373
+	 * @return boolean
374
+	 */
375
+	protected function isEditable()
376
+	{
377
+		$fieldNameAndPath = $this->getFieldNameAndPath();
378
+		$dataType = $this->getDataType();
379
+		$fieldName = $this->getFieldName();
380
+
381
+		return Tca::grid()->isEditable($fieldNameAndPath)
382
+		&& Tca::table($dataType)->hasField($fieldName)
383
+		&& Tca::table($dataType)->field($fieldName)->hasNoRelation(); // relation are editable through Renderers only.
384
+	}
385
+
386
+	/**
387
+	 * Return the appropriate URI to create the translation.
388
+	 *
389
+	 * @param int $language
390
+	 * @return string
391
+	 */
392
+	protected function getLocalizedUri($language)
393
+	{
394
+
395
+		// Transmit recursive selection parameter.
396
+		$parameterPrefix = $this->getModuleLoader()->getParameterPrefix();
397
+		$parameters = GeneralUtility::_GP($parameterPrefix);
398
+
399
+		$additionalParameters = array(
400
+			$this->getModuleLoader()->getParameterPrefix() => array(
401
+				'controller' => 'Content',
402
+				'action' => 'localize',
403
+				'format' => 'json',
404
+				'hasRecursiveSelection' => isset($parameters['hasRecursiveSelection']) ? (int)$parameters['hasRecursiveSelection'] : 0,
405
+				'fieldNameAndPath' => $this->getFieldNameAndPath(),
406
+				'language' => $language,
407
+				'matches' => array(
408
+					'uid' => $this->getObject()->getUid(),
409
+				),
410
+			),
411
+		);
412
+
413
+		return $this->getModuleLoader()->getModuleUrl($additionalParameters);
414
+	}
415
+
416
+	/**
417
+	 * Compute the value for the Content object according to a field name.
418
+	 *
419
+	 * @param \Fab\Vidi\Domain\Model\Content $object
420
+	 * @param string $fieldNameAndPath
421
+	 * @return string
422
+	 */
423
+	protected function resolveValue(Content $object, $fieldNameAndPath)
424
+	{
425
+
426
+		// Get the first part of the field name and
427
+		$fieldName = $this->getFieldPathResolver()->stripFieldName($fieldNameAndPath);
428
+
429
+		$value = $object[$fieldName];
430
+
431
+		// Relation but contains no data.
432
+		if (is_array($value) && empty($value)) {
433
+			$value = '';
434
+		} elseif ($value instanceof Content) {
435
+
436
+			$fieldNameOfForeignTable = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
437
+
438
+			// true means the field name does not contains a path. "title" vs "metadata.title"
439
+			// Fetch the default label
440
+			if ($fieldNameOfForeignTable === $fieldName) {
441
+				$foreignTable = Tca::table($object->getDataType())->field($fieldName)->getForeignTable();
442
+				$fieldNameOfForeignTable = Tca::table($foreignTable)->getLabelField();
443
+			}
444
+
445
+			$value = $object[$fieldName][$fieldNameOfForeignTable];
446
+		}
447
+
448
+		return $value;
449
+	}
450
+
451
+	/**
452
+	 * Check whether a string contains HTML tags.
453
+	 *
454
+	 * @param string $string the content to be analyzed
455
+	 * @return boolean
456
+	 */
457
+	protected function hasHtml($string)
458
+	{
459
+		$result = false;
460
+
461
+		// We compare the length of the string with html tags and without html tags.
462
+		if (strlen($string) !== strlen(strip_tags($string))) {
463
+			$result = true;
464
+		}
465
+		return $result;
466
+	}
467
+
468
+	/**
469
+	 * Check whether a string contains potential XSS.
470
+	 *
471
+	 * @param string $string the content to be analyzed
472
+	 * @return boolean
473
+	 */
474
+	protected function isClean($string)
475
+	{
476
+
477
+		// @todo implement me!
478
+		$result = true;
479
+		return $result;
480
+	}
481
+
482
+	/**
483
+	 * Process the value
484
+	 *
485
+	 * @todo implement me as a processor chain to be cleaner implementation wise. Look out at the performance however!
486
+	 *       e.g DefaultValueGridProcessor, TextAreaGridProcessor, ...
487
+	 *
488
+	 * @param string $value
489
+	 * @param \Fab\Vidi\Domain\Model\Content $object
490
+	 * @param string $fieldNameAndPath
491
+	 * @return string
492
+	 * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
493
+	 */
494
+	protected function processValue($value, Content $object, $fieldNameAndPath)
495
+	{
496
+
497
+		// Set default value if $field name correspond to the label of the table
498
+		$fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
499
+		if (Tca::table($object->getDataType())->getLabelField() === $fieldName && empty($value)) {
500
+			$value = sprintf('[%s]', $this->getLabelService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.no_title'));
501
+		}
502
+
503
+		// Sanitize the value in case of "select" or "radio button".
504
+		if (is_scalar($value)) {
505
+			$fieldType = Tca::table($object->getDataType())->field($fieldNameAndPath)->getType();
506
+			if ($fieldType !== FieldType::TEXTAREA) {
507
+				$value = htmlspecialchars($value);
508
+			} elseif ($fieldType === FieldType::TEXTAREA && !$this->isClean($value)) {
509
+				$value = htmlspecialchars($value); // Avoid bad surprise, converts characters to HTML.
510
+			} elseif ($fieldType === FieldType::TEXTAREA && !$this->hasHtml($value)) {
511
+				$value = nl2br($value);
512
+			}
513
+		}
514
+
515
+		return $value;
516
+	}
517
+
518
+	/**
519
+	 * Possible value formatting.
520
+	 *
521
+	 * @param string $value
522
+	 * @param array $configuration
523
+	 * @return string
524
+	 * @throws \InvalidArgumentException
525
+	 */
526
+	protected function formatValue($value, array $configuration)
527
+	{
528
+		if (empty($configuration['format'])) {
529
+			return $value;
530
+		}
531
+		$className = $configuration['format'];
532
+
533
+		/** @var \Fab\Vidi\Formatter\FormatterInterface $formatter */
534
+		$formatter = GeneralUtility::makeInstance($className);
535
+		$value = $formatter->format($value);
536
+
537
+		return $value;
538
+	}
539
+
540
+	/**
541
+	 * Possible value wrapping.
542
+	 *
543
+	 * @param string $value
544
+	 * @param array $configuration
545
+	 * @return string
546
+	 */
547
+	protected function wrapValue($value, array $configuration)
548
+	{
549
+		if (!empty($configuration['wrap'])) {
550
+			$parts = explode('|', $configuration['wrap']);
551
+			$value = implode($value, $parts);
552
+		}
553
+		return $value;
554
+	}
555
+
556
+	/**
557
+	 * Tell whether the field in the context really exists.
558
+	 *
559
+	 * @return bool
560
+	 */
561
+	protected function fieldExists()
562
+	{
563
+		if ($this->variables['hasField'] === null) {
564
+			$dataType = $this->getDataType();
565
+			$fieldName = $this->getFieldName();
566
+			$this->variables['hasField'] = Tca::table($dataType)->hasField($fieldName);
567
+		}
568
+		return $this->variables['hasField'];
569
+	}
570
+
571
+	/**
572
+	 * @return string
573
+	 */
574
+	protected function getDataType()
575
+	{
576
+		return $this->variables['dataType'];
577
+	}
578
+
579
+	/**
580
+	 * @return string
581
+	 */
582
+	protected function getFieldName()
583
+	{
584
+		return $this->variables['fieldName'];
585
+	}
586
+
587
+	/**
588
+	 * @return string
589
+	 */
590
+	protected function getFieldNameAndPath()
591
+	{
592
+		return $this->variables['fieldNameAndPath'];
593
+	}
594
+
595
+	/**
596
+	 * @return Content
597
+	 */
598
+	protected function getObject()
599
+	{
600
+		return $this->variables['object'];
601
+	}
602
+
603
+	/**
604
+	 * @return Content
605
+	 * @throws \InvalidArgumentException
606
+	 */
607
+	protected function getResolvedObject()
608
+	{
609
+		if (empty($this->variables['resolvedObject'])) {
610
+			$object = $this->getObject();
611
+			$fieldNameAndPath = $this->getFieldNameAndPath();
612
+			$this->variables['resolvedObject'] = $this->getContentObjectResolver()->getObject($object, $fieldNameAndPath);
613
+		}
614
+		return $this->variables['resolvedObject'];
615
+	}
616
+
617
+	/**
618
+	 * @return FieldPathResolver|object
619
+	 * @throws \InvalidArgumentException
620
+	 */
621
+	protected function getFieldPathResolver()
622
+	{
623
+		return GeneralUtility::makeInstance(FieldPathResolver::class);
624
+	}
625
+
626
+	/**
627
+	 * @return ContentObjectResolver|object
628
+	 * @throws \InvalidArgumentException
629
+	 */
630
+	protected function getContentObjectResolver()
631
+	{
632
+		return GeneralUtility::makeInstance(ContentObjectResolver::class);
633
+	}
634
+
635
+	/**
636
+	 * @return \TYPO3\CMS\Core\Localization\LanguageService
637
+	 */
638
+	protected function getLabelService()
639
+	{
640
+		return $GLOBALS['LANG'];
641
+	}
642
+
643
+	/**
644
+	 * @return LanguageService|object
645
+	 * @throws \InvalidArgumentException
646
+	 */
647
+	protected function getLanguageService()
648
+	{
649
+		return GeneralUtility::makeInstance(LanguageService::class);
650
+	}
651 651
 
652 652
 }
Please login to merge, or discard this patch.
Tests/Functional/Domain/Model/ContentTest.php 1 patch
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@  discard block
 block discarded – undo
16 16
 
17 17
 use Fab\Vidi\Tests\Functional\AbstractFunctionalTestCase;
18 18
 
19
-require_once dirname(dirname(dirname(__FILE__))) . '/AbstractFunctionalTestCase.php';
19
+require_once dirname(dirname(dirname(__FILE__))).'/AbstractFunctionalTestCase.php';
20 20
 
21 21
 /**
22 22
  * Test case for class \Fab\Vidi\Domain\Model\Content.
@@ -113,8 +113,8 @@  discard block
 block discarded – undo
113 113
 	 * @dataProvider propertyProvider
114 114
 	 */
115 115
 	public function testProperty($propertyName, $value) {
116
-		$setter = 'set' . ucfirst($propertyName);
117
-		$getter = 'get' . ucfirst($propertyName);
116
+		$setter = 'set'.ucfirst($propertyName);
117
+		$getter = 'get'.ucfirst($propertyName);
118 118
 		$this->markTestIncomplete(); # TCA must be faked
119 119
 		#call_user_func_array(array($this->fixture, $setter), array($value));
120 120
 		#$this->assertEquals($value, call_user_func(array($this->fixture, $getter)));
Please login to merge, or discard this patch.
Tests/Functional/Module/ModuleLoaderTest.php 1 patch
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@  discard block
 block discarded – undo
16 16
 
17 17
 use Fab\Vidi\Tests\Functional\AbstractFunctionalTestCase;
18 18
 
19
-require_once dirname(dirname(__FILE__)) . '/AbstractFunctionalTestCase.php';
19
+require_once dirname(dirname(__FILE__)).'/AbstractFunctionalTestCase.php';
20 20
 
21 21
 /**
22 22
  * Test case for class \Fab\Vidi\Module\ModuleLoader.
@@ -54,7 +54,7 @@  discard block
 block discarded – undo
54 54
 	 * @dataProvider attributeValueProvider
55 55
 	 */
56 56
 	public function attributeCanBeSet($attribute, $value) {
57
-		$setter = 'set' . ucfirst($attribute);
57
+		$setter = 'set'.ucfirst($attribute);
58 58
 		$this->fixture->$setter($value);
59 59
 		$this->assertAttributeEquals($value, $attribute, $this->fixture);
60 60
 	}
Please login to merge, or discard this patch.
Tests/Functional/Grid/RelationRendererTest.php 1 patch
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@
 block discarded – undo
16 16
 
17 17
 use Fab\Vidi\Tests\Functional\AbstractFunctionalTestCase;
18 18
 
19
-require_once dirname(dirname(__FILE__)) . '/AbstractFunctionalTestCase.php';
19
+require_once dirname(dirname(__FILE__)).'/AbstractFunctionalTestCase.php';
20 20
 
21 21
 /**
22 22
  * Test case for class \Fab\Vidi\Grid\CategoryRenderer.
Please login to merge, or discard this patch.