Completed
Push — master ( e90a07...f1d658 )
by Fabien
03:22
created
Classes/Service/ClipboardService.php 1 patch
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -24,83 +24,83 @@
 block discarded – undo
24 24
 class ClipboardService implements SingletonInterface
25 25
 {
26 26
 
27
-    /**
28
-     * Get the Matcher object of the clipboard.
29
-     *
30
-     * @return Matcher
31
-     */
32
-    public function getMatcher()
33
-    {
34
-        $matcher = $this->getBackendUser()->getModuleData($this->getDataKey());
35
-        if (!$matcher) {
36
-            /** @var $matcher Matcher */
37
-            $matcher = GeneralUtility::makeInstance('Fab\Vidi\Persistence\Matcher');
38
-        }
39
-        return $matcher;
40
-    }
27
+	/**
28
+	 * Get the Matcher object of the clipboard.
29
+	 *
30
+	 * @return Matcher
31
+	 */
32
+	public function getMatcher()
33
+	{
34
+		$matcher = $this->getBackendUser()->getModuleData($this->getDataKey());
35
+		if (!$matcher) {
36
+			/** @var $matcher Matcher */
37
+			$matcher = GeneralUtility::makeInstance('Fab\Vidi\Persistence\Matcher');
38
+		}
39
+		return $matcher;
40
+	}
41 41
 
42
-    /**
43
-     * Tell whether the clipboard has items or not.
44
-     *
45
-     * @return bool
46
-     */
47
-    public function hasItems()
48
-    {
49
-        $matcher = $this->getMatcher();
42
+	/**
43
+	 * Tell whether the clipboard has items or not.
44
+	 *
45
+	 * @return bool
46
+	 */
47
+	public function hasItems()
48
+	{
49
+		$matcher = $this->getMatcher();
50 50
 
51
-        $inCriteria = $matcher->getIn();
52
-        $likeCriteria = $matcher->getLike();
53
-        $searchTerm = $matcher->getSearchTerm();
51
+		$inCriteria = $matcher->getIn();
52
+		$likeCriteria = $matcher->getLike();
53
+		$searchTerm = $matcher->getSearchTerm();
54 54
 
55
-        $hasItems = !empty($inCriteria) || !empty($likeCriteria) || !empty($searchTerm);
56
-        return $hasItems;
57
-    }
55
+		$hasItems = !empty($inCriteria) || !empty($likeCriteria) || !empty($searchTerm);
56
+		return $hasItems;
57
+	}
58 58
 
59
-    /**
60
-     * Save data into the clipboard.
61
-     *
62
-     * @param Matcher $matches
63
-     */
64
-    public function save(Matcher $matches)
65
-    {
66
-        $this->getBackendUser()->pushModuleData($this->getDataKey(), $matches);
67
-    }
59
+	/**
60
+	 * Save data into the clipboard.
61
+	 *
62
+	 * @param Matcher $matches
63
+	 */
64
+	public function save(Matcher $matches)
65
+	{
66
+		$this->getBackendUser()->pushModuleData($this->getDataKey(), $matches);
67
+	}
68 68
 
69
-    /**
70
-     * Completely empty the clipboard for a data type.
71
-     *
72
-     * @return void
73
-     */
74
-    public function flush()
75
-    {
76
-        $this->getBackendUser()->pushModuleData($this->getDataKey(), NULL);
77
-    }
69
+	/**
70
+	 * Completely empty the clipboard for a data type.
71
+	 *
72
+	 * @return void
73
+	 */
74
+	public function flush()
75
+	{
76
+		$this->getBackendUser()->pushModuleData($this->getDataKey(), NULL);
77
+	}
78 78
 
79
-    /**
80
-     * @return string
81
-     */
82
-    protected function getDataKey()
83
-    {
84
-        return 'vidi_clipboard_' . $this->getModuleLoader()->getDataType();
85
-    }
79
+	/**
80
+	 * @return string
81
+	 */
82
+	protected function getDataKey()
83
+	{
84
+		return 'vidi_clipboard_' . $this->getModuleLoader()->getDataType();
85
+	}
86 86
 
87
-    /**
88
-     * Get the Vidi Module Loader.
89
-     *
90
-     * @return \Fab\Vidi\Module\ModuleLoader
91
-     */
92
-    protected function getModuleLoader()
93
-    {
94
-        return GeneralUtility::makeInstance('Fab\Vidi\Module\ModuleLoader');
95
-    }
87
+	/**
88
+	 * Get the Vidi Module Loader.
89
+	 *
90
+	 * @return \Fab\Vidi\Module\ModuleLoader
91
+	 */
92
+	protected function getModuleLoader()
93
+	{
94
+		return GeneralUtility::makeInstance('Fab\Vidi\Module\ModuleLoader');
95
+	}
96 96
 
97
-    /**
98
-     * Returns an instance of the current Backend User.
99
-     *
100
-     * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
101
-     */
102
-    protected function getBackendUser()
103
-    {
104
-        return $GLOBALS['BE_USER'];
105
-    }
97
+	/**
98
+	 * Returns an instance of the current Backend User.
99
+	 *
100
+	 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
101
+	 */
102
+	protected function getBackendUser()
103
+	{
104
+		return $GLOBALS['BE_USER'];
105
+	}
106 106
 }
Please login to merge, or discard this patch.
Classes/ViewHelpers/Result/ToXlsViewHelper.php 1 patch
Indentation   +95 added lines, -95 removed lines patch added patch discarded remove patch
@@ -23,100 +23,100 @@
 block discarded – undo
23 23
 class ToXlsViewHelper extends AbstractToFormatViewHelper
24 24
 {
25 25
 
26
-    /**
27
-     * Render a CSV export request.
28
-     *
29
-     * @return boolean
30
-     */
31
-    public function render()
32
-    {
33
-
34
-        $objects = $this->templateVariableContainer->get('objects');
35
-
36
-        // Make sure we have something to process...
37
-        if (!empty($objects)) {
38
-
39
-            // Initialization step.
40
-            $this->initializeEnvironment($objects);
41
-            $this->exportFileNameAndPath .= '.xls'; // add extension to the file.
42
-
43
-            // Write the exported data to a CSV file.
44
-            $this->writeXlsFile($objects);
45
-
46
-            // We must generate a zip archive since there are files included.
47
-            if ($this->hasCollectedFiles()) {
48
-
49
-                $this->writeZipFile();
50
-                $this->sendZipHttpHeaders();
51
-
52
-                readfile($this->zipFileNameAndPath);
53
-            } else {
54
-                $this->sendXlsHttpHeaders();
55
-                readfile($this->exportFileNameAndPath);
56
-            }
57
-
58
-            GeneralUtility::rmdir($this->temporaryDirectory, TRUE);
59
-        }
60
-    }
61
-
62
-    /**
63
-     * Write the CSV file to a temporary location.
64
-     *
65
-     * @param array $objects
66
-     * @return void
67
-     */
68
-    protected function writeXlsFile(array $objects)
69
-    {
70
-
71
-        /** @var SpreadSheetService $spreadSheet */
72
-        $spreadSheet = GeneralUtility::makeInstance(SpreadSheetService::class);
73
-
74
-        // Handle object header, get the first object and get the list of fields.
75
-        /** @var \Fab\Vidi\Domain\Model\Content $object */
76
-        $object = reset($objects);
77
-        $spreadSheet->addRow($object->toFields());
78
-
79
-        $this->checkWhetherObjectMayIncludeFiles($object);
80
-
81
-        foreach ($objects as $object) {
82
-            if ($this->hasFileFields()) {
83
-                $this->collectFiles($object);
84
-            }
85
-
86
-            // Make sure we have a flat array of values for the CSV purpose.
87
-            $flattenValues = array();
88
-            foreach ($object->toValues() as $fieldName => $value) {
89
-                if (is_array($value)) {
90
-                    $flattenValues[$fieldName] = implode(', ', $value);
91
-                } else {
92
-                    $flattenValues[$fieldName] = $value;
93
-                }
94
-            }
95
-
96
-            $spreadSheet->addRow($flattenValues);
97
-        }
98
-
99
-        file_put_contents($this->exportFileNameAndPath, $spreadSheet->toString());
100
-    }
101
-
102
-    /**
103
-     * @return void
104
-     */
105
-    protected function sendXlsHttpHeaders()
106
-    {
107
-
108
-        /** @var \TYPO3\CMS\Extbase\Mvc\Web\Response $response */
109
-        $response = $this->templateVariableContainer->get('response');
110
-        $response->setHeader('Pragma', 'public');
111
-        $response->setHeader('Expires', '0');
112
-        $response->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
113
-        $response->setHeader('Content-Type', 'application/vnd.ms-excel');
114
-        $response->setHeader('Content-Disposition', 'attachment; filename="' . basename($this->exportFileNameAndPath) . '"');
115
-        $response->setHeader('Content-Length', filesize($this->exportFileNameAndPath));
116
-        $response->setHeader('Content-Description', 'File Transfer');
117
-        $response->setHeader('Content-Transfer-Encoding', 'binary');
118
-
119
-        $response->sendHeaders();
120
-    }
26
+	/**
27
+	 * Render a CSV export request.
28
+	 *
29
+	 * @return boolean
30
+	 */
31
+	public function render()
32
+	{
33
+
34
+		$objects = $this->templateVariableContainer->get('objects');
35
+
36
+		// Make sure we have something to process...
37
+		if (!empty($objects)) {
38
+
39
+			// Initialization step.
40
+			$this->initializeEnvironment($objects);
41
+			$this->exportFileNameAndPath .= '.xls'; // add extension to the file.
42
+
43
+			// Write the exported data to a CSV file.
44
+			$this->writeXlsFile($objects);
45
+
46
+			// We must generate a zip archive since there are files included.
47
+			if ($this->hasCollectedFiles()) {
48
+
49
+				$this->writeZipFile();
50
+				$this->sendZipHttpHeaders();
51
+
52
+				readfile($this->zipFileNameAndPath);
53
+			} else {
54
+				$this->sendXlsHttpHeaders();
55
+				readfile($this->exportFileNameAndPath);
56
+			}
57
+
58
+			GeneralUtility::rmdir($this->temporaryDirectory, TRUE);
59
+		}
60
+	}
61
+
62
+	/**
63
+	 * Write the CSV file to a temporary location.
64
+	 *
65
+	 * @param array $objects
66
+	 * @return void
67
+	 */
68
+	protected function writeXlsFile(array $objects)
69
+	{
70
+
71
+		/** @var SpreadSheetService $spreadSheet */
72
+		$spreadSheet = GeneralUtility::makeInstance(SpreadSheetService::class);
73
+
74
+		// Handle object header, get the first object and get the list of fields.
75
+		/** @var \Fab\Vidi\Domain\Model\Content $object */
76
+		$object = reset($objects);
77
+		$spreadSheet->addRow($object->toFields());
78
+
79
+		$this->checkWhetherObjectMayIncludeFiles($object);
80
+
81
+		foreach ($objects as $object) {
82
+			if ($this->hasFileFields()) {
83
+				$this->collectFiles($object);
84
+			}
85
+
86
+			// Make sure we have a flat array of values for the CSV purpose.
87
+			$flattenValues = array();
88
+			foreach ($object->toValues() as $fieldName => $value) {
89
+				if (is_array($value)) {
90
+					$flattenValues[$fieldName] = implode(', ', $value);
91
+				} else {
92
+					$flattenValues[$fieldName] = $value;
93
+				}
94
+			}
95
+
96
+			$spreadSheet->addRow($flattenValues);
97
+		}
98
+
99
+		file_put_contents($this->exportFileNameAndPath, $spreadSheet->toString());
100
+	}
101
+
102
+	/**
103
+	 * @return void
104
+	 */
105
+	protected function sendXlsHttpHeaders()
106
+	{
107
+
108
+		/** @var \TYPO3\CMS\Extbase\Mvc\Web\Response $response */
109
+		$response = $this->templateVariableContainer->get('response');
110
+		$response->setHeader('Pragma', 'public');
111
+		$response->setHeader('Expires', '0');
112
+		$response->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
113
+		$response->setHeader('Content-Type', 'application/vnd.ms-excel');
114
+		$response->setHeader('Content-Disposition', 'attachment; filename="' . basename($this->exportFileNameAndPath) . '"');
115
+		$response->setHeader('Content-Length', filesize($this->exportFileNameAndPath));
116
+		$response->setHeader('Content-Description', 'File Transfer');
117
+		$response->setHeader('Content-Transfer-Encoding', 'binary');
118
+
119
+		$response->sendHeaders();
120
+	}
121 121
 
122 122
 }
Please login to merge, or discard this patch.
Classes/ViewHelpers/Result/ToJsonViewHelper.php 1 patch
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -24,56 +24,56 @@
 block discarded – undo
24 24
 class ToJsonViewHelper extends AbstractViewHelper
25 25
 {
26 26
 
27
-    /**
28
-     * Render a Json response
29
-     *
30
-     * @return boolean
31
-     */
32
-    public function render()
33
-    {
27
+	/**
28
+	 * Render a Json response
29
+	 *
30
+	 * @return boolean
31
+	 */
32
+	public function render()
33
+	{
34 34
 
35
-        $objects = $this->templateVariableContainer->get('objects');
36
-        $columns = $this->templateVariableContainer->get('columns');
37
-        $output = array(
38
-            'sEcho' => $this->getNextTransactionId(),
39
-            'iTotalRecords' => $this->templateVariableContainer->get('numberOfObjects'),
40
-            'iTotalDisplayRecords' => $this->templateVariableContainer->get('numberOfObjects'),
41
-            'iNumberOfRecords' => count($objects),
42
-            'aaData' => $this->getRowsViewHelper()->render($objects, $columns),
43
-        );
35
+		$objects = $this->templateVariableContainer->get('objects');
36
+		$columns = $this->templateVariableContainer->get('columns');
37
+		$output = array(
38
+			'sEcho' => $this->getNextTransactionId(),
39
+			'iTotalRecords' => $this->templateVariableContainer->get('numberOfObjects'),
40
+			'iTotalDisplayRecords' => $this->templateVariableContainer->get('numberOfObjects'),
41
+			'iNumberOfRecords' => count($objects),
42
+			'aaData' => $this->getRowsViewHelper()->render($objects, $columns),
43
+		);
44 44
 
45
-        $this->setHttpHeaders();
46
-        return json_encode($output);
47
-    }
45
+		$this->setHttpHeaders();
46
+		return json_encode($output);
47
+	}
48 48
 
49
-    /**
50
-     * @return int
51
-     */
52
-    protected function getNextTransactionId()
53
-    {
54
-        $transaction = 0;
55
-        if (GeneralUtility::_GET('sEcho')) {
56
-            $transaction = (int)GeneralUtility::_GET('sEcho') + 1;
57
-        }
58
-        return $transaction;
59
-    }
49
+	/**
50
+	 * @return int
51
+	 */
52
+	protected function getNextTransactionId()
53
+	{
54
+		$transaction = 0;
55
+		if (GeneralUtility::_GET('sEcho')) {
56
+			$transaction = (int)GeneralUtility::_GET('sEcho') + 1;
57
+		}
58
+		return $transaction;
59
+	}
60 60
 
61
-    /**
62
-     * @return void
63
-     */
64
-    protected function setHttpHeaders()
65
-    {
66
-        /** @var \TYPO3\CMS\Extbase\Mvc\Web\Response $response */
67
-        $response = $this->templateVariableContainer->get('response');
68
-        $response->setHeader('Content-Type', 'application/json');
69
-        $response->sendHeaders();
70
-    }
61
+	/**
62
+	 * @return void
63
+	 */
64
+	protected function setHttpHeaders()
65
+	{
66
+		/** @var \TYPO3\CMS\Extbase\Mvc\Web\Response $response */
67
+		$response = $this->templateVariableContainer->get('response');
68
+		$response->setHeader('Content-Type', 'application/json');
69
+		$response->sendHeaders();
70
+	}
71 71
 
72
-    /**
73
-     * @return RowsViewHelper
74
-     */
75
-    protected function getRowsViewHelper()
76
-    {
77
-        return $this->objectManager->get(RowsViewHelper::class);
78
-    }
72
+	/**
73
+	 * @return RowsViewHelper
74
+	 */
75
+	protected function getRowsViewHelper()
76
+	{
77
+		return $this->objectManager->get(RowsViewHelper::class);
78
+	}
79 79
 }
Please login to merge, or discard this patch.
Classes/ViewHelpers/Render/ComponentsViewHelper.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -24,31 +24,31 @@
 block discarded – undo
24 24
 class ComponentsViewHelper extends AbstractViewHelper
25 25
 {
26 26
 
27
-    /**
28
-     * Renders the position number of an content object.
29
-     *
30
-     * @param  string $part
31
-     * @return string
32
-     */
33
-    public function render($part)
34
-    {
35
-
36
-        /** @var ModuleLoader $moduleLoader */
37
-        $moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
38
-
39
-        $getComponents = 'get' . ucfirst($part) . 'Components';
40
-        $components = $moduleLoader->$getComponents();
41
-
42
-        $result = '';
43
-        foreach ($components as $component) {
44
-            $viewHelper = $this->objectManager->get($component);
45
-
46
-            // Get possible arguments but remove first one.
47
-            $arguments = func_get_args();
48
-            array_shift($arguments);
49
-            $result .= call_user_func_array(array($viewHelper, 'render'), $arguments);
50
-        }
51
-
52
-        return $result;
53
-    }
27
+	/**
28
+	 * Renders the position number of an content object.
29
+	 *
30
+	 * @param  string $part
31
+	 * @return string
32
+	 */
33
+	public function render($part)
34
+	{
35
+
36
+		/** @var ModuleLoader $moduleLoader */
37
+		$moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
38
+
39
+		$getComponents = 'get' . ucfirst($part) . 'Components';
40
+		$components = $moduleLoader->$getComponents();
41
+
42
+		$result = '';
43
+		foreach ($components as $component) {
44
+			$viewHelper = $this->objectManager->get($component);
45
+
46
+			// Get possible arguments but remove first one.
47
+			$arguments = func_get_args();
48
+			array_shift($arguments);
49
+			$result .= call_user_func_array(array($viewHelper, 'render'), $arguments);
50
+		}
51
+
52
+		return $result;
53
+	}
54 54
 }
Please login to merge, or discard this patch.
Classes/Module/ModuleLoader.php 1 patch
Indentation   +895 added lines, -895 removed lines patch added patch discarded remove patch
@@ -26,900 +26,900 @@
 block discarded – undo
26 26
 class ModuleLoader
27 27
 {
28 28
 
29
-    /**
30
-     * Define the default main module
31
-     */
32
-    const DEFAULT_MAIN_MODULE = 'content';
33
-
34
-    /**
35
-     * Define the default pid
36
-     */
37
-    const DEFAULT_PID = 0;
38
-
39
-    /**
40
-     * The type of data being listed (which corresponds to a table name in TCA)
41
-     *
42
-     * @var string
43
-     */
44
-    protected $dataType;
45
-
46
-    /**
47
-     * @var string
48
-     */
49
-    protected $defaultPid;
50
-
51
-    /**
52
-     * @var bool
53
-     */
54
-    protected $showPageTree;
55
-
56
-    /**
57
-     * @var bool
58
-     */
59
-    protected $isShown = TRUE;
60
-
61
-    /**
62
-     * @var string
63
-     */
64
-    protected $access = Access::USER;
65
-
66
-    /**
67
-     * @var string
68
-     */
69
-    protected $mainModule;
70
-
71
-    /**
72
-     * @var string
73
-     */
74
-    protected $position = '';
75
-
76
-    /**
77
-     * @var string
78
-     */
79
-    protected $icon = '';
80
-
81
-    /**
82
-     * @var string
83
-     */
84
-    protected $moduleLanguageFile = 'LLL:EXT:vidi/Resources/Private/Language/locallang_module.xlf';
85
-
86
-    /**
87
-     * The module key such as m1, m2.
88
-     *
89
-     * @var string
90
-     */
91
-    protected $moduleKey = 'm1';
92
-
93
-    /**
94
-     * @var string[]
95
-     */
96
-    protected $additionalJavaScriptFiles = array();
97
-
98
-    /**
99
-     * @var string[]
100
-     */
101
-    protected $additionalStyleSheetFiles = array();
102
-
103
-    /**
104
-     * @var array
105
-     */
106
-    protected $components = array(
107
-        ModulePosition::DOC_HEADER => array(
108
-            ModulePosition::TOP => array(
109
-                ModulePosition::LEFT => array(),
110
-                ModulePosition::RIGHT => array(
111
-                    'Fab\Vidi\View\Button\ToolButton',
112
-                ),
113
-            ),
114
-            ModulePosition::BOTTOM => array(
115
-                ModulePosition::LEFT => array(
116
-                    'Fab\Vidi\View\Button\NewButton',
117
-                    'Fab\Vidi\ViewHelpers\Link\BackViewHelper',
118
-                ),
119
-                ModulePosition::RIGHT => array(),
120
-            ),
121
-        ),
122
-        ModulePosition::GRID => array(
123
-            ModulePosition::TOP => array(
124
-                'Fab\Vidi\View\Check\PidCheck',
125
-                'Fab\Vidi\View\Check\RelationsCheck',
126
-                'Fab\Vidi\View\Tab\DataTypeTab',
127
-            ),
128
-            ModulePosition::BUTTONS => array(
129
-                'Fab\Vidi\View\Button\EditButton',
130
-                'Fab\Vidi\View\Button\DeleteButton',
131
-            ),
132
-            ModulePosition::BOTTOM => array(),
133
-        ),
134
-        ModulePosition::MENU_MASS_ACTION => array(
135
-            'Fab\Vidi\View\MenuItem\ExportXlsMenuItem',
136
-            'Fab\Vidi\View\MenuItem\ExportXmlMenuItem',
137
-            'Fab\Vidi\View\MenuItem\ExportCsvMenuItem',
138
-            'Fab\Vidi\View\MenuItem\DividerMenuItem',
139
-            'Fab\Vidi\View\MenuItem\MassDeleteMenuItem',
140
-            #'Fab\Vidi\View\MenuItem\MassEditMenuItem',
141
-        ),
142
-    );
143
-
144
-    /**
145
-     * @param string $dataType
146
-     */
147
-    public function __construct($dataType = null)
148
-    {
149
-        $this->dataType = $dataType;
150
-    }
151
-
152
-    /**
153
-     * Tell whether a module is already registered.
154
-     *
155
-     * @param string $dataType
156
-     * @return bool
157
-     */
158
-    public function isRegistered($dataType)
159
-    {
160
-        $internalModuleSignature = $this->getInternalModuleSignature($dataType);
161
-        return !empty($GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]);
162
-    }
163
-
164
-    /**
165
-     * Register the module
166
-     *
167
-     * @return void
168
-     */
169
-    public function register()
170
-    {
171
-
172
-        $this->initializeDefaultValues();
173
-        $internalModuleSignature = $this->getInternalModuleSignature();
174
-
175
-        $GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature] = array();
176
-        $GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['dataType'] = $this->dataType;
177
-        $GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['mainModule'] = $this->mainModule;
178
-        $GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['defaultPid'] = $this->defaultPid;
179
-        $GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['additionalJavaScriptFiles'] = $this->additionalJavaScriptFiles;
180
-        $GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['additionalStyleSheetFiles'] = $this->additionalStyleSheetFiles;
181
-        $GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['components'] = $this->components;
182
-
183
-        // Register and displays module in the BE only if told, default is TRUE.
184
-        if ($this->isShown) {
185
-            $moduleConfiguration = array(
186
-                #'routeTarget' => \Fab\Vidi\Controller\ContentController::class . '::mainAction', // what to do here?
187
-                'access' => $this->access,
188
-                'labels' => $this->moduleLanguageFile,
189
-                'inheritNavigationComponentFromMainModule' => TRUE
190
-            );
191
-
192
-            if (!empty($this->icon)) {
193
-                $moduleConfiguration['icon'] = $this->icon;
194
-            }
195
-
196
-            if (!is_null($this->showPageTree)) {
197
-                if ($this->showPageTree) {
198
-                    $moduleConfiguration['navigationComponentId'] = 'typo3-pagetree';
199
-                } else {
200
-                    $moduleConfiguration['inheritNavigationComponentFromMainModule'] = FALSE;
201
-                }
202
-            }
203
-
204
-            ExtensionUtility::registerModule(
205
-                'Fab.vidi',
206
-                $this->mainModule,
207
-                $this->dataType . '_' . $this->moduleKey,
208
-                $this->position,
209
-                array(
210
-                    'Content' => 'index, list, delete, update, edit, copy, move, localize, sort, copyClipboard, moveClipboard',
211
-                    'Tool' => 'welcome, work',
212
-                    'Facet' => 'autoSuggest, autoSuggests',
213
-                    'Selection' => 'edit, update, create, delete, list, show',
214
-                    'UserPreferences' => 'save',
215
-                    'Clipboard' => 'save, flush, show',
216
-                ),
217
-                $moduleConfiguration
218
-            );
219
-        }
220
-    }
221
-
222
-    /**
223
-     * Return the module code for a BE module.
224
-     *
225
-     * @return string
226
-     */
227
-    public function getSignature()
228
-    {
229
-        return GeneralUtility::_GP(Parameter::MODULE);
230
-    }
231
-
232
-    /**
233
-     * Tell whether the current module is the list one.
234
-     *
235
-     * @return bool
236
-     */
237
-    public function copeWithPageTree()
238
-    {
239
-        return GeneralUtility::_GP(Parameter::MODULE) === 'web_VidiM1';
240
-    }
241
-
242
-    /**
243
-     * Returns the current pid.
244
-     *
245
-     * @return bool
246
-     */
247
-    public function getCurrentPid()
248
-    {
249
-        return GeneralUtility::_GET(Parameter::PID) > 0 ? (int)GeneralUtility::_GET(Parameter::PID) : 0;
250
-    }
251
-
252
-    /**
253
-     * Return the Vidi module code which is stored in TBE_MODULES_EXT
254
-     *
255
-     * @return string
256
-     */
257
-    public function getVidiModuleCode()
258
-    {
259
-
260
-        if ($this->copeWithPageTree()) {
261
-            $userPreferenceKey = sprintf('Vidi_pid_%s', $this->getCurrentPid());
262
-
263
-            if (GeneralUtility::_GP(Parameter::SUBMODULE)) {
264
-                $subModuleCode = GeneralUtility::_GP(Parameter::SUBMODULE);
265
-                BackendUserPreferenceService::getInstance()->set($userPreferenceKey, $subModuleCode);
266
-            } else {
267
-
268
-                $defaultModuleCode = BackendUserPreferenceService::getInstance()->get($userPreferenceKey);
269
-                if (empty($defaultModuleCode)) {
270
-                    $defaultModuleCode = 'VidiTtContentM1'; // hard-coded submodule
271
-                    BackendUserPreferenceService::getInstance()->set($userPreferenceKey, $defaultModuleCode);
272
-                }
273
-
274
-                $vidiModules = ModuleService::getInstance()->getModulesForCurrentPid();
275
-
276
-                if (empty($vidiModules)) {
277
-                    $subModuleCode = $defaultModuleCode;
278
-                } elseif (isset($vidiModules[$defaultModuleCode])) {
279
-                    $subModuleCode = $defaultModuleCode;
280
-                } else {
281
-                    $subModuleCode = ModuleService::getInstance()->getFirstModuleForPid($this->getCurrentPid());
282
-                }
283
-            }
284
-        } else {
285
-            $moduleCode = $this->getSignature();
286
-
287
-            // Remove first part which is separated "_"
288
-            $delimiter = strpos($moduleCode, '_') + 1;
289
-            $subModuleCode = substr($moduleCode, $delimiter);
290
-        }
291
-
292
-        return $subModuleCode;
293
-    }
294
-
295
-    /**
296
-     * Return the module URL.
297
-     *
298
-     * @param array $additionalParameters
299
-     * @param bool $absoluteUrl
300
-     * @return string
301
-     */
302
-    public function getModuleUrl(array $additionalParameters = array(), $absoluteUrl = false)
303
-    {
304
-        $moduleCode = $this->getSignature();
305
-
306
-        // Add possible submodule if current module has page tree.
307
-        if ($this->copeWithPageTree() && !isset($additionalParameters[Parameter::SUBMODULE])) {
308
-            $additionalParameters[Parameter::SUBMODULE] = $this->getVidiModuleCode();
309
-        }
310
-
311
-        // And don't forget the pid!
312
-        if (GeneralUtility::_GET(Parameter::PID)) {
313
-            $additionalParameters[Parameter::PID] = GeneralUtility::_GET(Parameter::PID);
314
-        }
315
-
316
-        $moduleUrl = BackendUtility::getModuleUrl($moduleCode, $additionalParameters, false, $absoluteUrl);
317
-        return $moduleUrl;
318
-    }
319
-
320
-    /**
321
-     * Return the module absolute URL.
322
-     *
323
-     * @param array $additionalParameters
324
-     * @return string
325
-     */
326
-    public function getModuleAbsoluteUrl(array $additionalParameters = array())
327
-    {
328
-        return $this->getModuleUrl($additionalParameters, true);
329
-    }
330
-
331
-    /**
332
-     * Return the parameter prefix for a BE module.
333
-     *
334
-     * @return string
335
-     */
336
-    public function getParameterPrefix()
337
-    {
338
-        return 'tx_vidi_' . strtolower($this->getSignature());
339
-    }
340
-
341
-    /**
342
-     * Return a configuration key or the entire module configuration array if not key is given.
343
-     *
344
-     * @param string $key
345
-     * @throws InvalidKeyInArrayException
346
-     * @return mixed
347
-     */
348
-    public function getModuleConfiguration($key = '')
349
-    {
350
-
351
-        $vidiModuleCode = $this->getVidiModuleCode();
352
-
353
-        // Module code must exist
354
-        if (empty($GLOBALS['TBE_MODULES_EXT']['vidi'][$vidiModuleCode])) {
355
-            $message = sprintf('Invalid or not existing module code "%s"', $vidiModuleCode);
356
-            throw new InvalidKeyInArrayException($message, 1375092053);
357
-        }
358
-
359
-        $result = $GLOBALS['TBE_MODULES_EXT']['vidi'][$vidiModuleCode];
360
-
361
-        if (!empty($key)) {
362
-            if (isset($result[$key])) {
363
-                $result = $result[$key];
364
-            } else {
365
-                // key must exist
366
-                $message = sprintf('Invalid key configuration "%s"', $key);
367
-                throw new InvalidKeyInArrayException($message, 1375092054);
368
-            }
369
-        }
370
-        return $result;
371
-    }
372
-
373
-    /**
374
-     * @param string $icon
375
-     * @return $this
376
-     */
377
-    public function setIcon($icon)
378
-    {
379
-        $this->icon = $icon;
380
-        return $this;
381
-    }
382
-
383
-    /**
384
-     * @return string
385
-     */
386
-    public function getIcon()
387
-    {
388
-        return $this->icon;
389
-    }
390
-
391
-    /**
392
-     * @param string $mainModule
393
-     * @return $this
394
-     */
395
-    public function setMainModule($mainModule)
396
-    {
397
-        $this->mainModule = $mainModule;
398
-        return $this;
399
-    }
400
-
401
-    /**
402
-     * @return string
403
-     */
404
-    public function getMainModule()
405
-    {
406
-        if (is_null($this->mainModule)) {
407
-            $this->mainModule = $this->getModuleConfiguration('mainModule');
408
-        }
409
-        return $this->mainModule;
410
-    }
411
-
412
-    /**
413
-     * @param string $moduleLanguageFile
414
-     * @return $this
415
-     */
416
-    public function setModuleLanguageFile($moduleLanguageFile)
417
-    {
418
-        $this->moduleLanguageFile = $moduleLanguageFile;
419
-        return $this;
420
-    }
421
-
422
-    /**
423
-     * @return string
424
-     */
425
-    public function getModuleLanguageFile()
426
-    {
427
-        return $this->moduleLanguageFile;
428
-    }
429
-
430
-    /**
431
-     * @param string $position
432
-     * @return $this
433
-     */
434
-    public function setPosition($position)
435
-    {
436
-        $this->position = $position;
437
-        return $this;
438
-    }
439
-
440
-    /**
441
-     * @return string
442
-     */
443
-    public function getPosition()
444
-    {
445
-        return $this->position;
446
-    }
447
-
448
-    /**
449
-     * @param array $files
450
-     * @return $this
451
-     */
452
-    public function addJavaScriptFiles(array $files)
453
-    {
454
-        foreach ($files as $file) {
455
-            $this->additionalJavaScriptFiles[] = $file;
456
-        }
457
-        return $this;
458
-    }
459
-
460
-    /**
461
-     * @param string $fileNameAndPath
462
-     * @return $this
463
-     */
464
-    public function addJavaScriptFile($fileNameAndPath)
465
-    {
466
-        $this->additionalJavaScriptFiles[] = $fileNameAndPath;
467
-        return $this;
468
-    }
469
-
470
-    /**
471
-     * @param array $files
472
-     * @return $this
473
-     */
474
-    public function addStyleSheetFiles(array $files)
475
-    {
476
-        foreach ($files as $file) {
477
-            $this->additionalStyleSheetFiles[] = $file;
478
-        }
479
-        return $this;
480
-    }
481
-
482
-    /**
483
-     * @param string $fileNameAndPath
484
-     * @return $this
485
-     */
486
-    public function addStyleSheetFile($fileNameAndPath)
487
-    {
488
-        $this->additionalStyleSheetFiles[] = $fileNameAndPath;
489
-        return $this;
490
-    }
491
-
492
-    /**
493
-     * @return string
494
-     */
495
-    public function getDataType()
496
-    {
497
-        if (is_null($this->dataType)) {
498
-            $this->dataType = $this->getModuleConfiguration('dataType');
499
-        }
500
-        return $this->dataType;
501
-    }
502
-
503
-    /**
504
-     * @return array
505
-     */
506
-    public function getDataTypes()
507
-    {
508
-        $dataTypes = array();
509
-        foreach ($GLOBALS['TBE_MODULES_EXT']['vidi'] as $module) {
510
-            $dataTypes[] = $module['dataType'];
511
-        }
512
-        return $dataTypes;
513
-    }
514
-
515
-    /**
516
-     * @param string $dataType
517
-     * @return $this
518
-     */
519
-    public function setDataType($dataType)
520
-    {
521
-        $this->dataType = $dataType;
522
-        return $this;
523
-    }
524
-
525
-    /**
526
-     * @return string
527
-     */
528
-    public function getDefaultPid()
529
-    {
530
-        if (empty($this->defaultPid)) {
531
-            $this->defaultPid = $this->getModuleConfiguration('defaultPid');
532
-        }
533
-        return $this->defaultPid;
534
-    }
535
-
536
-    /**
537
-     * @param string $defaultPid
538
-     * @return $this
539
-     */
540
-    public function setDefaultPid($defaultPid)
541
-    {
542
-        $this->defaultPid = $defaultPid;
543
-        return $this;
544
-    }
545
-
546
-    /**
547
-     * @param bool $isPageTreeShown
548
-     * @return $this
549
-     */
550
-    public function showPageTree($isPageTreeShown)
551
-    {
552
-        $this->showPageTree = $isPageTreeShown;
553
-        return $this;
554
-    }
555
-
556
-    /**
557
-     * @param string $isShown
558
-     * @return $this
559
-     */
560
-    public function isShown($isShown)
561
-    {
562
-        $this->isShown = $isShown;
563
-        return $this;
564
-    }
565
-
566
-    /**
567
-     * @return $array
568
-     */
569
-    public function getDocHeaderTopLeftComponents()
570
-    {
571
-        $configuration = $this->getModuleConfiguration();
572
-        return $configuration['components'][ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::LEFT];
573
-    }
574
-
575
-    /**
576
-     * @param array $components
577
-     * @return $this
578
-     */
579
-    public function setDocHeaderTopLeftComponents(array $components)
580
-    {
581
-        $this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::LEFT] = $components;
582
-        return $this;
583
-    }
584
-
585
-    /**
586
-     * @param string|array $components
587
-     * @return $this
588
-     */
589
-    public function addDocHeaderTopLeftComponents($components)
590
-    {
591
-        if (is_string($components)) {
592
-            $components = array($components);
593
-        }
594
-        $currentComponents = $this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::LEFT];
595
-        $this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::LEFT] = array_merge($currentComponents, $components);
596
-        return $this;
597
-    }
598
-
599
-    /**
600
-     * @return $array
601
-     */
602
-    public function getDocHeaderTopRightComponents()
603
-    {
604
-        $configuration = $this->getModuleConfiguration();
605
-        return $configuration['components'][ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::RIGHT];
606
-    }
607
-
608
-    /**
609
-     * @param array $components
610
-     * @return $this
611
-     */
612
-    public function setDocHeaderTopRightComponents(array $components)
613
-    {
614
-        $this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::RIGHT] = $components;
615
-        return $this;
616
-    }
617
-
618
-    /**
619
-     * @param string|array $components
620
-     * @return $this
621
-     */
622
-    public function addDocHeaderTopRightComponents($components)
623
-    {
624
-        if (is_string($components)) {
625
-            $components = array($components);
626
-        }
627
-        $currentComponents = $this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::RIGHT];
628
-        $this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::RIGHT] = array_merge($currentComponents, $components);
629
-        return $this;
630
-    }
631
-
632
-    /**
633
-     * @return $array
634
-     */
635
-    public function getDocHeaderBottomLeftComponents()
636
-    {
637
-        $configuration = $this->getModuleConfiguration();
638
-        return $configuration['components'][ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::LEFT];
639
-    }
640
-
641
-    /**
642
-     * @param array $components
643
-     * @return $this
644
-     */
645
-    public function setDocHeaderBottomLeftComponents(array $components)
646
-    {
647
-        $this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::LEFT] = $components;
648
-        return $this;
649
-    }
650
-
651
-    /**
652
-     * @param string|array $components
653
-     * @return $this
654
-     */
655
-    public function addDocHeaderBottomLeftComponents($components)
656
-    {
657
-        if (is_string($components)) {
658
-            $components = array($components);
659
-        }
660
-        $currentComponents = $this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::LEFT];
661
-        $this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::LEFT] = array_merge($currentComponents, $components);
662
-        return $this;
663
-    }
664
-
665
-    /**
666
-     * @return $array
667
-     */
668
-    public function getDocHeaderBottomRightComponents()
669
-    {
670
-        $configuration = $this->getModuleConfiguration();
671
-        return $configuration['components'][ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::RIGHT];
672
-    }
673
-
674
-    /**
675
-     * @param array $components
676
-     * @return $this
677
-     */
678
-    public function setDocHeaderBottomRightComponents(array $components)
679
-    {
680
-        $this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::RIGHT] = $components;
681
-        return $this;
682
-    }
683
-
684
-    /**
685
-     * @param string|array $components
686
-     * @return $this
687
-     */
688
-    public function addDocHeaderBottomRightComponents($components)
689
-    {
690
-        if (is_string($components)) {
691
-            $components = array($components);
692
-        }
693
-        $currentComponents = $this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::RIGHT];
694
-        $this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::RIGHT] = array_merge($currentComponents, $components);
695
-        return $this;
696
-    }
697
-
698
-    /**
699
-     * @return $array
700
-     */
701
-    public function getGridTopComponents()
702
-    {
703
-        $configuration = $this->getModuleConfiguration();
704
-        return $configuration['components'][ModulePosition::GRID][ModulePosition::TOP];
705
-    }
706
-
707
-    /**
708
-     * @param array $components
709
-     * @return $this
710
-     */
711
-    public function setGridTopComponents(array $components)
712
-    {
713
-        $this->components[ModulePosition::GRID][ModulePosition::TOP] = $components;
714
-        return $this;
715
-    }
716
-
717
-    /**
718
-     * @param string|array $components
719
-     * @return $this
720
-     */
721
-    public function addGridTopComponents($components)
722
-    {
723
-        if (is_string($components)) {
724
-            $components = array($components);
725
-        }
726
-        $currentComponents = $this->components[ModulePosition::GRID][ModulePosition::TOP];
727
-        $this->components[ModulePosition::GRID][ModulePosition::TOP] = array_merge($currentComponents, $components);
728
-        return $this;
729
-    }
730
-
731
-    /**
732
-     * @return $array
733
-     */
734
-    public function getGridBottomComponents()
735
-    {
736
-        $configuration = $this->getModuleConfiguration();
737
-        return $configuration['components'][ModulePosition::GRID][ModulePosition::BOTTOM];
738
-    }
739
-
740
-    /**
741
-     * @param array $components
742
-     * @return $this
743
-     */
744
-    public function setGridBottomComponents(array $components)
745
-    {
746
-        $this->components[ModulePosition::GRID][ModulePosition::BOTTOM] = $components;
747
-        return $this;
748
-    }
749
-
750
-    /**
751
-     * @param string|array $components
752
-     * @return $this
753
-     */
754
-    public function addGridBottomComponents($components)
755
-    {
756
-        if (is_string($components)) {
757
-            $components = array($components);
758
-        }
759
-        $currentComponents = $this->components[ModulePosition::GRID][ModulePosition::BOTTOM];
760
-        $this->components[ModulePosition::GRID][ModulePosition::BOTTOM] = array_merge($currentComponents, $components);
761
-        return $this;
762
-    }
763
-
764
-    /**
765
-     * @return $array
766
-     */
767
-    public function getGridButtonsComponents()
768
-    {
769
-        $configuration = $this->getModuleConfiguration();
770
-        return $configuration['components'][ModulePosition::GRID][ModulePosition::BUTTONS];
771
-    }
772
-
773
-    /**
774
-     * @param array $components
775
-     * @return $this
776
-     */
777
-    public function setGridButtonsComponents(array $components)
778
-    {
779
-        $this->components[ModulePosition::GRID][ModulePosition::BUTTONS] = $components;
780
-        return $this;
781
-    }
782
-
783
-    /**
784
-     * @param string|array $components
785
-     * @return $this
786
-     */
787
-    public function addGridButtonsComponents($components)
788
-    {
789
-        if (is_string($components)) {
790
-            $components = array($components);
791
-        }
792
-        $currentComponents = $this->components[ModulePosition::GRID][ModulePosition::BUTTONS];
793
-        $this->components[ModulePosition::GRID][ModulePosition::BUTTONS] = array_merge($currentComponents, $components);
794
-        return $this;
795
-    }
796
-
797
-    /**
798
-     * @return $array
799
-     */
800
-    public function getMenuMassActionComponents()
801
-    {
802
-        $configuration = $this->getModuleConfiguration();
803
-        return $configuration['components'][ModulePosition::MENU_MASS_ACTION];
804
-    }
805
-
806
-    /**
807
-     * @param array $components
808
-     * @return $this
809
-     */
810
-    public function setMenuMassActionComponents(array $components)
811
-    {
812
-        $this->components[ModulePosition::MENU_MASS_ACTION] = $components;
813
-        return $this;
814
-    }
815
-
816
-    /**
817
-     * @param string|array $components
818
-     * @return $this
819
-     */
820
-    public function addMenuMassActionComponents($components)
821
-    {
822
-        if (is_string($components)) {
823
-            $components = array($components);
824
-        }
825
-        $currentComponents = $this->components[ModulePosition::MENU_MASS_ACTION];
826
-        $this->components[ModulePosition::MENU_MASS_ACTION] = array_merge($currentComponents, $components);
827
-        return $this;
828
-    }
829
-
830
-    /**
831
-     * @return string
832
-     */
833
-    public function getAccess()
834
-    {
835
-        return $this->access;
836
-    }
837
-
838
-    /**
839
-     * @param string $access
840
-     * @return $this
841
-     */
842
-    public function setAccess($access)
843
-    {
844
-        $this->access = $access;
845
-        return $this;
846
-    }
847
-
848
-    /**
849
-     * @return \string[]
850
-     */
851
-    public function getAdditionalJavaScriptFiles()
852
-    {
853
-        if (empty($this->additionalJavaScriptFiles)) {
854
-            $this->additionalJavaScriptFiles = $this->getModuleConfiguration('additionalJavaScriptFiles');
855
-        }
856
-        return $this->additionalJavaScriptFiles;
857
-    }
858
-
859
-    /**
860
-     * @return \string[]
861
-     */
862
-    public function getAdditionalStyleSheetFiles()
863
-    {
864
-        if (empty($this->additionalStyleSheetFiles)) {
865
-            $this->additionalStyleSheetFiles = $this->getModuleConfiguration('additionalStyleSheetFiles');
866
-        }
867
-        return $this->additionalStyleSheetFiles;
868
-    }
869
-
870
-    /**
871
-     * @return array
872
-     */
873
-    public function getComponents()
874
-    {
875
-        return $this->components;
876
-    }
877
-
878
-    /**
879
-     * @param string $pluginName
880
-     * @return bool
881
-     */
882
-    public function hasPlugin($pluginName = '')
883
-    {
884
-        $parameterPrefix = $this->getParameterPrefix();
885
-        $parameters = GeneralUtility::_GET($parameterPrefix);
886
-
887
-        $hasPlugin = !empty($parameters['plugins']) && is_array($parameters['plugins']);
888
-        if ($hasPlugin && $pluginName) {
889
-            $hasPlugin = in_array($pluginName, $parameters['plugins']);
890
-        }
891
-        return $hasPlugin;
892
-    }
893
-
894
-    /**
895
-     * Compute the internal module code
896
-     *
897
-     * @param NULL|string $dataType
898
-     * @return string
899
-     */
900
-    protected function getInternalModuleSignature($dataType = NULL)
901
-    {
902
-        if (is_null($dataType)) {
903
-            $dataType = $this->dataType;
904
-        }
905
-        $subModuleName = $dataType . '_' . $this->moduleKey;
906
-        return 'Vidi' . GeneralUtility::underscoredToUpperCamelCase($subModuleName);
907
-    }
908
-
909
-    /**
910
-     * Make sure default values are correctly initialized for the module.
911
-     *
912
-     * @return void
913
-     */
914
-    protected function initializeDefaultValues()
915
-    {
916
-        if (is_null($this->mainModule)) {
917
-            $this->mainModule = self::DEFAULT_MAIN_MODULE;
918
-        }
919
-
920
-        if (is_null($this->defaultPid)) {
921
-            $this->defaultPid = self::DEFAULT_PID;
922
-        }
923
-    }
29
+	/**
30
+	 * Define the default main module
31
+	 */
32
+	const DEFAULT_MAIN_MODULE = 'content';
33
+
34
+	/**
35
+	 * Define the default pid
36
+	 */
37
+	const DEFAULT_PID = 0;
38
+
39
+	/**
40
+	 * The type of data being listed (which corresponds to a table name in TCA)
41
+	 *
42
+	 * @var string
43
+	 */
44
+	protected $dataType;
45
+
46
+	/**
47
+	 * @var string
48
+	 */
49
+	protected $defaultPid;
50
+
51
+	/**
52
+	 * @var bool
53
+	 */
54
+	protected $showPageTree;
55
+
56
+	/**
57
+	 * @var bool
58
+	 */
59
+	protected $isShown = TRUE;
60
+
61
+	/**
62
+	 * @var string
63
+	 */
64
+	protected $access = Access::USER;
65
+
66
+	/**
67
+	 * @var string
68
+	 */
69
+	protected $mainModule;
70
+
71
+	/**
72
+	 * @var string
73
+	 */
74
+	protected $position = '';
75
+
76
+	/**
77
+	 * @var string
78
+	 */
79
+	protected $icon = '';
80
+
81
+	/**
82
+	 * @var string
83
+	 */
84
+	protected $moduleLanguageFile = 'LLL:EXT:vidi/Resources/Private/Language/locallang_module.xlf';
85
+
86
+	/**
87
+	 * The module key such as m1, m2.
88
+	 *
89
+	 * @var string
90
+	 */
91
+	protected $moduleKey = 'm1';
92
+
93
+	/**
94
+	 * @var string[]
95
+	 */
96
+	protected $additionalJavaScriptFiles = array();
97
+
98
+	/**
99
+	 * @var string[]
100
+	 */
101
+	protected $additionalStyleSheetFiles = array();
102
+
103
+	/**
104
+	 * @var array
105
+	 */
106
+	protected $components = array(
107
+		ModulePosition::DOC_HEADER => array(
108
+			ModulePosition::TOP => array(
109
+				ModulePosition::LEFT => array(),
110
+				ModulePosition::RIGHT => array(
111
+					'Fab\Vidi\View\Button\ToolButton',
112
+				),
113
+			),
114
+			ModulePosition::BOTTOM => array(
115
+				ModulePosition::LEFT => array(
116
+					'Fab\Vidi\View\Button\NewButton',
117
+					'Fab\Vidi\ViewHelpers\Link\BackViewHelper',
118
+				),
119
+				ModulePosition::RIGHT => array(),
120
+			),
121
+		),
122
+		ModulePosition::GRID => array(
123
+			ModulePosition::TOP => array(
124
+				'Fab\Vidi\View\Check\PidCheck',
125
+				'Fab\Vidi\View\Check\RelationsCheck',
126
+				'Fab\Vidi\View\Tab\DataTypeTab',
127
+			),
128
+			ModulePosition::BUTTONS => array(
129
+				'Fab\Vidi\View\Button\EditButton',
130
+				'Fab\Vidi\View\Button\DeleteButton',
131
+			),
132
+			ModulePosition::BOTTOM => array(),
133
+		),
134
+		ModulePosition::MENU_MASS_ACTION => array(
135
+			'Fab\Vidi\View\MenuItem\ExportXlsMenuItem',
136
+			'Fab\Vidi\View\MenuItem\ExportXmlMenuItem',
137
+			'Fab\Vidi\View\MenuItem\ExportCsvMenuItem',
138
+			'Fab\Vidi\View\MenuItem\DividerMenuItem',
139
+			'Fab\Vidi\View\MenuItem\MassDeleteMenuItem',
140
+			#'Fab\Vidi\View\MenuItem\MassEditMenuItem',
141
+		),
142
+	);
143
+
144
+	/**
145
+	 * @param string $dataType
146
+	 */
147
+	public function __construct($dataType = null)
148
+	{
149
+		$this->dataType = $dataType;
150
+	}
151
+
152
+	/**
153
+	 * Tell whether a module is already registered.
154
+	 *
155
+	 * @param string $dataType
156
+	 * @return bool
157
+	 */
158
+	public function isRegistered($dataType)
159
+	{
160
+		$internalModuleSignature = $this->getInternalModuleSignature($dataType);
161
+		return !empty($GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]);
162
+	}
163
+
164
+	/**
165
+	 * Register the module
166
+	 *
167
+	 * @return void
168
+	 */
169
+	public function register()
170
+	{
171
+
172
+		$this->initializeDefaultValues();
173
+		$internalModuleSignature = $this->getInternalModuleSignature();
174
+
175
+		$GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature] = array();
176
+		$GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['dataType'] = $this->dataType;
177
+		$GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['mainModule'] = $this->mainModule;
178
+		$GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['defaultPid'] = $this->defaultPid;
179
+		$GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['additionalJavaScriptFiles'] = $this->additionalJavaScriptFiles;
180
+		$GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['additionalStyleSheetFiles'] = $this->additionalStyleSheetFiles;
181
+		$GLOBALS['TBE_MODULES_EXT']['vidi'][$internalModuleSignature]['components'] = $this->components;
182
+
183
+		// Register and displays module in the BE only if told, default is TRUE.
184
+		if ($this->isShown) {
185
+			$moduleConfiguration = array(
186
+				#'routeTarget' => \Fab\Vidi\Controller\ContentController::class . '::mainAction', // what to do here?
187
+				'access' => $this->access,
188
+				'labels' => $this->moduleLanguageFile,
189
+				'inheritNavigationComponentFromMainModule' => TRUE
190
+			);
191
+
192
+			if (!empty($this->icon)) {
193
+				$moduleConfiguration['icon'] = $this->icon;
194
+			}
195
+
196
+			if (!is_null($this->showPageTree)) {
197
+				if ($this->showPageTree) {
198
+					$moduleConfiguration['navigationComponentId'] = 'typo3-pagetree';
199
+				} else {
200
+					$moduleConfiguration['inheritNavigationComponentFromMainModule'] = FALSE;
201
+				}
202
+			}
203
+
204
+			ExtensionUtility::registerModule(
205
+				'Fab.vidi',
206
+				$this->mainModule,
207
+				$this->dataType . '_' . $this->moduleKey,
208
+				$this->position,
209
+				array(
210
+					'Content' => 'index, list, delete, update, edit, copy, move, localize, sort, copyClipboard, moveClipboard',
211
+					'Tool' => 'welcome, work',
212
+					'Facet' => 'autoSuggest, autoSuggests',
213
+					'Selection' => 'edit, update, create, delete, list, show',
214
+					'UserPreferences' => 'save',
215
+					'Clipboard' => 'save, flush, show',
216
+				),
217
+				$moduleConfiguration
218
+			);
219
+		}
220
+	}
221
+
222
+	/**
223
+	 * Return the module code for a BE module.
224
+	 *
225
+	 * @return string
226
+	 */
227
+	public function getSignature()
228
+	{
229
+		return GeneralUtility::_GP(Parameter::MODULE);
230
+	}
231
+
232
+	/**
233
+	 * Tell whether the current module is the list one.
234
+	 *
235
+	 * @return bool
236
+	 */
237
+	public function copeWithPageTree()
238
+	{
239
+		return GeneralUtility::_GP(Parameter::MODULE) === 'web_VidiM1';
240
+	}
241
+
242
+	/**
243
+	 * Returns the current pid.
244
+	 *
245
+	 * @return bool
246
+	 */
247
+	public function getCurrentPid()
248
+	{
249
+		return GeneralUtility::_GET(Parameter::PID) > 0 ? (int)GeneralUtility::_GET(Parameter::PID) : 0;
250
+	}
251
+
252
+	/**
253
+	 * Return the Vidi module code which is stored in TBE_MODULES_EXT
254
+	 *
255
+	 * @return string
256
+	 */
257
+	public function getVidiModuleCode()
258
+	{
259
+
260
+		if ($this->copeWithPageTree()) {
261
+			$userPreferenceKey = sprintf('Vidi_pid_%s', $this->getCurrentPid());
262
+
263
+			if (GeneralUtility::_GP(Parameter::SUBMODULE)) {
264
+				$subModuleCode = GeneralUtility::_GP(Parameter::SUBMODULE);
265
+				BackendUserPreferenceService::getInstance()->set($userPreferenceKey, $subModuleCode);
266
+			} else {
267
+
268
+				$defaultModuleCode = BackendUserPreferenceService::getInstance()->get($userPreferenceKey);
269
+				if (empty($defaultModuleCode)) {
270
+					$defaultModuleCode = 'VidiTtContentM1'; // hard-coded submodule
271
+					BackendUserPreferenceService::getInstance()->set($userPreferenceKey, $defaultModuleCode);
272
+				}
273
+
274
+				$vidiModules = ModuleService::getInstance()->getModulesForCurrentPid();
275
+
276
+				if (empty($vidiModules)) {
277
+					$subModuleCode = $defaultModuleCode;
278
+				} elseif (isset($vidiModules[$defaultModuleCode])) {
279
+					$subModuleCode = $defaultModuleCode;
280
+				} else {
281
+					$subModuleCode = ModuleService::getInstance()->getFirstModuleForPid($this->getCurrentPid());
282
+				}
283
+			}
284
+		} else {
285
+			$moduleCode = $this->getSignature();
286
+
287
+			// Remove first part which is separated "_"
288
+			$delimiter = strpos($moduleCode, '_') + 1;
289
+			$subModuleCode = substr($moduleCode, $delimiter);
290
+		}
291
+
292
+		return $subModuleCode;
293
+	}
294
+
295
+	/**
296
+	 * Return the module URL.
297
+	 *
298
+	 * @param array $additionalParameters
299
+	 * @param bool $absoluteUrl
300
+	 * @return string
301
+	 */
302
+	public function getModuleUrl(array $additionalParameters = array(), $absoluteUrl = false)
303
+	{
304
+		$moduleCode = $this->getSignature();
305
+
306
+		// Add possible submodule if current module has page tree.
307
+		if ($this->copeWithPageTree() && !isset($additionalParameters[Parameter::SUBMODULE])) {
308
+			$additionalParameters[Parameter::SUBMODULE] = $this->getVidiModuleCode();
309
+		}
310
+
311
+		// And don't forget the pid!
312
+		if (GeneralUtility::_GET(Parameter::PID)) {
313
+			$additionalParameters[Parameter::PID] = GeneralUtility::_GET(Parameter::PID);
314
+		}
315
+
316
+		$moduleUrl = BackendUtility::getModuleUrl($moduleCode, $additionalParameters, false, $absoluteUrl);
317
+		return $moduleUrl;
318
+	}
319
+
320
+	/**
321
+	 * Return the module absolute URL.
322
+	 *
323
+	 * @param array $additionalParameters
324
+	 * @return string
325
+	 */
326
+	public function getModuleAbsoluteUrl(array $additionalParameters = array())
327
+	{
328
+		return $this->getModuleUrl($additionalParameters, true);
329
+	}
330
+
331
+	/**
332
+	 * Return the parameter prefix for a BE module.
333
+	 *
334
+	 * @return string
335
+	 */
336
+	public function getParameterPrefix()
337
+	{
338
+		return 'tx_vidi_' . strtolower($this->getSignature());
339
+	}
340
+
341
+	/**
342
+	 * Return a configuration key or the entire module configuration array if not key is given.
343
+	 *
344
+	 * @param string $key
345
+	 * @throws InvalidKeyInArrayException
346
+	 * @return mixed
347
+	 */
348
+	public function getModuleConfiguration($key = '')
349
+	{
350
+
351
+		$vidiModuleCode = $this->getVidiModuleCode();
352
+
353
+		// Module code must exist
354
+		if (empty($GLOBALS['TBE_MODULES_EXT']['vidi'][$vidiModuleCode])) {
355
+			$message = sprintf('Invalid or not existing module code "%s"', $vidiModuleCode);
356
+			throw new InvalidKeyInArrayException($message, 1375092053);
357
+		}
358
+
359
+		$result = $GLOBALS['TBE_MODULES_EXT']['vidi'][$vidiModuleCode];
360
+
361
+		if (!empty($key)) {
362
+			if (isset($result[$key])) {
363
+				$result = $result[$key];
364
+			} else {
365
+				// key must exist
366
+				$message = sprintf('Invalid key configuration "%s"', $key);
367
+				throw new InvalidKeyInArrayException($message, 1375092054);
368
+			}
369
+		}
370
+		return $result;
371
+	}
372
+
373
+	/**
374
+	 * @param string $icon
375
+	 * @return $this
376
+	 */
377
+	public function setIcon($icon)
378
+	{
379
+		$this->icon = $icon;
380
+		return $this;
381
+	}
382
+
383
+	/**
384
+	 * @return string
385
+	 */
386
+	public function getIcon()
387
+	{
388
+		return $this->icon;
389
+	}
390
+
391
+	/**
392
+	 * @param string $mainModule
393
+	 * @return $this
394
+	 */
395
+	public function setMainModule($mainModule)
396
+	{
397
+		$this->mainModule = $mainModule;
398
+		return $this;
399
+	}
400
+
401
+	/**
402
+	 * @return string
403
+	 */
404
+	public function getMainModule()
405
+	{
406
+		if (is_null($this->mainModule)) {
407
+			$this->mainModule = $this->getModuleConfiguration('mainModule');
408
+		}
409
+		return $this->mainModule;
410
+	}
411
+
412
+	/**
413
+	 * @param string $moduleLanguageFile
414
+	 * @return $this
415
+	 */
416
+	public function setModuleLanguageFile($moduleLanguageFile)
417
+	{
418
+		$this->moduleLanguageFile = $moduleLanguageFile;
419
+		return $this;
420
+	}
421
+
422
+	/**
423
+	 * @return string
424
+	 */
425
+	public function getModuleLanguageFile()
426
+	{
427
+		return $this->moduleLanguageFile;
428
+	}
429
+
430
+	/**
431
+	 * @param string $position
432
+	 * @return $this
433
+	 */
434
+	public function setPosition($position)
435
+	{
436
+		$this->position = $position;
437
+		return $this;
438
+	}
439
+
440
+	/**
441
+	 * @return string
442
+	 */
443
+	public function getPosition()
444
+	{
445
+		return $this->position;
446
+	}
447
+
448
+	/**
449
+	 * @param array $files
450
+	 * @return $this
451
+	 */
452
+	public function addJavaScriptFiles(array $files)
453
+	{
454
+		foreach ($files as $file) {
455
+			$this->additionalJavaScriptFiles[] = $file;
456
+		}
457
+		return $this;
458
+	}
459
+
460
+	/**
461
+	 * @param string $fileNameAndPath
462
+	 * @return $this
463
+	 */
464
+	public function addJavaScriptFile($fileNameAndPath)
465
+	{
466
+		$this->additionalJavaScriptFiles[] = $fileNameAndPath;
467
+		return $this;
468
+	}
469
+
470
+	/**
471
+	 * @param array $files
472
+	 * @return $this
473
+	 */
474
+	public function addStyleSheetFiles(array $files)
475
+	{
476
+		foreach ($files as $file) {
477
+			$this->additionalStyleSheetFiles[] = $file;
478
+		}
479
+		return $this;
480
+	}
481
+
482
+	/**
483
+	 * @param string $fileNameAndPath
484
+	 * @return $this
485
+	 */
486
+	public function addStyleSheetFile($fileNameAndPath)
487
+	{
488
+		$this->additionalStyleSheetFiles[] = $fileNameAndPath;
489
+		return $this;
490
+	}
491
+
492
+	/**
493
+	 * @return string
494
+	 */
495
+	public function getDataType()
496
+	{
497
+		if (is_null($this->dataType)) {
498
+			$this->dataType = $this->getModuleConfiguration('dataType');
499
+		}
500
+		return $this->dataType;
501
+	}
502
+
503
+	/**
504
+	 * @return array
505
+	 */
506
+	public function getDataTypes()
507
+	{
508
+		$dataTypes = array();
509
+		foreach ($GLOBALS['TBE_MODULES_EXT']['vidi'] as $module) {
510
+			$dataTypes[] = $module['dataType'];
511
+		}
512
+		return $dataTypes;
513
+	}
514
+
515
+	/**
516
+	 * @param string $dataType
517
+	 * @return $this
518
+	 */
519
+	public function setDataType($dataType)
520
+	{
521
+		$this->dataType = $dataType;
522
+		return $this;
523
+	}
524
+
525
+	/**
526
+	 * @return string
527
+	 */
528
+	public function getDefaultPid()
529
+	{
530
+		if (empty($this->defaultPid)) {
531
+			$this->defaultPid = $this->getModuleConfiguration('defaultPid');
532
+		}
533
+		return $this->defaultPid;
534
+	}
535
+
536
+	/**
537
+	 * @param string $defaultPid
538
+	 * @return $this
539
+	 */
540
+	public function setDefaultPid($defaultPid)
541
+	{
542
+		$this->defaultPid = $defaultPid;
543
+		return $this;
544
+	}
545
+
546
+	/**
547
+	 * @param bool $isPageTreeShown
548
+	 * @return $this
549
+	 */
550
+	public function showPageTree($isPageTreeShown)
551
+	{
552
+		$this->showPageTree = $isPageTreeShown;
553
+		return $this;
554
+	}
555
+
556
+	/**
557
+	 * @param string $isShown
558
+	 * @return $this
559
+	 */
560
+	public function isShown($isShown)
561
+	{
562
+		$this->isShown = $isShown;
563
+		return $this;
564
+	}
565
+
566
+	/**
567
+	 * @return $array
568
+	 */
569
+	public function getDocHeaderTopLeftComponents()
570
+	{
571
+		$configuration = $this->getModuleConfiguration();
572
+		return $configuration['components'][ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::LEFT];
573
+	}
574
+
575
+	/**
576
+	 * @param array $components
577
+	 * @return $this
578
+	 */
579
+	public function setDocHeaderTopLeftComponents(array $components)
580
+	{
581
+		$this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::LEFT] = $components;
582
+		return $this;
583
+	}
584
+
585
+	/**
586
+	 * @param string|array $components
587
+	 * @return $this
588
+	 */
589
+	public function addDocHeaderTopLeftComponents($components)
590
+	{
591
+		if (is_string($components)) {
592
+			$components = array($components);
593
+		}
594
+		$currentComponents = $this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::LEFT];
595
+		$this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::LEFT] = array_merge($currentComponents, $components);
596
+		return $this;
597
+	}
598
+
599
+	/**
600
+	 * @return $array
601
+	 */
602
+	public function getDocHeaderTopRightComponents()
603
+	{
604
+		$configuration = $this->getModuleConfiguration();
605
+		return $configuration['components'][ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::RIGHT];
606
+	}
607
+
608
+	/**
609
+	 * @param array $components
610
+	 * @return $this
611
+	 */
612
+	public function setDocHeaderTopRightComponents(array $components)
613
+	{
614
+		$this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::RIGHT] = $components;
615
+		return $this;
616
+	}
617
+
618
+	/**
619
+	 * @param string|array $components
620
+	 * @return $this
621
+	 */
622
+	public function addDocHeaderTopRightComponents($components)
623
+	{
624
+		if (is_string($components)) {
625
+			$components = array($components);
626
+		}
627
+		$currentComponents = $this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::RIGHT];
628
+		$this->components[ModulePosition::DOC_HEADER][ModulePosition::TOP][ModulePosition::RIGHT] = array_merge($currentComponents, $components);
629
+		return $this;
630
+	}
631
+
632
+	/**
633
+	 * @return $array
634
+	 */
635
+	public function getDocHeaderBottomLeftComponents()
636
+	{
637
+		$configuration = $this->getModuleConfiguration();
638
+		return $configuration['components'][ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::LEFT];
639
+	}
640
+
641
+	/**
642
+	 * @param array $components
643
+	 * @return $this
644
+	 */
645
+	public function setDocHeaderBottomLeftComponents(array $components)
646
+	{
647
+		$this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::LEFT] = $components;
648
+		return $this;
649
+	}
650
+
651
+	/**
652
+	 * @param string|array $components
653
+	 * @return $this
654
+	 */
655
+	public function addDocHeaderBottomLeftComponents($components)
656
+	{
657
+		if (is_string($components)) {
658
+			$components = array($components);
659
+		}
660
+		$currentComponents = $this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::LEFT];
661
+		$this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::LEFT] = array_merge($currentComponents, $components);
662
+		return $this;
663
+	}
664
+
665
+	/**
666
+	 * @return $array
667
+	 */
668
+	public function getDocHeaderBottomRightComponents()
669
+	{
670
+		$configuration = $this->getModuleConfiguration();
671
+		return $configuration['components'][ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::RIGHT];
672
+	}
673
+
674
+	/**
675
+	 * @param array $components
676
+	 * @return $this
677
+	 */
678
+	public function setDocHeaderBottomRightComponents(array $components)
679
+	{
680
+		$this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::RIGHT] = $components;
681
+		return $this;
682
+	}
683
+
684
+	/**
685
+	 * @param string|array $components
686
+	 * @return $this
687
+	 */
688
+	public function addDocHeaderBottomRightComponents($components)
689
+	{
690
+		if (is_string($components)) {
691
+			$components = array($components);
692
+		}
693
+		$currentComponents = $this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::RIGHT];
694
+		$this->components[ModulePosition::DOC_HEADER][ModulePosition::BOTTOM][ModulePosition::RIGHT] = array_merge($currentComponents, $components);
695
+		return $this;
696
+	}
697
+
698
+	/**
699
+	 * @return $array
700
+	 */
701
+	public function getGridTopComponents()
702
+	{
703
+		$configuration = $this->getModuleConfiguration();
704
+		return $configuration['components'][ModulePosition::GRID][ModulePosition::TOP];
705
+	}
706
+
707
+	/**
708
+	 * @param array $components
709
+	 * @return $this
710
+	 */
711
+	public function setGridTopComponents(array $components)
712
+	{
713
+		$this->components[ModulePosition::GRID][ModulePosition::TOP] = $components;
714
+		return $this;
715
+	}
716
+
717
+	/**
718
+	 * @param string|array $components
719
+	 * @return $this
720
+	 */
721
+	public function addGridTopComponents($components)
722
+	{
723
+		if (is_string($components)) {
724
+			$components = array($components);
725
+		}
726
+		$currentComponents = $this->components[ModulePosition::GRID][ModulePosition::TOP];
727
+		$this->components[ModulePosition::GRID][ModulePosition::TOP] = array_merge($currentComponents, $components);
728
+		return $this;
729
+	}
730
+
731
+	/**
732
+	 * @return $array
733
+	 */
734
+	public function getGridBottomComponents()
735
+	{
736
+		$configuration = $this->getModuleConfiguration();
737
+		return $configuration['components'][ModulePosition::GRID][ModulePosition::BOTTOM];
738
+	}
739
+
740
+	/**
741
+	 * @param array $components
742
+	 * @return $this
743
+	 */
744
+	public function setGridBottomComponents(array $components)
745
+	{
746
+		$this->components[ModulePosition::GRID][ModulePosition::BOTTOM] = $components;
747
+		return $this;
748
+	}
749
+
750
+	/**
751
+	 * @param string|array $components
752
+	 * @return $this
753
+	 */
754
+	public function addGridBottomComponents($components)
755
+	{
756
+		if (is_string($components)) {
757
+			$components = array($components);
758
+		}
759
+		$currentComponents = $this->components[ModulePosition::GRID][ModulePosition::BOTTOM];
760
+		$this->components[ModulePosition::GRID][ModulePosition::BOTTOM] = array_merge($currentComponents, $components);
761
+		return $this;
762
+	}
763
+
764
+	/**
765
+	 * @return $array
766
+	 */
767
+	public function getGridButtonsComponents()
768
+	{
769
+		$configuration = $this->getModuleConfiguration();
770
+		return $configuration['components'][ModulePosition::GRID][ModulePosition::BUTTONS];
771
+	}
772
+
773
+	/**
774
+	 * @param array $components
775
+	 * @return $this
776
+	 */
777
+	public function setGridButtonsComponents(array $components)
778
+	{
779
+		$this->components[ModulePosition::GRID][ModulePosition::BUTTONS] = $components;
780
+		return $this;
781
+	}
782
+
783
+	/**
784
+	 * @param string|array $components
785
+	 * @return $this
786
+	 */
787
+	public function addGridButtonsComponents($components)
788
+	{
789
+		if (is_string($components)) {
790
+			$components = array($components);
791
+		}
792
+		$currentComponents = $this->components[ModulePosition::GRID][ModulePosition::BUTTONS];
793
+		$this->components[ModulePosition::GRID][ModulePosition::BUTTONS] = array_merge($currentComponents, $components);
794
+		return $this;
795
+	}
796
+
797
+	/**
798
+	 * @return $array
799
+	 */
800
+	public function getMenuMassActionComponents()
801
+	{
802
+		$configuration = $this->getModuleConfiguration();
803
+		return $configuration['components'][ModulePosition::MENU_MASS_ACTION];
804
+	}
805
+
806
+	/**
807
+	 * @param array $components
808
+	 * @return $this
809
+	 */
810
+	public function setMenuMassActionComponents(array $components)
811
+	{
812
+		$this->components[ModulePosition::MENU_MASS_ACTION] = $components;
813
+		return $this;
814
+	}
815
+
816
+	/**
817
+	 * @param string|array $components
818
+	 * @return $this
819
+	 */
820
+	public function addMenuMassActionComponents($components)
821
+	{
822
+		if (is_string($components)) {
823
+			$components = array($components);
824
+		}
825
+		$currentComponents = $this->components[ModulePosition::MENU_MASS_ACTION];
826
+		$this->components[ModulePosition::MENU_MASS_ACTION] = array_merge($currentComponents, $components);
827
+		return $this;
828
+	}
829
+
830
+	/**
831
+	 * @return string
832
+	 */
833
+	public function getAccess()
834
+	{
835
+		return $this->access;
836
+	}
837
+
838
+	/**
839
+	 * @param string $access
840
+	 * @return $this
841
+	 */
842
+	public function setAccess($access)
843
+	{
844
+		$this->access = $access;
845
+		return $this;
846
+	}
847
+
848
+	/**
849
+	 * @return \string[]
850
+	 */
851
+	public function getAdditionalJavaScriptFiles()
852
+	{
853
+		if (empty($this->additionalJavaScriptFiles)) {
854
+			$this->additionalJavaScriptFiles = $this->getModuleConfiguration('additionalJavaScriptFiles');
855
+		}
856
+		return $this->additionalJavaScriptFiles;
857
+	}
858
+
859
+	/**
860
+	 * @return \string[]
861
+	 */
862
+	public function getAdditionalStyleSheetFiles()
863
+	{
864
+		if (empty($this->additionalStyleSheetFiles)) {
865
+			$this->additionalStyleSheetFiles = $this->getModuleConfiguration('additionalStyleSheetFiles');
866
+		}
867
+		return $this->additionalStyleSheetFiles;
868
+	}
869
+
870
+	/**
871
+	 * @return array
872
+	 */
873
+	public function getComponents()
874
+	{
875
+		return $this->components;
876
+	}
877
+
878
+	/**
879
+	 * @param string $pluginName
880
+	 * @return bool
881
+	 */
882
+	public function hasPlugin($pluginName = '')
883
+	{
884
+		$parameterPrefix = $this->getParameterPrefix();
885
+		$parameters = GeneralUtility::_GET($parameterPrefix);
886
+
887
+		$hasPlugin = !empty($parameters['plugins']) && is_array($parameters['plugins']);
888
+		if ($hasPlugin && $pluginName) {
889
+			$hasPlugin = in_array($pluginName, $parameters['plugins']);
890
+		}
891
+		return $hasPlugin;
892
+	}
893
+
894
+	/**
895
+	 * Compute the internal module code
896
+	 *
897
+	 * @param NULL|string $dataType
898
+	 * @return string
899
+	 */
900
+	protected function getInternalModuleSignature($dataType = NULL)
901
+	{
902
+		if (is_null($dataType)) {
903
+			$dataType = $this->dataType;
904
+		}
905
+		$subModuleName = $dataType . '_' . $this->moduleKey;
906
+		return 'Vidi' . GeneralUtility::underscoredToUpperCamelCase($subModuleName);
907
+	}
908
+
909
+	/**
910
+	 * Make sure default values are correctly initialized for the module.
911
+	 *
912
+	 * @return void
913
+	 */
914
+	protected function initializeDefaultValues()
915
+	{
916
+		if (is_null($this->mainModule)) {
917
+			$this->mainModule = self::DEFAULT_MAIN_MODULE;
918
+		}
919
+
920
+		if (is_null($this->defaultPid)) {
921
+			$this->defaultPid = self::DEFAULT_PID;
922
+		}
923
+	}
924 924
 
925 925
 }
Please login to merge, or discard this patch.
Classes/Controller/ContentController.php 1 patch
Indentation   +759 added lines, -759 removed lines patch added patch discarded remove patch
@@ -38,764 +38,764 @@
 block discarded – undo
38 38
 class ContentController extends ActionController
39 39
 {
40 40
 
41
-    /**
42
-     * @var \Fab\Vidi\Domain\Repository\SelectionRepository
43
-     * @inject
44
-     */
45
-    protected $selectionRepository;
46
-
47
-    /**
48
-     * Initialize every action.
49
-     */
50
-    public function initializeAction()
51
-    {
52
-        $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
53
-        $pageRenderer->addInlineLanguageLabelFile('EXT:vidi/Resources/Private/Language/locallang.xlf');
54
-
55
-        // Configure property mapping to retrieve the file object.
56
-        if ($this->arguments->hasArgument('columns')) {
57
-
58
-            /** @var \Fab\Vidi\TypeConverter\CsvToArrayConverter $typeConverter */
59
-            $typeConverter = $this->objectManager->get('Fab\Vidi\TypeConverter\CsvToArrayConverter');
60
-
61
-            $propertyMappingConfiguration = $this->arguments->getArgument('columns')->getPropertyMappingConfiguration();
62
-            $propertyMappingConfiguration->setTypeConverter($typeConverter);
63
-        }
64
-    }
65
-
66
-    /**
67
-     * List action for this controller.
68
-     *
69
-     * @return void
70
-     */
71
-    public function indexAction()
72
-    {
73
-        $dataType = $this->getModuleLoader()->getDataType();
74
-        $selections = $this->selectionRepository->findByDataTypeForCurrentBackendUser($dataType);
75
-        $this->view->assign('selections', $selections);
76
-
77
-        $columns = Tca::grid()->getFields();
78
-        $this->view->assign('columns', $columns);
79
-        $this->view->assign('numberOfColumns', count($columns));
80
-    }
81
-
82
-    /**
83
-     * List Row action for this controller. Output a json list of contents
84
-     *
85
-     * @param array $columns corresponds to columns to be rendered.
86
-     * @param array $matches
87
-     * @validate $columns Fab\Vidi\Domain\Validator\ColumnsValidator
88
-     * @validate $matches Fab\Vidi\Domain\Validator\MatchesValidator
89
-     * @return void
90
-     */
91
-    public function listAction(array $columns = [], $matches = [])
92
-    {
93
-        // Initialize some objects related to the query.
94
-        $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
95
-        $order = OrderObjectFactory::getInstance()->getOrder();
96
-        $pager = PagerObjectFactory::getInstance()->getPager();
97
-
98
-        // Fetch objects via the Content Service.
99
-        $contentService = $this->getContentService()->findBy($matcher, $order, $pager->getLimit(), $pager->getOffset());
100
-        $pager->setCount($contentService->getNumberOfObjects());
101
-
102
-        // Assign values.
103
-        $this->view->assign('columns', $columns);
104
-        $this->view->assign('objects', $contentService->getObjects());
105
-        $this->view->assign('numberOfObjects', $contentService->getNumberOfObjects());
106
-        $this->view->assign('pager', $pager);
107
-        $this->view->assign('response', $this->response);
108
-    }
109
-
110
-    /**
111
-     * Retrieve Content objects first according to matching criteria and then "update" them.
112
-     * Important to notice the field name can contains a path, e.g. metadata.title and therefore must be analysed.
113
-     *
114
-     * Possible values for $matches:
115
-     * -----------------------------
116
-     *
117
-     * $matches = array(uid => 1), will be taken as $query->equals
118
-     * $matches = array(uid => 1,2,3), will be taken as $query->in
119
-     * $matches = array(field_name1 => bar, field_name2 => bax), will be separated by AND.
120
-     *
121
-     * Possible values for $content:
122
-     * -----------------------------
123
-     *
124
-     * $content = array(field_name => bar)
125
-     * $content = array(field_name => array(value1, value2)) <-- will be CSV converted by "value1,value2"
126
-     *
127
-     * @param string $fieldNameAndPath
128
-     * @param array $content
129
-     * @param array $matches
130
-     * @param string $savingBehavior
131
-     * @param int $language
132
-     * @param array $columns
133
-     * @return string
134
-     * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
135
-     */
136
-    public function updateAction($fieldNameAndPath, array $content, array $matches = [], $savingBehavior = SavingBehavior::REPLACE, $language = 0, $columns = [])
137
-    {
138
-
139
-        // Instantiate the Matcher object according different rules.
140
-        $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
141
-        $order = OrderObjectFactory::getInstance()->getOrder();
142
-
143
-        // Fetch objects via the Content Service.
144
-        $contentService = $this->getContentService()->findBy($matcher, $order);
145
-
146
-        // Get the real field that is going to be updated.
147
-        $updatedFieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
148
-
149
-        // Get result object for storing data along the processing.
150
-        $result = $this->getJsonResult();
151
-        $result->setNumberOfObjects($contentService->getNumberOfObjects());
152
-
153
-        foreach ($contentService->getObjects() as $index => $object) {
154
-
155
-            $identifier = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, 'uid', $language);
156
-
157
-            // It could be the identifier is not found because the translation
158
-            // of the record does not yet exist when mass-editing
159
-            if ((int)$identifier <= 0) {
160
-                continue;
161
-            }
162
-
163
-            $dataType = $this->getContentObjectResolver()->getDataType($object, $fieldNameAndPath);
164
-
165
-            $signalResult = $this->emitProcessContentDataSignal($object, $fieldNameAndPath, $content, $index + 1, $savingBehavior, $language);
166
-            $contentData = $signalResult->getContentData();
167
-
168
-            // Add identifier to content data, required by TCEMain.
169
-            $contentData['uid'] = $identifier;
170
-
171
-            /** @var Content $dataObject */
172
-            $dataObject = GeneralUtility::makeInstance('Fab\Vidi\Domain\Model\Content', $dataType, $contentData);
173
-
174
-            // Properly update object.
175
-            ContentRepositoryFactory::getInstance($dataType)->update($dataObject);
176
-
177
-            // Get the possible error messages and store them.
178
-            $errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
179
-            $result->addErrorMessages($errorMessages);
180
-
181
-            // We only want to see the detail result if there is one object updated.
182
-            // Required for inline editing + it will display some useful info on the GUI in the flash messages.
183
-            if ($contentService->getNumberOfObjects() === 1) {
184
-
185
-                // Fetch the updated object from repository.
186
-                $updatedObject = ContentRepositoryFactory::getInstance()->findByUid($object->getUid());
187
-
188
-                // Re-fetch the updated result.
189
-                $updatedResult = $this->getContentObjectResolver()->getValue($updatedObject, $fieldNameAndPath, $updatedFieldName, $language);
190
-                if (is_array($updatedResult)) {
191
-                    $_updatedResult = []; // reset result set.
192
-
193
-                    /** @var Content $contentObject */
194
-                    foreach ($updatedResult as $contentObject) {
195
-                        $labelField = Tca::table($contentObject)->getLabelField();
196
-                        $values = array(
197
-                            'uid' => $contentObject->getUid(),
198
-                            'name' => $contentObject[$labelField],
199
-                        );
200
-                        $_updatedResult[] = $values;
201
-                    }
202
-
203
-                    $updatedResult = $_updatedResult;
204
-                }
205
-
206
-                $labelField = Tca::table($object)->getLabelField();
207
-
208
-                $processedObjectData = array(
209
-                    'uid' => $object->getUid(),
210
-                    'name' => $object[$labelField],
211
-                    'updatedField' => $fieldNameAndPath,
212
-                    'updatedValue' => $updatedResult,
213
-                );
214
-                $result->setProcessedObject($processedObjectData);
215
-
216
-                if (!empty($columns)) {
217
-                    /** @var Row $row */
218
-                    $row = GeneralUtility::makeInstance('Fab\Vidi\View\Grid\Row', $columns);
219
-                    $result->setRow($row->render($updatedObject));
220
-                }
221
-            }
222
-        }
223
-
224
-        // Set the result and render the JSON view.
225
-        $this->getJsonView()->setResult($result);
226
-        return $this->getJsonView()->render();
227
-    }
228
-
229
-    /**
230
-     * Set the sorting of a record giving the previous object.
231
-     *
232
-     * @param array $matches
233
-     * @param int $previousIdentifier
234
-     * @return string
235
-     */
236
-    public function sortAction(array $matches = [], $previousIdentifier = NULL)
237
-    {
238
-
239
-        $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
240
-
241
-        // Fetch objects via the Content Service.
242
-        $contentService = $this->getContentService()->findBy($matcher);
243
-
244
-        // Compute the label field name of the table.
245
-        $tableTitleField = Tca::table()->getLabelField();
246
-
247
-        // Get result object for storing data along the processing.
248
-        $result = $this->getJsonResult();
249
-        $result->setNumberOfObjects($contentService->getNumberOfObjects());
250
-
251
-        foreach ($contentService->getObjects() as $object) {
252
-
253
-            // Store the first object, so that the "action" message can be more explicit when deleting only one record.
254
-            if ($contentService->getNumberOfObjects() === 1) {
255
-                $tableTitleValue = $object[$tableTitleField];
256
-                $processedObjectData = array(
257
-                    'uid' => $object->getUid(),
258
-                    'name' => $tableTitleValue,
259
-                );
260
-                $result->setProcessedObject($processedObjectData);
261
-            }
262
-
263
-            // The $target corresponds to the pid to move the records to.
264
-            // It can also be a negative value in case of sorting. The negative value would be the uid of its predecessor.
265
-            $target = is_null($previousIdentifier) ? $object->getPid() : (-(int)$previousIdentifier);
266
-
267
-            // Work out the object.
268
-            ContentRepositoryFactory::getInstance()->move($object, $target);
269
-
270
-            // Get the possible error messages and store them.
271
-            $errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
272
-            $result->addErrorMessages($errorMessages);
273
-        }
274
-
275
-        // Set the result and render the JSON view.
276
-        $this->getJsonView()->setResult($result);
277
-        return $this->getJsonView()->render();
278
-    }
279
-
280
-    /**
281
-     * Returns an editing form for a given field name of a Content object.
282
-     * Argument $fieldNameAndPath corresponds to the field name to be edited.
283
-     * Important to notice it can contains a path, e.g. metadata.title and therefore must be analysed.
284
-     *
285
-     * Possible values for $matches, refer to method "updateAction".
286
-     *
287
-     * @param string $fieldNameAndPath
288
-     * @param array $matches
289
-     * @param bool $hasRecursiveSelection
290
-     * @throws \Exception
291
-     */
292
-    public function editAction($fieldNameAndPath, array $matches = [], $hasRecursiveSelection = FALSE)
293
-    {
294
-
295
-        // Instantiate the Matcher object according different rules.
296
-        $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
297
-
298
-        // Fetch objects via the Content Service.
299
-        $contentService = $this->getContentService()->findBy($matcher);
300
-
301
-        $dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath);
302
-        $fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
303
-
304
-        $fieldType = Tca::table($dataType)->field($fieldName)->getType();
305
-        $this->view->assign('fieldType', ucfirst($fieldType));
306
-        $this->view->assign('dataType', $dataType);
307
-        $this->view->assign('fieldName', $fieldName);
308
-        $this->view->assign('matches', $matches);
309
-        $this->view->assign('fieldNameAndPath', $fieldNameAndPath);
310
-        $this->view->assign('numberOfObjects', $contentService->getNumberOfObjects());
311
-        $this->view->assign('hasRecursiveSelection', $hasRecursiveSelection);
312
-        $this->view->assign('editWholeSelection', empty($matches['uid'])); // necessary??
313
-
314
-        // Fetch content and its relations.
315
-        if ($fieldType === FieldType::MULTISELECT) {
316
-
317
-            $object = ContentRepositoryFactory::getInstance()->findOneBy($matcher);
318
-            $identifier = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, 'uid');
319
-            $dataType = $this->getContentObjectResolver()->getDataType($object, $fieldNameAndPath);
320
-
321
-            $content = ContentRepositoryFactory::getInstance($dataType)->findByUid($identifier);
322
-
323
-            // Makes sure the object was retrieved. Security!
324
-            if (!$content) {
325
-                $message = sprintf('I could not retrieved content object of type "%s" with identifier %s.', $dataType, $identifier);
326
-                throw new \Exception($message, 1402350182);
327
-            }
328
-
329
-            $relatedDataType = Tca::table($dataType)->field($fieldName)->getForeignTable();
330
-
331
-            // Initialize the matcher object.
332
-            /** @var \Fab\Vidi\Persistence\Matcher $matcher */
333
-            $matcher = GeneralUtility::makeInstance('Fab\Vidi\Persistence\Matcher', [], $relatedDataType);
334
-
335
-            // Default ordering for related data type.
336
-            $defaultOrderings = Tca::table($relatedDataType)->getDefaultOrderings();
337
-            /** @var \Fab\Vidi\Persistence\Order $order */
338
-            $defaultOrder = GeneralUtility::makeInstance('Fab\Vidi\Persistence\Order', $defaultOrderings);
339
-
340
-            // Fetch related contents
341
-            $relatedContents = ContentRepositoryFactory::getInstance($relatedDataType)->findBy($matcher, $defaultOrder);
342
-
343
-            if (Tca::table($dataType)->field($fieldName)->isRenderModeTree()) {
344
-
345
-                $fieldConfiguration = Tca::table($dataType)->field($fieldName)->getConfiguration();
346
-                $parentField = $fieldConfiguration['treeConfig']['parentField'];
347
-
348
-                $flatTree = [];
349
-                foreach ($relatedContents as $node) {
350
-                    $flatTree[$node->getUid()] = array(
351
-                        'item' => $node,
352
-                        'parent' => $node[$parentField] ? $node[$parentField]['uid'] : NULL,
353
-                    );
354
-                }
355
-
356
-                $tree = [];
357
-
358
-                // If leaves are selected without its parents selected, those are shown as parent
359
-                foreach ($flatTree as $id => &$flatNode) {
360
-                    if (!isset($flatTree[$flatNode['parent']])) {
361
-                        $flatNode['parent'] = NULL;
362
-                    }
363
-                }
364
-
365
-                foreach ($flatTree as $id => &$node) {
366
-                    if ($node['parent'] === NULL) {
367
-                        $tree[$id] = &$node;
368
-                    } else {
369
-                        $flatTree[$node['parent']]['children'][$id] = &$node;
370
-                    }
371
-                }
372
-
373
-                $relatedContents = $tree;
374
-            }
375
-
376
-            $this->view->assign('content', $content);
377
-            $this->view->assign('relatedContents', $relatedContents);
378
-            $this->view->assign('relatedDataType', $relatedDataType);
379
-            $this->view->assign('relatedContentTitle', Tca::table($relatedDataType)->getTitle());
380
-            $this->view->assign(
381
-                'renderMode',
382
-                Tca::table($dataType)->field($fieldName)->isRenderModeTree() ? FieldType::TREE : NULL
383
-            );
384
-        }
385
-    }
386
-
387
-    /**
388
-     * Retrieve Content objects first according to matching criteria and then "delete" them.
389
-     *
390
-     * Possible values for $matches, refer to method "updateAction".
391
-     *
392
-     * @param array $matches
393
-     * @return string
394
-     */
395
-    public function deleteAction(array $matches = [])
396
-    {
397
-
398
-        $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
399
-
400
-        // Fetch objects via the Content Service.
401
-        $contentService = $this->getContentService()->findBy($matcher);
402
-
403
-        // Compute the label field name of the table.
404
-        $tableTitleField = Tca::table()->getLabelField();
405
-
406
-        // Get result object for storing data along the processing.
407
-        $result = $this->getJsonResult();
408
-        $result->setNumberOfObjects($contentService->getNumberOfObjects());
409
-
410
-        foreach ($contentService->getObjects() as $object) {
411
-
412
-            // Store the first object, so that the delete message can be more explicit when deleting only one record.
413
-            if ($contentService->getNumberOfObjects() === 1) {
414
-                $tableTitleValue = $object[$tableTitleField];
415
-                $processedObjectData = array(
416
-                    'uid' => $object->getUid(),
417
-                    'name' => $tableTitleValue,
418
-                );
419
-                $result->setProcessedObject($processedObjectData);
420
-            }
421
-
422
-            // Properly delete object.
423
-            ContentRepositoryFactory::getInstance()->remove($object);
424
-
425
-            // Get the possible error messages and store them.
426
-            $errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
427
-            $result->addErrorMessages($errorMessages);
428
-        }
429
-
430
-        // Set the result and render the JSON view.
431
-        $this->getJsonView()->setResult($result);
432
-        return $this->getJsonView()->render();
433
-    }
434
-
435
-    /**
436
-     * Retrieve Content objects first according to matching criteria and then "copy" them.
437
-     *
438
-     * Possible values for $matches, refer to method "updateAction".
439
-     *
440
-     * @param string $target
441
-     * @param array $matches
442
-     * @throws \Exception
443
-     * @return string
444
-     */
445
-    public function copyAction($target, array $matches = [])
446
-    {
447
-        // @todo
448
-        throw new \Exception('Not yet implemented', 1410192546);
449
-    }
450
-
451
-    /**
452
-     * Retrieve Content objects from the Clipboard then "copy" them according to the target.
453
-     *
454
-     * @param string $target
455
-     * @throws \Exception
456
-     * @return string
457
-     */
458
-    public function copyClipboardAction($target)
459
-    {
460
-
461
-        // Retrieve matcher object from clipboard.
462
-        $matcher = $this->getClipboardService()->getMatcher();
463
-
464
-        // Fetch objects via the Content Service.
465
-        $contentService = $this->getContentService()->findBy($matcher);
466
-
467
-        // Compute the label field name of the table.
468
-        $tableTitleField = Tca::table()->getLabelField();
469
-
470
-        // Get result object for storing data along the processing.
471
-        $result = $this->getJsonResult();
472
-        $result->setNumberOfObjects($contentService->getNumberOfObjects());
473
-
474
-        foreach ($contentService->getObjects() as $object) {
475
-
476
-            // Store the first object, so that the "action" message can be more explicit when deleting only one record.
477
-            if ($contentService->getNumberOfObjects() === 1) {
478
-                $tableTitleValue = $object[$tableTitleField];
479
-                $processedObjectData = array(
480
-                    'uid' => $object->getUid(),
481
-                    'name' => $tableTitleValue,
482
-                );
483
-                $result->setProcessedObject($processedObjectData);
484
-            }
485
-
486
-            // Work out the object.
487
-            ContentRepositoryFactory::getInstance()->copy($object, $target);
488
-
489
-            // Get the possible error messages and store them.
490
-            $errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
491
-            $result->addErrorMessages($errorMessages);
492
-        }
493
-
494
-        // Flush Clipboard if told so.
495
-        if (GeneralUtility::_GP('flushClipboard')) {
496
-            $this->getClipboardService()->flush();
497
-        }
498
-
499
-        // Set the result and render the JSON view.
500
-        $this->getJsonView()->setResult($result);
501
-        return $this->getJsonView()->render();
502
-    }
503
-
504
-    /**
505
-     * Retrieve Content objects first according to matching criteria and then "move" them.
506
-     *
507
-     * Possible values for $matches, refer to method "updateAction".
508
-     *
509
-     * @param string $target
510
-     * @param array $matches
511
-     * @return string
512
-     */
513
-    public function moveAction($target, array $matches = [])
514
-    {
515
-
516
-        $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
517
-
518
-        // Fetch objects via the Content Service.
519
-        $contentService = $this->getContentService()->findBy($matcher);
520
-
521
-        // Compute the label field name of the table.
522
-        $tableTitleField = Tca::table()->getLabelField();
523
-
524
-        // Get result object for storing data along the processing.
525
-        $result = $this->getJsonResult();
526
-        $result->setNumberOfObjects($contentService->getNumberOfObjects());
527
-
528
-        foreach ($contentService->getObjects() as $object) {
529
-
530
-            // Store the first object, so that the "action" message can be more explicit when deleting only one record.
531
-            if ($contentService->getNumberOfObjects() === 1) {
532
-                $tableTitleValue = $object[$tableTitleField];
533
-                $processedObjectData = array(
534
-                    'uid' => $object->getUid(),
535
-                    'name' => $tableTitleValue,
536
-                );
537
-                $result->setProcessedObject($processedObjectData);
538
-            }
539
-
540
-            // Work out the object.
541
-            ContentRepositoryFactory::getInstance()->move($object, $target);
542
-
543
-            // Get the possible error messages and store them.
544
-            $errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
545
-            $result->addErrorMessages($errorMessages);
546
-        }
547
-
548
-        // Set the result and render the JSON view.
549
-        $this->getJsonView()->setResult($result);
550
-        return $this->getJsonView()->render();
551
-    }
552
-
553
-    /**
554
-     * Retrieve Content objects from the Clipboard then "move" them according to the target.
555
-     *
556
-     * @param string $target
557
-     * @return string
558
-     */
559
-    public function moveClipboardAction($target)
560
-    {
561
-
562
-        // Retrieve matcher object from clipboard.
563
-        $matcher = $this->getClipboardService()->getMatcher();
564
-
565
-        // Fetch objects via the Content Service.
566
-        $contentService = $this->getContentService()->findBy($matcher);
567
-
568
-        // Compute the label field name of the table.
569
-        $tableTitleField = Tca::table()->getLabelField();
570
-
571
-        // Get result object for storing data along the processing.
572
-        $result = $this->getJsonResult();
573
-        $result->setNumberOfObjects($contentService->getNumberOfObjects());
574
-
575
-        foreach ($contentService->getObjects() as $object) {
576
-
577
-            // Store the first object, so that the "action" message can be more explicit when deleting only one record.
578
-            if ($contentService->getNumberOfObjects() === 1) {
579
-                $tableTitleValue = $object[$tableTitleField];
580
-                $processedObjectData = array(
581
-                    'uid' => $object->getUid(),
582
-                    'name' => $tableTitleValue,
583
-                );
584
-                $result->setProcessedObject($processedObjectData);
585
-            }
586
-
587
-            // Work out the object.
588
-            ContentRepositoryFactory::getInstance()->move($object, $target);
589
-
590
-            // Get the possible error messages and store them.
591
-            $errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
592
-            $result->addErrorMessages($errorMessages);
593
-        }
594
-
595
-        // Flush Clipboard if told so.
596
-        if (GeneralUtility::_GP('flushClipboard')) {
597
-            $this->getClipboardService()->flush();
598
-        }
599
-
600
-        // Set the result and render the JSON view.
601
-        $this->getJsonView()->setResult($result);
602
-        return $this->getJsonView()->render();
603
-    }
604
-
605
-    /**
606
-     * Retrieve Content objects first according to matching criteria and then "localize" them.
607
-     *
608
-     * Possible values for $matches, refer to method "updateAction".
609
-     *
610
-     * @param string $fieldNameAndPath
611
-     * @param array $matches
612
-     * @param int $language
613
-     * @return string
614
-     * @throws \Exception
615
-     */
616
-    public function localizeAction($fieldNameAndPath, array $matches = [], $language = 0)
617
-    {
618
-
619
-        $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
620
-
621
-        // Fetch objects via the Content Service.
622
-        $contentService = $this->getContentService()->findBy($matcher);
623
-
624
-        // Get result object for storing data along the processing.
625
-        $result = $this->getJsonResult();
626
-        $result->setNumberOfObjects($contentService->getNumberOfObjects());
627
-
628
-        foreach ($contentService->getObjects() as $object) {
629
-
630
-            $identifier = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, 'uid');
631
-            $dataType = $this->getContentObjectResolver()->getDataType($object, $fieldNameAndPath);
632
-
633
-            // Fetch the source object to be localized.
634
-            /** @var Content $content */
635
-            $content = ContentRepositoryFactory::getInstance($dataType)->findByIdentifier($identifier);
636
-
637
-            // Makes sure the object was retrieved. Security!
638
-            if (!$content) {
639
-                $message = sprintf('Something went wrong when retrieving content "%s" with identifier "%s".', $dataType, $identifier);
640
-                throw new \Exception($message, 1412343097);
641
-            }
642
-
643
-            // Handover the localization to the Repository.
644
-            ContentRepositoryFactory::getInstance($dataType)->localize($content, $language);
645
-
646
-            // Get the possible error messages and store them.
647
-            $errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
648
-
649
-            // Redirect to TCEForm so that the BE User can do its job!
650
-            if ($contentService->getNumberOfObjects() === 1) {
651
-
652
-                if (!empty($errorMessages)) {
653
-                    $message = sprintf('Something went wrong when localizing content "%s" with identifier "%s". <br/>%s',
654
-                        $dataType,
655
-                        $identifier,
656
-                        implode('<br/>', $errorMessages)
657
-                    );
658
-                    throw new \Exception($message, 1412343098);
659
-                }
660
-
661
-                $localizedContent = $this->getLanguageService()->getLocalizedContent($content, $language);
662
-                if (empty($localizedContent)) {
663
-                    $message = sprintf('Oups! I could not retrieve localized content of type "%s" with identifier "%s"',
664
-                        $content->getDataType(),
665
-                        $content->getUid()
666
-                    );
667
-                    throw new \Exception($message, 1412343099);
668
-                }
669
-
670
-                /** @var \Fab\Vidi\View\Uri\EditUri $uri */
671
-                $uriRenderer = GeneralUtility::makeInstance('Fab\Vidi\View\Uri\EditUri');
672
-                $uri = $uriRenderer->render($localizedContent);
673
-                HttpUtility::redirect($uri);
674
-                break; // no need to further continue
675
-            }
676
-
677
-            $result->addErrorMessages($errorMessages);
678
-        }
679
-
680
-        // Set the result and render the JSON view.
681
-        $this->getJsonView()->setResult($result);
682
-        return $this->getJsonView()->render();
683
-    }
684
-
685
-    /**
686
-     * Get the Vidi Module Loader.
687
-     *
688
-     * @return \Fab\Vidi\Service\ContentService
689
-     */
690
-    protected function getContentService()
691
-    {
692
-        return GeneralUtility::makeInstance('Fab\Vidi\Service\ContentService');
693
-    }
694
-
695
-    /**
696
-     * @return \Fab\Vidi\Resolver\ContentObjectResolver
697
-     */
698
-    protected function getContentObjectResolver()
699
-    {
700
-        return GeneralUtility::makeInstance('Fab\Vidi\Resolver\ContentObjectResolver');
701
-    }
702
-
703
-    /**
704
-     * @return \Fab\Vidi\Resolver\FieldPathResolver
705
-     */
706
-    protected function getFieldPathResolver()
707
-    {
708
-        return GeneralUtility::makeInstance('Fab\Vidi\Resolver\FieldPathResolver');
709
-    }
710
-
711
-    /**
712
-     * Return a special view for handling JSON
713
-     * Goal is to have this view injected but require more configuration.
714
-     *
715
-     * @return JsonView
716
-     */
717
-    protected function getJsonView()
718
-    {
719
-        if (!$this->view instanceof JsonView) {
720
-            /** @var JsonView $view */
721
-            $this->view = $this->objectManager->get('Fab\Vidi\Mvc\JsonView');
722
-            $this->view->setResponse($this->response);
723
-        }
724
-        return $this->view;
725
-    }
726
-
727
-    /**
728
-     * @return JsonResult
729
-     */
730
-    protected function getJsonResult()
731
-    {
732
-        return GeneralUtility::makeInstance('Fab\Vidi\Mvc\JsonResult');
733
-    }
734
-
735
-    /**
736
-     * Signal that is called for post-processing content data send to the server for update.
737
-     *
738
-     * @param Content $contentObject
739
-     * @param $fieldNameAndPath
740
-     * @param $contentData
741
-     * @param $counter
742
-     * @param $savingBehavior
743
-     * @param $language
744
-     * @return ProcessContentDataSignalArguments
745
-     * @signal
746
-     */
747
-    protected function emitProcessContentDataSignal(Content $contentObject, $fieldNameAndPath, $contentData, $counter, $savingBehavior, $language)
748
-    {
749
-
750
-        /** @var \Fab\Vidi\Signal\ProcessContentDataSignalArguments $signalArguments */
751
-        $signalArguments = GeneralUtility::makeInstance('Fab\Vidi\Signal\ProcessContentDataSignalArguments');
752
-        $signalArguments->setContentObject($contentObject)
753
-            ->setFieldNameAndPath($fieldNameAndPath)
754
-            ->setContentData($contentData)
755
-            ->setCounter($counter)
756
-            ->setSavingBehavior($savingBehavior)
757
-            ->setLanguage($language);
758
-
759
-        $signalResult = $this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\Controller\Backend\ContentController', 'processContentData', array($signalArguments));
760
-        return $signalResult[0];
761
-    }
762
-
763
-    /**
764
-     * Get the SignalSlot dispatcher.
765
-     *
766
-     * @return \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
767
-     */
768
-    protected function getSignalSlotDispatcher()
769
-    {
770
-        return $this->objectManager->get('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
771
-    }
772
-
773
-    /**
774
-     * Get the Clipboard service.
775
-     *
776
-     * @return \Fab\Vidi\Service\ClipboardService
777
-     */
778
-    protected function getClipboardService()
779
-    {
780
-        return GeneralUtility::makeInstance('Fab\Vidi\Service\ClipboardService');
781
-    }
782
-
783
-    /**
784
-     * @return \Fab\Vidi\Language\LanguageService
785
-     */
786
-    protected function getLanguageService()
787
-    {
788
-        return GeneralUtility::makeInstance('Fab\Vidi\Language\LanguageService');
789
-    }
790
-
791
-    /**
792
-     * Get the Vidi Module Loader.
793
-     *
794
-     * @return \Fab\Vidi\Module\ModuleLoader
795
-     */
796
-    protected function getModuleLoader()
797
-    {
798
-        return GeneralUtility::makeInstance('Fab\Vidi\Module\ModuleLoader');
799
-    }
41
+	/**
42
+	 * @var \Fab\Vidi\Domain\Repository\SelectionRepository
43
+	 * @inject
44
+	 */
45
+	protected $selectionRepository;
46
+
47
+	/**
48
+	 * Initialize every action.
49
+	 */
50
+	public function initializeAction()
51
+	{
52
+		$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
53
+		$pageRenderer->addInlineLanguageLabelFile('EXT:vidi/Resources/Private/Language/locallang.xlf');
54
+
55
+		// Configure property mapping to retrieve the file object.
56
+		if ($this->arguments->hasArgument('columns')) {
57
+
58
+			/** @var \Fab\Vidi\TypeConverter\CsvToArrayConverter $typeConverter */
59
+			$typeConverter = $this->objectManager->get('Fab\Vidi\TypeConverter\CsvToArrayConverter');
60
+
61
+			$propertyMappingConfiguration = $this->arguments->getArgument('columns')->getPropertyMappingConfiguration();
62
+			$propertyMappingConfiguration->setTypeConverter($typeConverter);
63
+		}
64
+	}
65
+
66
+	/**
67
+	 * List action for this controller.
68
+	 *
69
+	 * @return void
70
+	 */
71
+	public function indexAction()
72
+	{
73
+		$dataType = $this->getModuleLoader()->getDataType();
74
+		$selections = $this->selectionRepository->findByDataTypeForCurrentBackendUser($dataType);
75
+		$this->view->assign('selections', $selections);
76
+
77
+		$columns = Tca::grid()->getFields();
78
+		$this->view->assign('columns', $columns);
79
+		$this->view->assign('numberOfColumns', count($columns));
80
+	}
81
+
82
+	/**
83
+	 * List Row action for this controller. Output a json list of contents
84
+	 *
85
+	 * @param array $columns corresponds to columns to be rendered.
86
+	 * @param array $matches
87
+	 * @validate $columns Fab\Vidi\Domain\Validator\ColumnsValidator
88
+	 * @validate $matches Fab\Vidi\Domain\Validator\MatchesValidator
89
+	 * @return void
90
+	 */
91
+	public function listAction(array $columns = [], $matches = [])
92
+	{
93
+		// Initialize some objects related to the query.
94
+		$matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
95
+		$order = OrderObjectFactory::getInstance()->getOrder();
96
+		$pager = PagerObjectFactory::getInstance()->getPager();
97
+
98
+		// Fetch objects via the Content Service.
99
+		$contentService = $this->getContentService()->findBy($matcher, $order, $pager->getLimit(), $pager->getOffset());
100
+		$pager->setCount($contentService->getNumberOfObjects());
101
+
102
+		// Assign values.
103
+		$this->view->assign('columns', $columns);
104
+		$this->view->assign('objects', $contentService->getObjects());
105
+		$this->view->assign('numberOfObjects', $contentService->getNumberOfObjects());
106
+		$this->view->assign('pager', $pager);
107
+		$this->view->assign('response', $this->response);
108
+	}
109
+
110
+	/**
111
+	 * Retrieve Content objects first according to matching criteria and then "update" them.
112
+	 * Important to notice the field name can contains a path, e.g. metadata.title and therefore must be analysed.
113
+	 *
114
+	 * Possible values for $matches:
115
+	 * -----------------------------
116
+	 *
117
+	 * $matches = array(uid => 1), will be taken as $query->equals
118
+	 * $matches = array(uid => 1,2,3), will be taken as $query->in
119
+	 * $matches = array(field_name1 => bar, field_name2 => bax), will be separated by AND.
120
+	 *
121
+	 * Possible values for $content:
122
+	 * -----------------------------
123
+	 *
124
+	 * $content = array(field_name => bar)
125
+	 * $content = array(field_name => array(value1, value2)) <-- will be CSV converted by "value1,value2"
126
+	 *
127
+	 * @param string $fieldNameAndPath
128
+	 * @param array $content
129
+	 * @param array $matches
130
+	 * @param string $savingBehavior
131
+	 * @param int $language
132
+	 * @param array $columns
133
+	 * @return string
134
+	 * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException
135
+	 */
136
+	public function updateAction($fieldNameAndPath, array $content, array $matches = [], $savingBehavior = SavingBehavior::REPLACE, $language = 0, $columns = [])
137
+	{
138
+
139
+		// Instantiate the Matcher object according different rules.
140
+		$matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
141
+		$order = OrderObjectFactory::getInstance()->getOrder();
142
+
143
+		// Fetch objects via the Content Service.
144
+		$contentService = $this->getContentService()->findBy($matcher, $order);
145
+
146
+		// Get the real field that is going to be updated.
147
+		$updatedFieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
148
+
149
+		// Get result object for storing data along the processing.
150
+		$result = $this->getJsonResult();
151
+		$result->setNumberOfObjects($contentService->getNumberOfObjects());
152
+
153
+		foreach ($contentService->getObjects() as $index => $object) {
154
+
155
+			$identifier = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, 'uid', $language);
156
+
157
+			// It could be the identifier is not found because the translation
158
+			// of the record does not yet exist when mass-editing
159
+			if ((int)$identifier <= 0) {
160
+				continue;
161
+			}
162
+
163
+			$dataType = $this->getContentObjectResolver()->getDataType($object, $fieldNameAndPath);
164
+
165
+			$signalResult = $this->emitProcessContentDataSignal($object, $fieldNameAndPath, $content, $index + 1, $savingBehavior, $language);
166
+			$contentData = $signalResult->getContentData();
167
+
168
+			// Add identifier to content data, required by TCEMain.
169
+			$contentData['uid'] = $identifier;
170
+
171
+			/** @var Content $dataObject */
172
+			$dataObject = GeneralUtility::makeInstance('Fab\Vidi\Domain\Model\Content', $dataType, $contentData);
173
+
174
+			// Properly update object.
175
+			ContentRepositoryFactory::getInstance($dataType)->update($dataObject);
176
+
177
+			// Get the possible error messages and store them.
178
+			$errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
179
+			$result->addErrorMessages($errorMessages);
180
+
181
+			// We only want to see the detail result if there is one object updated.
182
+			// Required for inline editing + it will display some useful info on the GUI in the flash messages.
183
+			if ($contentService->getNumberOfObjects() === 1) {
184
+
185
+				// Fetch the updated object from repository.
186
+				$updatedObject = ContentRepositoryFactory::getInstance()->findByUid($object->getUid());
187
+
188
+				// Re-fetch the updated result.
189
+				$updatedResult = $this->getContentObjectResolver()->getValue($updatedObject, $fieldNameAndPath, $updatedFieldName, $language);
190
+				if (is_array($updatedResult)) {
191
+					$_updatedResult = []; // reset result set.
192
+
193
+					/** @var Content $contentObject */
194
+					foreach ($updatedResult as $contentObject) {
195
+						$labelField = Tca::table($contentObject)->getLabelField();
196
+						$values = array(
197
+							'uid' => $contentObject->getUid(),
198
+							'name' => $contentObject[$labelField],
199
+						);
200
+						$_updatedResult[] = $values;
201
+					}
202
+
203
+					$updatedResult = $_updatedResult;
204
+				}
205
+
206
+				$labelField = Tca::table($object)->getLabelField();
207
+
208
+				$processedObjectData = array(
209
+					'uid' => $object->getUid(),
210
+					'name' => $object[$labelField],
211
+					'updatedField' => $fieldNameAndPath,
212
+					'updatedValue' => $updatedResult,
213
+				);
214
+				$result->setProcessedObject($processedObjectData);
215
+
216
+				if (!empty($columns)) {
217
+					/** @var Row $row */
218
+					$row = GeneralUtility::makeInstance('Fab\Vidi\View\Grid\Row', $columns);
219
+					$result->setRow($row->render($updatedObject));
220
+				}
221
+			}
222
+		}
223
+
224
+		// Set the result and render the JSON view.
225
+		$this->getJsonView()->setResult($result);
226
+		return $this->getJsonView()->render();
227
+	}
228
+
229
+	/**
230
+	 * Set the sorting of a record giving the previous object.
231
+	 *
232
+	 * @param array $matches
233
+	 * @param int $previousIdentifier
234
+	 * @return string
235
+	 */
236
+	public function sortAction(array $matches = [], $previousIdentifier = NULL)
237
+	{
238
+
239
+		$matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
240
+
241
+		// Fetch objects via the Content Service.
242
+		$contentService = $this->getContentService()->findBy($matcher);
243
+
244
+		// Compute the label field name of the table.
245
+		$tableTitleField = Tca::table()->getLabelField();
246
+
247
+		// Get result object for storing data along the processing.
248
+		$result = $this->getJsonResult();
249
+		$result->setNumberOfObjects($contentService->getNumberOfObjects());
250
+
251
+		foreach ($contentService->getObjects() as $object) {
252
+
253
+			// Store the first object, so that the "action" message can be more explicit when deleting only one record.
254
+			if ($contentService->getNumberOfObjects() === 1) {
255
+				$tableTitleValue = $object[$tableTitleField];
256
+				$processedObjectData = array(
257
+					'uid' => $object->getUid(),
258
+					'name' => $tableTitleValue,
259
+				);
260
+				$result->setProcessedObject($processedObjectData);
261
+			}
262
+
263
+			// The $target corresponds to the pid to move the records to.
264
+			// It can also be a negative value in case of sorting. The negative value would be the uid of its predecessor.
265
+			$target = is_null($previousIdentifier) ? $object->getPid() : (-(int)$previousIdentifier);
266
+
267
+			// Work out the object.
268
+			ContentRepositoryFactory::getInstance()->move($object, $target);
269
+
270
+			// Get the possible error messages and store them.
271
+			$errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
272
+			$result->addErrorMessages($errorMessages);
273
+		}
274
+
275
+		// Set the result and render the JSON view.
276
+		$this->getJsonView()->setResult($result);
277
+		return $this->getJsonView()->render();
278
+	}
279
+
280
+	/**
281
+	 * Returns an editing form for a given field name of a Content object.
282
+	 * Argument $fieldNameAndPath corresponds to the field name to be edited.
283
+	 * Important to notice it can contains a path, e.g. metadata.title and therefore must be analysed.
284
+	 *
285
+	 * Possible values for $matches, refer to method "updateAction".
286
+	 *
287
+	 * @param string $fieldNameAndPath
288
+	 * @param array $matches
289
+	 * @param bool $hasRecursiveSelection
290
+	 * @throws \Exception
291
+	 */
292
+	public function editAction($fieldNameAndPath, array $matches = [], $hasRecursiveSelection = FALSE)
293
+	{
294
+
295
+		// Instantiate the Matcher object according different rules.
296
+		$matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
297
+
298
+		// Fetch objects via the Content Service.
299
+		$contentService = $this->getContentService()->findBy($matcher);
300
+
301
+		$dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath);
302
+		$fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
303
+
304
+		$fieldType = Tca::table($dataType)->field($fieldName)->getType();
305
+		$this->view->assign('fieldType', ucfirst($fieldType));
306
+		$this->view->assign('dataType', $dataType);
307
+		$this->view->assign('fieldName', $fieldName);
308
+		$this->view->assign('matches', $matches);
309
+		$this->view->assign('fieldNameAndPath', $fieldNameAndPath);
310
+		$this->view->assign('numberOfObjects', $contentService->getNumberOfObjects());
311
+		$this->view->assign('hasRecursiveSelection', $hasRecursiveSelection);
312
+		$this->view->assign('editWholeSelection', empty($matches['uid'])); // necessary??
313
+
314
+		// Fetch content and its relations.
315
+		if ($fieldType === FieldType::MULTISELECT) {
316
+
317
+			$object = ContentRepositoryFactory::getInstance()->findOneBy($matcher);
318
+			$identifier = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, 'uid');
319
+			$dataType = $this->getContentObjectResolver()->getDataType($object, $fieldNameAndPath);
320
+
321
+			$content = ContentRepositoryFactory::getInstance($dataType)->findByUid($identifier);
322
+
323
+			// Makes sure the object was retrieved. Security!
324
+			if (!$content) {
325
+				$message = sprintf('I could not retrieved content object of type "%s" with identifier %s.', $dataType, $identifier);
326
+				throw new \Exception($message, 1402350182);
327
+			}
328
+
329
+			$relatedDataType = Tca::table($dataType)->field($fieldName)->getForeignTable();
330
+
331
+			// Initialize the matcher object.
332
+			/** @var \Fab\Vidi\Persistence\Matcher $matcher */
333
+			$matcher = GeneralUtility::makeInstance('Fab\Vidi\Persistence\Matcher', [], $relatedDataType);
334
+
335
+			// Default ordering for related data type.
336
+			$defaultOrderings = Tca::table($relatedDataType)->getDefaultOrderings();
337
+			/** @var \Fab\Vidi\Persistence\Order $order */
338
+			$defaultOrder = GeneralUtility::makeInstance('Fab\Vidi\Persistence\Order', $defaultOrderings);
339
+
340
+			// Fetch related contents
341
+			$relatedContents = ContentRepositoryFactory::getInstance($relatedDataType)->findBy($matcher, $defaultOrder);
342
+
343
+			if (Tca::table($dataType)->field($fieldName)->isRenderModeTree()) {
344
+
345
+				$fieldConfiguration = Tca::table($dataType)->field($fieldName)->getConfiguration();
346
+				$parentField = $fieldConfiguration['treeConfig']['parentField'];
347
+
348
+				$flatTree = [];
349
+				foreach ($relatedContents as $node) {
350
+					$flatTree[$node->getUid()] = array(
351
+						'item' => $node,
352
+						'parent' => $node[$parentField] ? $node[$parentField]['uid'] : NULL,
353
+					);
354
+				}
355
+
356
+				$tree = [];
357
+
358
+				// If leaves are selected without its parents selected, those are shown as parent
359
+				foreach ($flatTree as $id => &$flatNode) {
360
+					if (!isset($flatTree[$flatNode['parent']])) {
361
+						$flatNode['parent'] = NULL;
362
+					}
363
+				}
364
+
365
+				foreach ($flatTree as $id => &$node) {
366
+					if ($node['parent'] === NULL) {
367
+						$tree[$id] = &$node;
368
+					} else {
369
+						$flatTree[$node['parent']]['children'][$id] = &$node;
370
+					}
371
+				}
372
+
373
+				$relatedContents = $tree;
374
+			}
375
+
376
+			$this->view->assign('content', $content);
377
+			$this->view->assign('relatedContents', $relatedContents);
378
+			$this->view->assign('relatedDataType', $relatedDataType);
379
+			$this->view->assign('relatedContentTitle', Tca::table($relatedDataType)->getTitle());
380
+			$this->view->assign(
381
+				'renderMode',
382
+				Tca::table($dataType)->field($fieldName)->isRenderModeTree() ? FieldType::TREE : NULL
383
+			);
384
+		}
385
+	}
386
+
387
+	/**
388
+	 * Retrieve Content objects first according to matching criteria and then "delete" them.
389
+	 *
390
+	 * Possible values for $matches, refer to method "updateAction".
391
+	 *
392
+	 * @param array $matches
393
+	 * @return string
394
+	 */
395
+	public function deleteAction(array $matches = [])
396
+	{
397
+
398
+		$matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
399
+
400
+		// Fetch objects via the Content Service.
401
+		$contentService = $this->getContentService()->findBy($matcher);
402
+
403
+		// Compute the label field name of the table.
404
+		$tableTitleField = Tca::table()->getLabelField();
405
+
406
+		// Get result object for storing data along the processing.
407
+		$result = $this->getJsonResult();
408
+		$result->setNumberOfObjects($contentService->getNumberOfObjects());
409
+
410
+		foreach ($contentService->getObjects() as $object) {
411
+
412
+			// Store the first object, so that the delete message can be more explicit when deleting only one record.
413
+			if ($contentService->getNumberOfObjects() === 1) {
414
+				$tableTitleValue = $object[$tableTitleField];
415
+				$processedObjectData = array(
416
+					'uid' => $object->getUid(),
417
+					'name' => $tableTitleValue,
418
+				);
419
+				$result->setProcessedObject($processedObjectData);
420
+			}
421
+
422
+			// Properly delete object.
423
+			ContentRepositoryFactory::getInstance()->remove($object);
424
+
425
+			// Get the possible error messages and store them.
426
+			$errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
427
+			$result->addErrorMessages($errorMessages);
428
+		}
429
+
430
+		// Set the result and render the JSON view.
431
+		$this->getJsonView()->setResult($result);
432
+		return $this->getJsonView()->render();
433
+	}
434
+
435
+	/**
436
+	 * Retrieve Content objects first according to matching criteria and then "copy" them.
437
+	 *
438
+	 * Possible values for $matches, refer to method "updateAction".
439
+	 *
440
+	 * @param string $target
441
+	 * @param array $matches
442
+	 * @throws \Exception
443
+	 * @return string
444
+	 */
445
+	public function copyAction($target, array $matches = [])
446
+	{
447
+		// @todo
448
+		throw new \Exception('Not yet implemented', 1410192546);
449
+	}
450
+
451
+	/**
452
+	 * Retrieve Content objects from the Clipboard then "copy" them according to the target.
453
+	 *
454
+	 * @param string $target
455
+	 * @throws \Exception
456
+	 * @return string
457
+	 */
458
+	public function copyClipboardAction($target)
459
+	{
460
+
461
+		// Retrieve matcher object from clipboard.
462
+		$matcher = $this->getClipboardService()->getMatcher();
463
+
464
+		// Fetch objects via the Content Service.
465
+		$contentService = $this->getContentService()->findBy($matcher);
466
+
467
+		// Compute the label field name of the table.
468
+		$tableTitleField = Tca::table()->getLabelField();
469
+
470
+		// Get result object for storing data along the processing.
471
+		$result = $this->getJsonResult();
472
+		$result->setNumberOfObjects($contentService->getNumberOfObjects());
473
+
474
+		foreach ($contentService->getObjects() as $object) {
475
+
476
+			// Store the first object, so that the "action" message can be more explicit when deleting only one record.
477
+			if ($contentService->getNumberOfObjects() === 1) {
478
+				$tableTitleValue = $object[$tableTitleField];
479
+				$processedObjectData = array(
480
+					'uid' => $object->getUid(),
481
+					'name' => $tableTitleValue,
482
+				);
483
+				$result->setProcessedObject($processedObjectData);
484
+			}
485
+
486
+			// Work out the object.
487
+			ContentRepositoryFactory::getInstance()->copy($object, $target);
488
+
489
+			// Get the possible error messages and store them.
490
+			$errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
491
+			$result->addErrorMessages($errorMessages);
492
+		}
493
+
494
+		// Flush Clipboard if told so.
495
+		if (GeneralUtility::_GP('flushClipboard')) {
496
+			$this->getClipboardService()->flush();
497
+		}
498
+
499
+		// Set the result and render the JSON view.
500
+		$this->getJsonView()->setResult($result);
501
+		return $this->getJsonView()->render();
502
+	}
503
+
504
+	/**
505
+	 * Retrieve Content objects first according to matching criteria and then "move" them.
506
+	 *
507
+	 * Possible values for $matches, refer to method "updateAction".
508
+	 *
509
+	 * @param string $target
510
+	 * @param array $matches
511
+	 * @return string
512
+	 */
513
+	public function moveAction($target, array $matches = [])
514
+	{
515
+
516
+		$matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
517
+
518
+		// Fetch objects via the Content Service.
519
+		$contentService = $this->getContentService()->findBy($matcher);
520
+
521
+		// Compute the label field name of the table.
522
+		$tableTitleField = Tca::table()->getLabelField();
523
+
524
+		// Get result object for storing data along the processing.
525
+		$result = $this->getJsonResult();
526
+		$result->setNumberOfObjects($contentService->getNumberOfObjects());
527
+
528
+		foreach ($contentService->getObjects() as $object) {
529
+
530
+			// Store the first object, so that the "action" message can be more explicit when deleting only one record.
531
+			if ($contentService->getNumberOfObjects() === 1) {
532
+				$tableTitleValue = $object[$tableTitleField];
533
+				$processedObjectData = array(
534
+					'uid' => $object->getUid(),
535
+					'name' => $tableTitleValue,
536
+				);
537
+				$result->setProcessedObject($processedObjectData);
538
+			}
539
+
540
+			// Work out the object.
541
+			ContentRepositoryFactory::getInstance()->move($object, $target);
542
+
543
+			// Get the possible error messages and store them.
544
+			$errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
545
+			$result->addErrorMessages($errorMessages);
546
+		}
547
+
548
+		// Set the result and render the JSON view.
549
+		$this->getJsonView()->setResult($result);
550
+		return $this->getJsonView()->render();
551
+	}
552
+
553
+	/**
554
+	 * Retrieve Content objects from the Clipboard then "move" them according to the target.
555
+	 *
556
+	 * @param string $target
557
+	 * @return string
558
+	 */
559
+	public function moveClipboardAction($target)
560
+	{
561
+
562
+		// Retrieve matcher object from clipboard.
563
+		$matcher = $this->getClipboardService()->getMatcher();
564
+
565
+		// Fetch objects via the Content Service.
566
+		$contentService = $this->getContentService()->findBy($matcher);
567
+
568
+		// Compute the label field name of the table.
569
+		$tableTitleField = Tca::table()->getLabelField();
570
+
571
+		// Get result object for storing data along the processing.
572
+		$result = $this->getJsonResult();
573
+		$result->setNumberOfObjects($contentService->getNumberOfObjects());
574
+
575
+		foreach ($contentService->getObjects() as $object) {
576
+
577
+			// Store the first object, so that the "action" message can be more explicit when deleting only one record.
578
+			if ($contentService->getNumberOfObjects() === 1) {
579
+				$tableTitleValue = $object[$tableTitleField];
580
+				$processedObjectData = array(
581
+					'uid' => $object->getUid(),
582
+					'name' => $tableTitleValue,
583
+				);
584
+				$result->setProcessedObject($processedObjectData);
585
+			}
586
+
587
+			// Work out the object.
588
+			ContentRepositoryFactory::getInstance()->move($object, $target);
589
+
590
+			// Get the possible error messages and store them.
591
+			$errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
592
+			$result->addErrorMessages($errorMessages);
593
+		}
594
+
595
+		// Flush Clipboard if told so.
596
+		if (GeneralUtility::_GP('flushClipboard')) {
597
+			$this->getClipboardService()->flush();
598
+		}
599
+
600
+		// Set the result and render the JSON view.
601
+		$this->getJsonView()->setResult($result);
602
+		return $this->getJsonView()->render();
603
+	}
604
+
605
+	/**
606
+	 * Retrieve Content objects first according to matching criteria and then "localize" them.
607
+	 *
608
+	 * Possible values for $matches, refer to method "updateAction".
609
+	 *
610
+	 * @param string $fieldNameAndPath
611
+	 * @param array $matches
612
+	 * @param int $language
613
+	 * @return string
614
+	 * @throws \Exception
615
+	 */
616
+	public function localizeAction($fieldNameAndPath, array $matches = [], $language = 0)
617
+	{
618
+
619
+		$matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
620
+
621
+		// Fetch objects via the Content Service.
622
+		$contentService = $this->getContentService()->findBy($matcher);
623
+
624
+		// Get result object for storing data along the processing.
625
+		$result = $this->getJsonResult();
626
+		$result->setNumberOfObjects($contentService->getNumberOfObjects());
627
+
628
+		foreach ($contentService->getObjects() as $object) {
629
+
630
+			$identifier = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, 'uid');
631
+			$dataType = $this->getContentObjectResolver()->getDataType($object, $fieldNameAndPath);
632
+
633
+			// Fetch the source object to be localized.
634
+			/** @var Content $content */
635
+			$content = ContentRepositoryFactory::getInstance($dataType)->findByIdentifier($identifier);
636
+
637
+			// Makes sure the object was retrieved. Security!
638
+			if (!$content) {
639
+				$message = sprintf('Something went wrong when retrieving content "%s" with identifier "%s".', $dataType, $identifier);
640
+				throw new \Exception($message, 1412343097);
641
+			}
642
+
643
+			// Handover the localization to the Repository.
644
+			ContentRepositoryFactory::getInstance($dataType)->localize($content, $language);
645
+
646
+			// Get the possible error messages and store them.
647
+			$errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
648
+
649
+			// Redirect to TCEForm so that the BE User can do its job!
650
+			if ($contentService->getNumberOfObjects() === 1) {
651
+
652
+				if (!empty($errorMessages)) {
653
+					$message = sprintf('Something went wrong when localizing content "%s" with identifier "%s". <br/>%s',
654
+						$dataType,
655
+						$identifier,
656
+						implode('<br/>', $errorMessages)
657
+					);
658
+					throw new \Exception($message, 1412343098);
659
+				}
660
+
661
+				$localizedContent = $this->getLanguageService()->getLocalizedContent($content, $language);
662
+				if (empty($localizedContent)) {
663
+					$message = sprintf('Oups! I could not retrieve localized content of type "%s" with identifier "%s"',
664
+						$content->getDataType(),
665
+						$content->getUid()
666
+					);
667
+					throw new \Exception($message, 1412343099);
668
+				}
669
+
670
+				/** @var \Fab\Vidi\View\Uri\EditUri $uri */
671
+				$uriRenderer = GeneralUtility::makeInstance('Fab\Vidi\View\Uri\EditUri');
672
+				$uri = $uriRenderer->render($localizedContent);
673
+				HttpUtility::redirect($uri);
674
+				break; // no need to further continue
675
+			}
676
+
677
+			$result->addErrorMessages($errorMessages);
678
+		}
679
+
680
+		// Set the result and render the JSON view.
681
+		$this->getJsonView()->setResult($result);
682
+		return $this->getJsonView()->render();
683
+	}
684
+
685
+	/**
686
+	 * Get the Vidi Module Loader.
687
+	 *
688
+	 * @return \Fab\Vidi\Service\ContentService
689
+	 */
690
+	protected function getContentService()
691
+	{
692
+		return GeneralUtility::makeInstance('Fab\Vidi\Service\ContentService');
693
+	}
694
+
695
+	/**
696
+	 * @return \Fab\Vidi\Resolver\ContentObjectResolver
697
+	 */
698
+	protected function getContentObjectResolver()
699
+	{
700
+		return GeneralUtility::makeInstance('Fab\Vidi\Resolver\ContentObjectResolver');
701
+	}
702
+
703
+	/**
704
+	 * @return \Fab\Vidi\Resolver\FieldPathResolver
705
+	 */
706
+	protected function getFieldPathResolver()
707
+	{
708
+		return GeneralUtility::makeInstance('Fab\Vidi\Resolver\FieldPathResolver');
709
+	}
710
+
711
+	/**
712
+	 * Return a special view for handling JSON
713
+	 * Goal is to have this view injected but require more configuration.
714
+	 *
715
+	 * @return JsonView
716
+	 */
717
+	protected function getJsonView()
718
+	{
719
+		if (!$this->view instanceof JsonView) {
720
+			/** @var JsonView $view */
721
+			$this->view = $this->objectManager->get('Fab\Vidi\Mvc\JsonView');
722
+			$this->view->setResponse($this->response);
723
+		}
724
+		return $this->view;
725
+	}
726
+
727
+	/**
728
+	 * @return JsonResult
729
+	 */
730
+	protected function getJsonResult()
731
+	{
732
+		return GeneralUtility::makeInstance('Fab\Vidi\Mvc\JsonResult');
733
+	}
734
+
735
+	/**
736
+	 * Signal that is called for post-processing content data send to the server for update.
737
+	 *
738
+	 * @param Content $contentObject
739
+	 * @param $fieldNameAndPath
740
+	 * @param $contentData
741
+	 * @param $counter
742
+	 * @param $savingBehavior
743
+	 * @param $language
744
+	 * @return ProcessContentDataSignalArguments
745
+	 * @signal
746
+	 */
747
+	protected function emitProcessContentDataSignal(Content $contentObject, $fieldNameAndPath, $contentData, $counter, $savingBehavior, $language)
748
+	{
749
+
750
+		/** @var \Fab\Vidi\Signal\ProcessContentDataSignalArguments $signalArguments */
751
+		$signalArguments = GeneralUtility::makeInstance('Fab\Vidi\Signal\ProcessContentDataSignalArguments');
752
+		$signalArguments->setContentObject($contentObject)
753
+			->setFieldNameAndPath($fieldNameAndPath)
754
+			->setContentData($contentData)
755
+			->setCounter($counter)
756
+			->setSavingBehavior($savingBehavior)
757
+			->setLanguage($language);
758
+
759
+		$signalResult = $this->getSignalSlotDispatcher()->dispatch('Fab\Vidi\Controller\Backend\ContentController', 'processContentData', array($signalArguments));
760
+		return $signalResult[0];
761
+	}
762
+
763
+	/**
764
+	 * Get the SignalSlot dispatcher.
765
+	 *
766
+	 * @return \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
767
+	 */
768
+	protected function getSignalSlotDispatcher()
769
+	{
770
+		return $this->objectManager->get('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
771
+	}
772
+
773
+	/**
774
+	 * Get the Clipboard service.
775
+	 *
776
+	 * @return \Fab\Vidi\Service\ClipboardService
777
+	 */
778
+	protected function getClipboardService()
779
+	{
780
+		return GeneralUtility::makeInstance('Fab\Vidi\Service\ClipboardService');
781
+	}
782
+
783
+	/**
784
+	 * @return \Fab\Vidi\Language\LanguageService
785
+	 */
786
+	protected function getLanguageService()
787
+	{
788
+		return GeneralUtility::makeInstance('Fab\Vidi\Language\LanguageService');
789
+	}
790
+
791
+	/**
792
+	 * Get the Vidi Module Loader.
793
+	 *
794
+	 * @return \Fab\Vidi\Module\ModuleLoader
795
+	 */
796
+	protected function getModuleLoader()
797
+	{
798
+		return GeneralUtility::makeInstance('Fab\Vidi\Module\ModuleLoader');
799
+	}
800 800
 
801 801
 }
Please login to merge, or discard this patch.
Classes/Controller/UserPreferencesController.php 1 patch
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -24,69 +24,69 @@
 block discarded – undo
24 24
 class UserPreferencesController extends ActionController
25 25
 {
26 26
 
27
-    /**
28
-     * @param string $key
29
-     * @param string $value
30
-     * @param string $preferenceSignature
31
-     * @return string
32
-     */
33
-    public function saveAction($key, $value, $preferenceSignature)
34
-    {
27
+	/**
28
+	 * @param string $key
29
+	 * @param string $value
30
+	 * @param string $preferenceSignature
31
+	 * @return string
32
+	 */
33
+	public function saveAction($key, $value, $preferenceSignature)
34
+	{
35 35
 
36
-        $dataType = $this->getModuleLoader()->getDataType();
36
+		$dataType = $this->getModuleLoader()->getDataType();
37 37
 
38
-        $key = $dataType . '_' . $this->getBackendUserIdentifier() . '_' . $key;
39
-        $this->getCacheInstance()->set($key, $value, array(), 0);
38
+		$key = $dataType . '_' . $this->getBackendUserIdentifier() . '_' . $key;
39
+		$this->getCacheInstance()->set($key, $value, array(), 0);
40 40
 
41
-        $key = $dataType . '_' . $this->getBackendUserIdentifier() . '_signature';
42
-        $this->getCacheInstance()->set($key, $preferenceSignature, array(), 0);
41
+		$key = $dataType . '_' . $this->getBackendUserIdentifier() . '_signature';
42
+		$this->getCacheInstance()->set($key, $preferenceSignature, array(), 0);
43 43
 
44
-        return 'OK';
45
-    }
44
+		return 'OK';
45
+	}
46 46
 
47
-    /**
48
-     * @return int
49
-     */
50
-    protected function getBackendUserIdentifier()
51
-    {
52
-        return $this->getBackendUser()->user['uid'];
53
-    }
47
+	/**
48
+	 * @return int
49
+	 */
50
+	protected function getBackendUserIdentifier()
51
+	{
52
+		return $this->getBackendUser()->user['uid'];
53
+	}
54 54
 
55
-    /**
56
-     * Returns an instance of the current Backend User.
57
-     *
58
-     * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
59
-     */
60
-    protected function getBackendUser()
61
-    {
62
-        return $GLOBALS['BE_USER'];
63
-    }
55
+	/**
56
+	 * Returns an instance of the current Backend User.
57
+	 *
58
+	 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
59
+	 */
60
+	protected function getBackendUser()
61
+	{
62
+		return $GLOBALS['BE_USER'];
63
+	}
64 64
 
65
-    /**
66
-     * Get the Vidi Module Loader.
67
-     *
68
-     * @return ModuleLoader
69
-     */
70
-    protected function getModuleLoader()
71
-    {
72
-        return GeneralUtility::makeInstance(ModuleLoader::class);
73
-    }
65
+	/**
66
+	 * Get the Vidi Module Loader.
67
+	 *
68
+	 * @return ModuleLoader
69
+	 */
70
+	protected function getModuleLoader()
71
+	{
72
+		return GeneralUtility::makeInstance(ModuleLoader::class);
73
+	}
74 74
 
75
-    /**
76
-     * @return \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend
77
-     */
78
-    protected function getCacheInstance()
79
-    {
80
-        return $this->getCacheManager()->getCache('vidi');
81
-    }
75
+	/**
76
+	 * @return \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend
77
+	 */
78
+	protected function getCacheInstance()
79
+	{
80
+		return $this->getCacheManager()->getCache('vidi');
81
+	}
82 82
 
83
-    /**
84
-     * Return the Cache Manager
85
-     *
86
-     * @return \TYPO3\CMS\Core\Cache\CacheManager
87
-     */
88
-    protected function getCacheManager()
89
-    {
90
-        return GeneralUtility::makeInstance('TYPO3\CMS\Core\Cache\CacheManager');
91
-    }
83
+	/**
84
+	 * Return the Cache Manager
85
+	 *
86
+	 * @return \TYPO3\CMS\Core\Cache\CacheManager
87
+	 */
88
+	protected function getCacheManager()
89
+	{
90
+		return GeneralUtility::makeInstance('TYPO3\CMS\Core\Cache\CacheManager');
91
+	}
92 92
 }
Please login to merge, or discard this patch.