diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4d83b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.php_cs.cache diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 0000000..b13755c --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,77 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'binary_operator_spaces' => true, + 'concat_space' => [ + 'spacing' => 'one', + ], + 'function_typehint_space' => true, + 'hash_to_slash_comment' => true, + 'linebreak_after_opening_tag' => true, + 'lowercase_cast' => true, + 'method_separation' => true, + 'native_function_casing' => true, + 'new_with_braces' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_blank_lines_before_namespace' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_consecutive_blank_lines' => [ + 'continue', + 'curly_brace_block', + 'extra', + 'parenthesis_brace_block', + 'square_brace_block', + 'throw', + ], + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_multiline_whitespace_before_semicolons' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_unneeded_control_parentheses' => [ + 'break', + 'clone', + 'continue', + 'echo_print', + 'return', + 'switch_case', + ], + 'no_unreachable_default_argument_value' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'normalize_index_brace' => true, + 'ordered_imports' => true, + 'phpdoc_add_missing_param_annotation' => true, + 'phpdoc_no_package' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_types' => true, + 'self_accessor' => true, + 'short_scalar_cast' => true, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'ternary_operator_spaces' => true, + 'trailing_comma_in_multiline_array' => true, + 'whitespace_after_comma_in_array' => true, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__) + ->exclude('Resources') + ->notName('ext_emconf.php') + ); diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..5573af3 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,59 @@ +preset: psr2 + +enabled: + - alpha_ordered_imports + - binary_operator_spaces + - concat_with_spaces + - function_typehint_space + - hash_to_slash_comment + - linebreak_after_opening_tag + - lowercase_cast + - method_separation + - native_function_casing + - new_with_braces + - no_alias_functions + - no_blank_lines_after_class_opening + - no_blank_lines_after_phpdoc + - no_blank_lines_before_namespace + - no_empty_comment + - no_empty_phpdoc + - no_empty_statement + - no_extra_block_blank_lines + - no_extra_consecutive_blank_lines + - no_leading_import_slash + - no_leading_namespace_whitespace + - no_multiline_whitespace_around_double_arrow + - no_multiline_whitespace_before_semicolons + - no_short_bool_cast + - no_singleline_whitespace_before_semicolons + - no_trailing_comma_in_list_call + - no_trailing_comma_in_singleline_array + - no_unneeded_control_parentheses + - no_unreachable_default_argument_value + - no_unused_imports + - no_useless_else + - no_useless_return + - no_whitespace_before_comma_in_array + - no_whitespace_in_blank_line + - normalize_index_brace + - phpdoc_add_missing_param_annotation + - phpdoc_no_package + - phpdoc_order + - phpdoc_scalar + - phpdoc_types + - self_accessor + - short_array_syntax + - short_scalar_cast + - single_quote + - standardize_not_equals + - ternary_operator_spaces + - trailing_comma_in_multiline_array + - whitespace_after_comma_in_array + +finder: + name: + - "*.php" + exclude: + - "Resources" + not-name: + - "ext_emconf.php" diff --git a/Classes/Controller/DashboardController.php b/Classes/Controller/DashboardController.php index 0ae90d0..b1cd231 100644 --- a/Classes/Controller/DashboardController.php +++ b/Classes/Controller/DashboardController.php @@ -1,5 +1,5 @@ backendUserAuthentication = $backendUserAuthentication ?: $GLOBALS['BE_USER']; + } /** * Initialize action */ public function initializeAction() { + $dashboardSettings = $this->objectManager + ->get(ConfigurationManagerInterface::class) + ->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, 'dashboard', 'dashboardmod1'); + + $userTsConfigSettings = GeneralUtility::removeDotsFromTS((array)$this->backendUserAuthentication->getTSConfigProp('tx_dashboard.settings')); + $this->dashboardSettings = array_replace($dashboardSettings, $userTsConfigSettings); $querySettings = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings'); - $querySettings->setRespectStoragePage(false); + if (empty($this->dashboardSettings['persistence']['storagePid']) || strpos($this->dashboardSettings['persistence']['storagePid'], ',') !== false) { + throw new \UnexpectedValueException('tx_dashboard.persistence.storagePid must be set in Dashboard settings or user tsconfig and must be a single page id', 1511102864); + } + $querySettings->setStoragePageIds([$this->dashboardSettings['persistence']['storagePid']]); $this->dashboardRepository->setDefaultQuerySettings($querySettings); - $configurationManager = GeneralUtility::makeInstance(ObjectManager::class) - ->get(ConfigurationManagerInterface::class); - $this->dashboardSettings = $configurationManager - ->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, 'dashboard', 'dashboardmod1'); - + $dashBoardUid = null; if ($this->request->hasArgument('id')) { - $this->dashboard = $this->dashboardRepository->findByUid($this->request->getArgument('id')); - if ($this->dashboard->getBeUser()->getuid() != $this->getBackendUser()->user['uid']) { - throw new \Exception("Access denied to selected dashboard", 1); + $dashBoardUid = (int)$this->request->getArgument('id'); + } + if ($dashBoardUid) { + $this->dashboard = $this->dashboardRepository->findByUid($dashBoardUid); + if ($this->dashboard->getBeUser()->getUid() !== (int)$this->backendUserAuthentication->user['uid']) { + throw new \Exception('Access denied to selected dashboard', 1); } } else { - $this->dashboard = $this->dashboardRepository->findByBeuser($this->getBackendUser()->user['uid'])->getFirst(); - }; + $this->dashboard = $this->dashboardRepository->findOneByBeuser($this->backendUserAuthentication->user['uid']); + } } /** @@ -151,29 +170,29 @@ public function indexAction() $this->view->assign('dashboard', $this->dashboard); } + public function initializeChangeAction() + { + $configuration = $this->arguments->getArgument('items') + ->getPropertyMappingConfiguration(); + + $configuration->allowAllProperties(); + $configuration->forProperty('*')->setTypeConverterOption(PersistentObjectConverter::class, PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED, true); + $configuration->forProperty('*.*')->allowAllProperties(); + } + /** * action change * + * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Pixelant\Dashboard\Domain\Model\Widget> $items * @return string */ - public function changeAction() + public function changeAction($items) { - $getVars = $this->request->getArguments(); - $items = $getVars['items']; - if (!empty($items) && is_array($items)) { - foreach ($items as $index => $item) { - $widget = $this->dashboardWidgetSettingsRepository->findByUid($item['uid']); - $widget->setX($item['x']); - $widget->setY($item['y']); - $widget->setWidth($item['width']); - $widget->setHeight($item['height']); - $this->dashboardWidgetSettingsRepository->update($widget); - } - $this->objectManager - ->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class) - ->persistAll(); + foreach ($items as $widget) { + $this->dashboard->updateWidget($widget); } - return 'sent string was: ' . print_r($getVars['items'], true); + $this->dashboardRepository->update($this->dashboard); + return 'Updated widget positions'; } /** @@ -184,19 +203,19 @@ public function changeAction() public function createWidgetAction() { $getVars = $this->request->getArguments(); - if (is_object($this->dashboard)) { + if ($this->dashboard) { $storagePid = $this->dashboardSettings['persistence']['storagePid']; $widgetType = $getVars['widgetType']; $widgetSettings = $this->getWidgetSettings($widgetType); - $width = (isset($widgetSettings['defaultWidth'])) ? $widgetSettings['defaultWidth'] : 3; - $height = (isset($widgetSettings['defaultHeight'])) ? $widgetSettings['defaultHeight'] : 5; - $overrideVals = '&overrideVals[tx_dashboard_domain_model_dashboardwidgetsettings][dashboard]=' . $this->dashboard->getUid(); - $overrideVals .= '&overrideVals[tx_dashboard_domain_model_dashboardwidgetsettings][widget_identifier]=' . $getVars['widgetType']; - $overrideVals .= '&overrideVals[tx_dashboard_domain_model_dashboardwidgetsettings][width]=' . $width; - $overrideVals .= '&overrideVals[tx_dashboard_domain_model_dashboardwidgetsettings][height]=' . $height; - $overrideVals .= '&overrideVals[tx_dashboard_domain_model_dashboardwidgetsettings][y]=' . $this->getNextRow($this->dashboard->getUid()); - $overrideVals .= '&overrideVals[tx_dashboard_domain_model_dashboardwidgetsettings][x]=0'; - $params = '&edit[tx_dashboard_domain_model_dashboardwidgetsettings][' . $storagePid . ']=new' . $overrideVals; + $width = $widgetSettings['defaultWidth'] ?? 3; + $height = $widgetSettings['defaultHeight'] ?? 5; + $overrideVals = '&overrideVals[tx_dashboard_domain_model_widget][dashboard]=' . $this->dashboard->getUid(); + $overrideVals .= '&overrideVals[tx_dashboard_domain_model_widget][widget_identifier]=' . $getVars['widgetType']; + $overrideVals .= '&overrideVals[tx_dashboard_domain_model_widget][width]=' . $width; + $overrideVals .= '&overrideVals[tx_dashboard_domain_model_widget][height]=' . $height; + $overrideVals .= '&overrideVals[tx_dashboard_domain_model_widget][y]=' . $this->dashboard->findNextAvailableWidgetPosition(); + $overrideVals .= '&overrideVals[tx_dashboard_domain_model_widget][x]=0'; + $params = '&edit[tx_dashboard_domain_model_widget][' . $storagePid . ']=new' . $overrideVals; $returnUrl = urlencode($this->controllerContext->getUriBuilder()->uriFor('index', ['id' => $this->dashboard->getUid()])); return BackendUtility::getModuleUrl('record_edit') . $params . '&returnUrl=' . $returnUrl; @@ -213,51 +232,48 @@ public function createAction() { $getVars = $this->request->getArguments(); - if (isset($GLOBALS['BE_USER']->user['uid'])) { - $beUserUid = (int)$GLOBALS['BE_USER']->user['uid']; + if (isset($this->backendUserAuthentication->user['uid'])) { + $beUserUid = (int)$this->backendUserAuthentication->user['uid']; $beUserRepository = $this->objectManager->get( \TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository::class ); $beUser = $beUserRepository->findByUid($beUserUid); if ($beUser !== null) { - $newDashboard = $this->objectManager->get(\TYPO3\CMS\Dashboard\Domain\Model\Dashboard::class); + $newDashboard = $this->objectManager->get(\Pixelant\Dashboard\Domain\Model\Dashboard::class); $newDashboard->setTitle($getVars['dashboardName']); + $newDashboard->setPid($this->dashboardSettings['persistence']['storagePid']); $newDashboard->setBeuser($beUser); $this->dashboardRepository->add($newDashboard); - $this->objectManager - ->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class) - ->persistAll(); + // We need to call persistAll here to get the uid of the just created dashboard + $this->objectManager->get(PersistenceManagerInterface::class)->persistAll(); + return $this->controllerContext->getUriBuilder()->uriFor('index', ['id' => $newDashboard->getUid()]); } - // return 'Would create dashboard with name: ' . $getVars['dashboardName']; - return $this->controllerContext->getUriBuilder()->uriFor('index', ['id' => $newDashboard->getUid()]); } - return false; //$this->controllerContext->getUriBuilder()->uriFor('index'); + return false; } /** * action renderWidget * + * @param int $widgetId * @return string */ - public function renderWidgetAction() + public function renderWidgetAction(int $widgetId) { - $content = ''; - $getVars = $this->request->getArguments(); - $widgetId = $getVars['widgetId']; $errorTitle = $this ->getLanguageService() ->sL('LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:error.title'); - + $content = ''; if (!empty($widgetId) && (int)$widgetId > 0) { - $widget = $this->dashboardWidgetSettingsRepository->findByUid($widgetId); + $widget = $this->dashboard->getWidgetById($widgetId); if ($widget) { - $widgetConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$widget->getWidgetIdentifier()]; - $widgetClassName = $widgetConfiguration['class']; - if (class_exists($widgetClassName)) { - $widgetClass = $this->objectManager->get($widgetClassName); + $widgetSettings = $widget->getSettings(); + $widgetControllerClassName = $widgetSettings['class']; + if (class_exists($widgetControllerClassName)) { + $widgetController = $this->objectManager->get($widgetControllerClassName); try { - return $widgetClass->render($widget); + return $widgetController->render($widget); } catch (\Exception $e) { $localizedError = $this ->getLanguageService() @@ -268,10 +284,10 @@ public function renderWidgetAction() $content = $this->getHtmlErrorMessage($errorTitle, $localizedError); } } else { - $content = $this->getHtmlErrorMessage($errorTitle, 'Class : ' . $widgetClassName .' could not be found!'); + $content = $this->getHtmlErrorMessage($errorTitle, 'Class : ' . $widgetControllerClassName . ' could not be found!'); } } else { - $content = $this->getHtmlErrorMessage($errorTitle, 'Widget [' . $widgetId .'] could not be found!'); + $content = $this->getHtmlErrorMessage($errorTitle, 'Widget [' . $widgetId . '] could not be found!'); } } return $content; @@ -285,15 +301,17 @@ public function renderWidgetAction() protected function registerDocheaderMenu() { // Dashboards - $dashboards = $this->dashboardRepository->findByBeuser((int)$GLOBALS['BE_USER']->user['uid']); + $dashboards = $this->dashboardRepository->findByBeuser((int)$this->backendUserAuthentication->user['uid']); if (!empty($dashboards)) { $dashboardMenu = $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->makeMenu(); - $dashboardMenu->setIdentifier('_dsahboardSelector'); + $dashboardMenu->setIdentifier('_dashboardSelector'); + $uriBuilder = $this->controllerContext->getUriBuilder(); foreach ($dashboards as $index => $dashboard) { + $uriBuilder->reset(); $menuItem = $dashboardMenu->makeMenuItem() ->setTitle($dashboard->getTitle()) ->setHref( - $this->controllerContext->getUriBuilder()->uriFor('index', ['id' => $dashboard->getUid()]) + $uriBuilder->uriFor('index', ['id' => $dashboard->getUid()]) ); if ($dashboard->getUid() === $this->dashboard->getUid()) { $menuItem->setActive(true); @@ -313,7 +331,6 @@ protected function registerDocheaderButtons() { /** @var ButtonBar $buttonBar */ $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar(); - $getVars = $this->request->getArguments(); // New dashboard button $newDashboardButton = $buttonBar->makeLinkButton() @@ -338,8 +355,8 @@ protected function registerDocheaderButtons() $newWidgetButton = $buttonBar->makeLinkButton() ->setDataAttributes( [ - 'identifier' => 'newDashboardWidgetSetting', - 'dashboardid' => $this->dashboard->getUid() + 'identifier' => 'newWidget', + 'dashboardid' => $this->dashboard->getUid(), ] ) ->setHref('#') @@ -363,31 +380,30 @@ protected function registerDocheaderButtons() * Returns the json encoded data which is used by the dashboard * JavaScript app. * - * @return string + * @return array */ - protected function getDashboardAppInitialData(): string + protected function getDashboardAppInitialData(): array { + $uriBuilder = $this->controllerContext->getUriBuilder(); + $uriBuilder->reset(); + $uriArguments = $this->dashboard ? ['id' => $this->dashboard->getUid()] : []; $dashboardAppInitialData = [ 'selectableWidgetTypesConfiguration' => $this->getSelectableWidgets(), 'endpoints' => [ - 'create' => $this->controllerContext->getUriBuilder()->uriFor('create'), - 'createWidget' => $this->controllerContext->getUriBuilder()->uriFor('createWidget'), - 'change' => $this->controllerContext->getUriBuilder()->uriFor('change'), - 'index' => $this->controllerContext->getUriBuilder()->uriFor('index'), - 'renderWidget' => $this->controllerContext->getUriBuilder()->uriFor('renderWidget'), + 'create' => $uriBuilder->uriFor('create'), + 'createWidget' => $uriBuilder->uriFor('createWidget', $uriArguments), + 'change' => $uriBuilder->uriFor('change', $uriArguments), + 'index' => $uriBuilder->uriFor('index', $uriArguments), + 'renderWidget' => $uriBuilder->uriFor('renderWidget', $uriArguments), 'editDashboard' => $this->getEditDashboardEndpoint(), ], ]; - if (is_object($this->dashboard)) { + if ($this->dashboard) { $dashboardAppInitialData['dashboard'] = [ 'id' => $this->dashboard->getUid(), 'title' => $this->dashboard->getTitle(), ]; - $dashboardAppInitialData['endpoints']['index'] = - $this->controllerContext->getUriBuilder()->uriFor( - 'index', ['id' => $this->dashboard->getUid()] - ); } $dashboardAppInitialData = ArrayUtility::reIndexNumericArrayKeysRecursive($dashboardAppInitialData); @@ -396,7 +412,7 @@ protected function getDashboardAppInitialData(): string $this->dashboardSettings['settings']['translationFile'] ); - return json_encode($dashboardAppInitialData); + return $dashboardAppInitialData; } /** @@ -406,7 +422,7 @@ protected function getDashboardAppInitialData(): string */ protected function getSelectableWidgets(): array { - $items = $GLOBALS['TCA']['tx_dashboard_domain_model_dashboardwidgetsettings']['columns']['widget_identifier']['config']['items']; + $items = $GLOBALS['TCA']['tx_dashboard_domain_model_widget']['columns']['widget_identifier']['config']['items']; unset($items['0']); if (!empty($items) && is_array($items)) { foreach ($items as $index => $values) { @@ -419,52 +435,14 @@ protected function getSelectableWidgets(): array /** * Returns array of item configured for widget_identifier * - * @param string widgetIdentifier + * @param string $widgetIdentifier * * @return array */ protected function getWidgetSettings(string $widgetIdentifier): array { - $widgetSettings = []; - - $selectableWidgets = $this->getSelectableWidgets(); - if (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$widgetIdentifier])) { - $widgetSettings = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$widgetIdentifier]; - } - return $widgetSettings; - } - - /** - * Returns next available "row" - * - * @param integer $dasboardId - * - * @return integer - */ - protected function getNextRow(int $dasboardId): int - { - $retval = 0; - - /** @var QueryBuilder $queryBuilder */ - $queryBuilder = - GeneralUtility::makeInstance( - \TYPO3\CMS\Core\Database\ConnectionPool::class - )->getQueryBuilderForTable('tx_dashboard_domain_model_dashboardwidgetsettings'); - - $result = $queryBuilder - ->select('y', 'height') - ->from('tx_dashboard_domain_model_dashboardwidgetsettings') - ->where($queryBuilder->expr()->eq('dashboard', $dasboardId)) - ->andWhere($queryBuilder->expr()->eq('deleted', 0)) - ->orderBy('y', 'DESC') - ->addOrderBy('height', 'DESC') - ->execute() - ->fetch(); - - if ($result) { - $retval = $result['y'] + $result['height']; - } - return $retval; + $widget = new Widget($widgetIdentifier); + return $widget->getSettings(); } /** @@ -475,7 +453,7 @@ protected function getNextRow(int $dasboardId): int protected function getEditDashboardEndpoint() { $editDashboardEndpoint = ''; - if (is_object($this->dashboard)) { + if ($this->dashboard) { $params = '&edit[tx_dashboard_domain_model_dashboard][' . $this->dashboard->getUid() . ']=edit'; $returnUrl = urlencode($this->controllerContext->getUriBuilder()->uriFor('index', ['id' => $this->dashboard->getUid()])); $editDashboardEndpoint = BackendUtility::getModuleUrl('record_edit') . $params . '&returnUrl=' . $returnUrl; @@ -532,8 +510,8 @@ protected function getHtmlErrorMessage($title, $message) $content .= ' '; $content .= ' '; $content .= '
'; - $content .= '

' . $title . '

'; - $content .= '

' . $message . '

'; + $content .= '

' . htmlspecialchars($title) . '

'; + $content .= '

' . htmlspecialchars($message) . '

'; $content .= '
'; $content .= ' '; $content .= ' '; @@ -541,16 +519,6 @@ protected function getHtmlErrorMessage($title, $message) return $content; } - /** - * Returns the current BE user. - * - * @return BackendUserAuthentication - */ - protected function getBackendUser(): BackendUserAuthentication - { - return $GLOBALS['BE_USER']; - } - /** * Returns the Language Service * diff --git a/Classes/DashboardWidgetInterface.php b/Classes/DashboardWidgetInterface.php deleted file mode 100644 index 6f6e81a..0000000 --- a/Classes/DashboardWidgetInterface.php +++ /dev/null @@ -1,16 +0,0 @@ -get('TYPO3\\CMS\\Extbase\\Service\\FlexFormService'); - return $flexFormService->convertFlexFormContentToArray($dashboardWidgetSetting->getSettingsFlexform()); - } -} diff --git a/Classes/DashboardWidgets/RssWidget.php b/Classes/DashboardWidgets/RssWidget.php deleted file mode 100644 index b0890f7..0000000 --- a/Classes/DashboardWidgets/RssWidget.php +++ /dev/null @@ -1,232 +0,0 @@ -initialize($dashboardWidgetSetting); - - $content = false; - if ($this->cacheLifetime == NULL) { - $content = $this->generateContent(); - } else { - /** @var \TYPO3\CMS\Core\Cache\CacheManager $cacheManager */ - $cacheManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager')->get('TYPO3\\CMS\\Core\\Cache\\CacheManager'); - $cacheIdentifier = 'dashboardWidget_' . (int)$dashboardWidgetSetting->getUid(); - - if (TRUE === $cacheManager->hasCache('dashboard') && TRUE === $cacheManager->getCache('dashboard')->has($cacheIdentifier)) { - $content = $cacheManager->getCache('dashboard')->get($cacheIdentifier); - } else { - $content = $this->generateContent(); - $cacheManager->getCache('dashboard')->set($cacheIdentifier, $content, array(), $this->cacheLifetime); - } - unset($cacheManager); - } - return $content; - } - - /** - * Initializes settings from flexform - * @param \TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings $dashboardWidgetSetting - * @return void - */ - private function initialize($dashboardWidgetSetting = NULL) { - $flexformSettings = $this->getFlexFormSettings($dashboardWidgetSetting); - $this->feedUrl = $flexformSettings['settings']['feedUrl']; - $this->feedLimit = (int)$flexformSettings['settings']['feedLimit']; - $this->cacheLifetime = (int)$flexformSettings['settings']['cacheLifetime'] * 60; - $this->widget = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$dashboardWidgetSetting->getWidgetIdentifier()]; - } - - /** - * Generates the content - * @return string - */ - private function generateContent() { - $widgetTemplateName = $this->widget['template']; - $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); - $rssView = $objectManager->get('TYPO3\\CMS\\Fluid\\View\\StandaloneView'); - $template = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($widgetTemplateName); - $rssView->setTemplatePathAndFilename($template); - $feed = $this->getFeed(); - $rssView->assign('feed', $feed); - $rssView->assign('currentdate', time()); - $rssView->assign('cacheLifetime', $this->cacheLifetime); - return $rssView->render(); - } - - /** - * Loads feed and cuts unneeded items - * - * @return array Array from xml - */ - private function getFeed() { - $feed = []; - $report = []; - if (\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($this->feedUrl)) { - - $content = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl( - $this->feedUrl, - 0, - null, - $report - ); - if (!$content) { - if (isset($report['message'])) { - throw new \Exception($report['message'], $report['error']); - } else { - throw new \Exception("The response was empty", 1910020001); - } - } - if (!empty($content)) { - $simpleXmlElement = simplexml_load_string( $content ,'SimpleXMLElement'); - if (!$simpleXmlElement) { - throw new \Exception('The response is not valid XML', 1910020003); - } - $feed['channel'] = $this->rssToArray($simpleXmlElement); - if ((int)$this->feedLimit > 0) { - $feed['channel']['item'] = array_splice($feed['channel']['item'], 0, $this->feedLimit); - } - } else { - throw new \Exception('An error occured', 1910020002); - } - } else { - throw new \Exception('The provided url is not valid', 1910020004); - } - return $feed; - } - - /** - * rssToArray RSS to array from a SimpleXMLElement - * @param \SimpleXmlElement $simpleXmlElement - * @return array - */ - private function rssToArray($simpleXmlElement) { - $rss2Array = array(); - $rss2Array = $this->sxeToArray($simpleXmlElement->channel); - foreach($simpleXmlElement->channel->item as $simpleXmlElementItem) { - $simpleXmlElementArray = $this->sxeToArray($simpleXmlElementItem); - if ($simpleXmlElementArray) { - $rss2Array['item'][] = $simpleXmlElementArray; - } - } - return $rss2Array; - } - - /** - * sxeToArray Generates the base array for the element, also includes namespaces. - * @param \SimpleXMLElement $simpleXmlElement The element to create an array of - * @return array - */ - private function sxeToArray($simpleXmlElement) { - $returnArray = false; - $children = $simpleXmlElement->children(); - $sxeChildrenToArray = $this->sxeChildrenToArray($children); - if ($sxeChildrenToArray) { - $returnArray = $sxeChildrenToArray; - } - $namespaces = $simpleXmlElement->getNamespaces(TRUE); - foreach ($namespaces as $ns => $nsuri) { - $children = $simpleXmlElement->children($ns, true); - $sxeChildrenToArray = $this->sxeChildrenToArray($children); - if ($sxeChildrenToArray) { - $returnArray[$ns] = $sxeChildrenToArray; - } - } - return $returnArray; - } - - /** - * sxeChildrenToArray Returns an array of the elements children and attributes recursively - * @param mixed $children The children of a element - * @return array - */ - private function sxeChildrenToArray($children) { - $nodeData = array(); - if (count($children) > 0) { - foreach ($children as $elementName => $node) { - $nodeName = $this->stringToArrayKey((string)$elementName); - $nodeData[$nodeName] = array(); - $nodeAttributes = $node->attributes(); - if (count($nodeAttributes) > 0) { - foreach ($nodeAttributes as $nodeAttributeName => $nodeAttributeValue) { - $arrayKey = $this->stringToArrayKey((string)$nodeAttributeName); - $arrayValue = trim((string)$nodeAttributeValue->__toString()); - $nodeData[$nodeName][$arrayKey] = $arrayValue; - } - } - $nodeValue = trim((string)$node); - if (strlen($nodeValue) > 0) { - if (count($nodeAttributes) == 0) { - $nodeData[$nodeName] = $nodeValue; - } else { - $nodeData[$nodeName]['value'] = $nodeValue; - } - } else { - if ($nodeName != 'item') { - $childs = $this->sxeToArray($node); - if ($childs) { - $nodeData[$nodeName] = $childs; - } - } - } - } - return $nodeData; - } else { - return false; - } - } - - /** - * stringToArrayKey Returns a string which is ok to use as array key - * @param string $key The array key to check - * @return string - */ - private function stringToArrayKey($key) { - return str_replace('.', '_', trim((string)$key)); - } -} diff --git a/Classes/Domain/Model/Dashboard.php b/Classes/Domain/Model/Dashboard.php index 124011e..a578625 100644 --- a/Classes/Domain/Model/Dashboard.php +++ b/Classes/Domain/Model/Dashboard.php @@ -1,5 +1,6 @@ + * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Pixelant\Dashboard\Domain\Model\Widget> */ - protected $dashboardWidgetSettings = null; + protected $widgets; /** - * Widgets - * * @var \TYPO3\CMS\Beuser\Domain\Model\BackendUser */ protected $beuser = null; @@ -80,7 +78,46 @@ public function __construct() */ protected function initStorageObjects() { - $this->dashboardWidgetSettings = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage(); + $this->widgets = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage(); + } + + /** + * @return int + */ + public function findNextAvailableWidgetPosition(): int + { + if (!$this->widgets || $this->widgets->count() === 0) { + return 0; + } + $orderedWidgets = iterator_to_array($this->widgets); + usort($orderedWidgets, function($widgetOne, $widgetTwo) { + return $widgetOne->getY() + $widgetOne->getHeight() < $widgetTwo->getY() + $widgetTwo->getHeight(); + }); + + return $orderedWidgets[0]->getY() + $orderedWidgets[0]->getHeight(); + } + + public function updateWidget(Widget $updatedWidget) + { + $widget = $this->getWidgetById($updatedWidget->getUid()); + if ($widget) { + $this->widgets->detach($widget); + $this->widgets->attach($updatedWidget); + } + } + + /** + * @param int $uid + * @return Widget|null + */ + public function getWidgetById(int $uid) + { + foreach ($this->widgets as $widget) { + if ($widget->getUid() === $uid) { + return $widget; + } + } + return null; } /** @@ -128,44 +165,41 @@ public function setDescription($description) /** * Adds a DashboardWidget * - * @param \TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings $dashboardWidgetSetting - * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings> dashboardWidgetSettings + * @param \Pixelant\Dashboard\Domain\Model\Widget $widget */ - public function addDashboardWidgetSetting(\TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings $dashboardWidgetSetting) + public function addWidget(\Pixelant\Dashboard\Domain\Model\Widget $widget) { - $this->dashboardWidgetSettings->attach($dashboardWidgetSetting); + $this->widgets->attach($widget); } /** * Removes a DashboardWidget * - * @param \TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings $dashboardWidgetSettingToRemove The DashboardWidgetSettings to be removed - * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings> dashboardWidgetSettings + * @param \Pixelant\Dashboard\Domain\Model\Widget $widget The Widget to be removed */ - public function removeDashboardWidgetSetting(\TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings $dashboardWidgetSettingToRemove) + public function removeWidget(\Pixelant\Dashboard\Domain\Model\Widget $widget) { - $this->dashboardWidgetSettings->detach($dashboardWidgetSettingToRemove); + $this->widgets->detach($widget); } /** - * Returns the dashboardWidgetSettings + * Returns the widget * - * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings> dashboardWidgetSettings + * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Pixelant\Dashboard\Domain\Model\Widget> */ - public function getDashboardWidgetSettings() + public function getWidgets() { - return $this->dashboardWidgetSettings; + return $this->widgets; } /** - * Sets the dashboardWidgetSettings + * Sets the widget * - * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings> $dashboardWidgetSettings - * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings> dashboardWidgetSettings + * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Pixelant\Dashboard\Domain\Model\Widget> $widgets */ - public function setDashboardWidgetSettings(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $dashboardWidgetSettings) + public function setWidgets(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $widgets) { - $this->dashboardWidgetSettings = $dashboardWidgetSettings; + $this->widgets = $widgets; } /** diff --git a/Classes/Domain/Model/DashboardWidgetSettings.php b/Classes/Domain/Model/Widget.php similarity index 58% rename from Classes/Domain/Model/DashboardWidgetSettings.php rename to Classes/Domain/Model/Widget.php index 273a086..9b44cf7 100644 --- a/Classes/Domain/Model/DashboardWidgetSettings.php +++ b/Classes/Domain/Model/Widget.php @@ -1,5 +1,5 @@ title; + private $backendUserAuthentication; + + /** + * @param string $widgetIdentifier + * @param string $title + * @param string $settingsFlexform + * @param FlexFormService $flexFormService + * @param BackendUserAuthentication $backendUserAuthentication + */ + public function __construct( + $widgetIdentifier, + $title = '', + $settingsFlexform = '', + FlexFormService $flexFormService = null, + BackendUserAuthentication $backendUserAuthentication = null + ) { + $this->flexFormService = $flexFormService ?: GeneralUtility::makeInstance(FlexFormService::class); + $this->backendUserAuthentication = $backendUserAuthentication ?: $GLOBALS['BE_USER']; } /** - * Sets the title + * Make sure a thawed object also gets this dependency injected * - * @param string $title - * @return void + * @param FlexFormService $flexFormService */ - public function setTitle($title) + public function injectFlexFormService(FlexFormService $flexFormService) { - $this->title = $title; + $this->flexFormService = $flexFormService; + $this->backendUserAuthentication = $GLOBALS['BE_USER']; } /** - * Returns the state + * Returns the title * - * @return string $state + * @return string $title */ - public function getState() + public function getTitle() { - return $this->state; + return $this->title; } /** - * Sets the state + * Returns the state * - * @param string $state - * @return void + * @return string $state */ - public function setState($state) + public function getState() { - $this->state = $state; + return $this->state; } /** * Returns the x * - * @return integer $x + * @return int $x */ public function getX() { @@ -143,7 +163,7 @@ public function getX() /** * Sets the x * - * @param integer $x + * @param int $x * @return void */ public function setX($x) @@ -154,7 +174,7 @@ public function setX($x) /** * Returns the y * - * @return integer $y + * @return int $y */ public function getY() { @@ -164,7 +184,7 @@ public function getY() /** * Sets the y * - * @param integer $y + * @param int $y * @return void */ public function setY($y) @@ -175,7 +195,7 @@ public function setY($y) /** * Returns the width * - * @return integer $width + * @return int $width */ public function getWidth() { @@ -185,7 +205,7 @@ public function getWidth() /** * Sets the width * - * @param integer $width + * @param int $width * @return void */ public function setWidth($width) @@ -196,7 +216,7 @@ public function setWidth($width) /** * Returns the height * - * @return integer $height + * @return int $height */ public function getHeight() { @@ -206,7 +226,7 @@ public function getHeight() /** * Sets the height * - * @param integer $height + * @param int $height * @return void */ public function setHeight($height) @@ -214,25 +234,17 @@ public function setHeight($height) $this->height = $height; } - /** - * Returns the settingsFlexform - * - * @return string $settingsFlexform - */ - public function getSettingsFlexform() - { - return $this->settingsFlexform; - } - - /** - * Sets the settingsFlexform - * - * @param string $settingsFlexform - * @return void - */ - public function setSettingsFlexform($settingsFlexform) + public function getSettings(): array { - $this->settingsFlexform = $settingsFlexform; + $widgetSettings = []; + if (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$this->widgetIdentifier])) { + $widgetSettings = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$this->widgetIdentifier]; + } + if (empty($this->settingsFlexform)) { + return $widgetSettings; + } + $userTsConfigSettings = GeneralUtility::removeDotsFromTS((array)$this->backendUserAuthentication->getTSConfigProp('tx_dashboard.widgets.' . $this->widgetIdentifier . '.settings')); + return array_replace($widgetSettings, $userTsConfigSettings, $this->flexFormService->convertFlexFormContentToArray($this->settingsFlexform)['settings'] ?? []); } /** @@ -244,15 +256,4 @@ public function getWidgetIdentifier() { return $this->widgetIdentifier; } - - /** - * Sets the widgetIdentifier - * - * @param string $widgetIdentifier - * @return string widgetIdentifier - */ - public function setWidgetIdentifier($widgetIdentifier) - { - $this->widgetIdentifier = $widgetIdentifier; - } } diff --git a/Classes/Domain/Repository/DashboardRepository.php b/Classes/Domain/Repository/DashboardRepository.php index 1bfbf29..44c24d1 100644 --- a/Classes/Domain/Repository/DashboardRepository.php +++ b/Classes/Domain/Repository/DashboardRepository.php @@ -1,5 +1,5 @@ get(self::class); + } + + /** + * Returns the localized label of the LOCAL_LANG key, $key. + * + * @param mixed $key The key from the LOCAL_LANG array for which to return the value. + * @param array $arguments the arguments of the extension, being passed over to vsprintf + * @param string $locallangPathAndFilename + * @param string $language + * @param mixed $defaultValue + * @return mixed The value from LOCAL_LANG or $defaultValue if no translation was found. + */ + public function translate( + $key, + array $arguments = null, + string $locallangPathAndFilename = null, + string $language = null, + $defaultValue = '' + ) { + $value = null; + $key = (string) $key; + + if ($locallangPathAndFilename) { + $key = $locallangPathAndFilename . ':' . $key; + } + + $keyParts = explode(':', $key); + if (GeneralUtility::isFirstPartOfStr($key, 'LLL:')) { + $locallangPathAndFilename = $keyParts[1] . ':' . $keyParts[2]; + $key = $keyParts[3]; + } elseif (GeneralUtility::isFirstPartOfStr($key, 'EXT:')) { + $locallangPathAndFilename = $keyParts[0] . ':' . $keyParts[1]; + $key = $keyParts[2]; + } else { + if (count($keyParts) === 2) { + $locallangPathAndFilename = $keyParts[0]; + $key = $keyParts[1]; + } + } + + if ($language) { + $this->languageKey = $language; + } + + $this->initializeLocalization($locallangPathAndFilename); + + // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG + if (!empty($this->LOCAL_LANG[$this->languageKey][$key][0]['target']) + || isset($this->LOCAL_LANG_UNSET[$this->languageKey][$key]) + ) { + // Local language translation for key exists + $value = $this->LOCAL_LANG[$this->languageKey][$key][0]['target']; + } elseif (!empty($this->alternativeLanguageKeys)) { + $languages = array_reverse($this->alternativeLanguageKeys); + foreach ($languages as $language) { + if (!empty($this->LOCAL_LANG[$language][$key][0]['target']) + || isset($this->LOCAL_LANG_UNSET[$language][$key]) + ) { + // Alternative language translation for key exists + $value = $this->LOCAL_LANG[$language][$key][0]['target']; + break; + } + } + } + + if ($value === null && (!empty($this->LOCAL_LANG['default'][$key][0]['target']) + || isset($this->LOCAL_LANG_UNSET['default'][$key])) + ) { + // Default language translation for key exists + // No charset conversion because default is English and thereby ASCII + $value = $this->LOCAL_LANG['default'][$key][0]['target']; + } + + if (is_array($arguments) && !empty($arguments) && $value !== null) { + $value = vsprintf($value, $arguments); + } else { + if (empty($value)) { + $value = $defaultValue; + } + } + + return $value; + } + + /** + * Recursively translate values. + * + * @param array $array + * @param array|string|null $translationFile + * @return array the modified array + */ + public function translateValuesRecursive(array $array, $translationFile = null): array + { + $result = $array; + foreach ($result as $key => $value) { + if (is_array($value)) { + $result[$key] = $this->translateValuesRecursive($value, $translationFile); + } else { + $translationFiles = null; + if (is_string($translationFile)) { + $translationFiles = [$translationFile]; + } elseif (is_array($translationFile)) { + $translationFiles = $this->sortArrayWithIntegerKeysDescending($translationFile); + } + + if ($translationFiles) { + foreach ($translationFiles as $_translationFile) { + $translatedValue = $this->translate($value, null, $_translationFile, null); + if (!empty($translatedValue)) { + $result[$key] = $translatedValue; + break; + } + } + } else { + $result[$key] = $this->translate($value, null, $translationFile, null, $value); + } + } + } + return $result; + } + + /** + * @param string $languageKey + */ + public function setLanguage(string $languageKey) + { + $this->languageKey = $languageKey; + } + + /** + * @return string + */ + public function getLanguage(): string + { + return $this->languageKey; + } + + /** + * @param array $translationKeyChain + * @param string $language + * @param array $arguments + * @return string|null + */ + protected function processTranslationChain( + array $translationKeyChain, + string $language = null, + array $arguments = null + ) { + $translatedValue = null; + foreach ($translationKeyChain as $translationKey) { + $translatedValue = $this->translate($translationKey, $arguments, null, $language); + if (!empty($translatedValue)) { + break; + } + } + return $translatedValue; + } + + /** + * @param string $locallangPathAndFilename + */ + protected function initializeLocalization(string $locallangPathAndFilename) + { + if (empty($this->languageKey)) { + $this->setLanguageKeys(); + } + + if (!empty($locallangPathAndFilename)) { + /** @var $languageFactory LocalizationFactory */ + $languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class); + $this->LOCAL_LANG = $languageFactory->getParsedData($locallangPathAndFilename, $this->languageKey, 'utf-8'); + + foreach ($this->alternativeLanguageKeys as $language) { + $tempLL = $languageFactory->getParsedData($locallangPathAndFilename, $language, 'utf-8'); + if ($this->languageKey !== 'default' && isset($tempLL[$language])) { + $this->LOCAL_LANG[$language] = $tempLL[$language]; + } + } + } + $this->loadTypoScriptLabels(); + } + + /** + * Sets the currently active language/language_alt keys. + * Default values are "default" for language key and "" for language_alt key. + */ + protected function setLanguageKeys() + { + $this->languageKey = 'default'; + + $this->alternativeLanguageKeys = []; + if (TYPO3_MODE === 'FE') { + if (isset($this->getTypoScriptFrontendController()->config['config']['language'])) { + $this->languageKey = $this->getTypoScriptFrontendController()->config['config']['language']; + if (isset($this->getTypoScriptFrontendController()->config['config']['language_alt'])) { + $this->alternativeLanguageKeys[] = $this->getTypoScriptFrontendController()->config['config']['language_alt']; + } else { + /** @var $locales \TYPO3\CMS\Core\Localization\Locales */ + $locales = GeneralUtility::makeInstance(Locales::class); + if (in_array($this->languageKey, $locales->getLocales(), true)) { + foreach ($locales->getLocaleDependencies($this->languageKey) as $language) { + $this->alternativeLanguageKeys[] = $language; + } + } + } + } + } elseif (!empty($GLOBALS['BE_USER']->uc['lang'])) { + $this->languageKey = $GLOBALS['BE_USER']->uc['lang']; + } elseif (!empty($this->getLanguageService()->lang)) { + $this->languageKey = $this->getLanguageService()->lang; + } + } + + /** + * Overwrites labels that are set via TypoScript. + * TS locallang labels have to be configured like: + * plugin.tx_form._LOCAL_LANG.languageKey.key = value + */ + protected function loadTypoScriptLabels() + { + $frameworkConfiguration = $this->getConfigurationManager() + ->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, 'form'); + + if (!is_array($frameworkConfiguration['_LOCAL_LANG'])) { + return; + } + $this->LOCAL_LANG_UNSET = []; + foreach ($frameworkConfiguration['_LOCAL_LANG'] as $languageKey => $labels) { + if (!(is_array($labels) && isset($this->LOCAL_LANG[$languageKey]))) { + continue; + } + foreach ($labels as $labelKey => $labelValue) { + if (is_string($labelValue)) { + $this->LOCAL_LANG[$languageKey][$labelKey][0]['target'] = $labelValue; + if ($labelValue === '') { + $this->LOCAL_LANG_UNSET[$languageKey][$labelKey] = ''; + } + } elseif (is_array($labelValue)) { + $labelValue = $this->flattenTypoScriptLabelArray($labelValue, $labelKey); + foreach ($labelValue as $key => $value) { + $this->LOCAL_LANG[$languageKey][$key][0]['target'] = $value; + if ($value === '') { + $this->LOCAL_LANG_UNSET[$languageKey][$key] = ''; + } + } + } + } + } + } + + /** + * Flatten TypoScript label array; converting a hierarchical array into a flat + * array with the keys separated by dots. + * + * Example Input: array('k1' => array('subkey1' => 'val1')) + * Example Output: array('k1.subkey1' => 'val1') + * + * @param array $labelValues Hierarchical array of labels + * @param string $parentKey the name of the parent key in the recursion; is only needed for recursion. + * @return array flattened array of labels. + */ + protected function flattenTypoScriptLabelArray(array $labelValues, string $parentKey = ''): array + { + $result = []; + foreach ($labelValues as $key => $labelValue) { + if (!empty($parentKey)) { + $key = $parentKey . '.' . $key; + } + if (is_array($labelValue)) { + $labelValue = $this->flattenTypoScriptLabelArray($labelValue, $key); + $result = array_merge($result, $labelValue); + } else { + $result[$key] = $labelValue; + } + } + return $result; + } + + /** + * If the array contains numerical keys only, sort it in descending order + * + * @param array $array + * @return array + */ + protected function sortArrayWithIntegerKeysDescending(array $array) + { + if (count(array_filter(array_keys($array), 'is_string')) === 0) { + krsort($array); + } + return $array; + } + + /** + * Returns instance of the configuration manager + * + * @return ConfigurationManagerInterface + */ + protected function getConfigurationManager(): ConfigurationManagerInterface + { + if ($this->configurationManager !== null) { + return $this->configurationManager; + } + + $this->configurationManager = GeneralUtility::makeInstance(ObjectManager::class) + ->get(ConfigurationManagerInterface::class); + return $this->configurationManager; + } + + /** + * @return LanguageService + */ + protected function getLanguageService(): LanguageService + { + return $GLOBALS['LANG']; + } + + /** + * @return TypoScriptFrontendController + */ + protected function getTypoScriptFrontendController(): TypoScriptFrontendController + { + return $GLOBALS['TSFE']; + } +} diff --git a/Classes/ViewHelpers/Be/DashboardWidget/EditOnClickViewHelper.php b/Classes/ViewHelpers/Be/DashboardWidget/EditOnClickViewHelper.php index ba82d08..82b6764 100644 --- a/Classes/ViewHelpers/Be/DashboardWidget/EditOnClickViewHelper.php +++ b/Classes/ViewHelpers/Be/DashboardWidget/EditOnClickViewHelper.php @@ -1,5 +1,5 @@ getUid() . ']=edit'); + $editOnClick = \TYPO3\CMS\Backend\Utility\BackendUtility::editOnClick('&edit[tx_dashboard_domain_model_widget][' . $widget->getUid() . ']=edit'); return $editOnClick; } } diff --git a/Classes/ViewHelpers/Be/DashboardWidget/GridAttributesViewHelper.php b/Classes/ViewHelpers/Be/DashboardWidget/GridAttributesViewHelper.php index ab3dfc4..b0d86f4 100644 --- a/Classes/ViewHelpers/Be/DashboardWidget/GridAttributesViewHelper.php +++ b/Classes/ViewHelpers/Be/DashboardWidget/GridAttributesViewHelper.php @@ -1,5 +1,5 @@ getWidgetIdentifier(); - $widget = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$widgetIdentifier]; + $widget = $widgetSetting->getSettings(); list($width, $height) = explode('x', $widget['size']); $width = $this->getItemWidth((int)$width, $numberOfCols); $height = $this->getItemHeight((int)$height); @@ -73,8 +71,8 @@ public function render($widgetSetting, $index, $className = 'grid-item') /** * Returns the correct grid item width * - * @param integer $width - * @param integer $numberOfCols + * @param int $width + * @param int $numberOfCols * @return string css class name */ protected function getItemWidth($width, $numberOfCols) @@ -92,7 +90,7 @@ protected function getItemWidth($width, $numberOfCols) /** * Returns the correct grid item height * - * @param integer $height + * @param int $height * @return string css class name */ protected function getItemHeight($height) diff --git a/Classes/ViewHelpers/Be/DashboardWidget/IconSrcViewHelper.php b/Classes/ViewHelpers/Be/DashboardWidget/IconViewHelper.php similarity index 62% rename from Classes/ViewHelpers/Be/DashboardWidget/IconSrcViewHelper.php rename to Classes/ViewHelpers/Be/DashboardWidget/IconViewHelper.php index 063bdac..c347612 100644 --- a/Classes/ViewHelpers/Be/DashboardWidget/IconSrcViewHelper.php +++ b/Classes/ViewHelpers/Be/DashboardWidget/IconViewHelper.php @@ -1,5 +1,5 @@ getSettings(); + return $widgetSettings['icon'] ?? $defaultIcon; } } diff --git a/Classes/ViewHelpers/Be/DashboardWidget/SizeViewHelper.php b/Classes/ViewHelpers/Be/DashboardWidget/SizeViewHelper.php index ec7fb4e..a13522e 100644 --- a/Classes/ViewHelpers/Be/DashboardWidget/SizeViewHelper.php +++ b/Classes/ViewHelpers/Be/DashboardWidget/SizeViewHelper.php @@ -1,5 +1,5 @@ getSettings(); list($width, $height) = explode('x', $widget['size']); - return $this->getColumnClassName((int)$width) . " " . $this->getHeightClassName((int)$height); + return $this->getColumnClassName((int)$width) . ' ' . $this->getHeightClassName((int)$height); } /** diff --git a/Classes/ViewHelpers/Be/DashboardWidgetViewHelper.php b/Classes/ViewHelpers/Be/DashboardWidgetViewHelper.php index e81c517..6df225b 100644 --- a/Classes/ViewHelpers/Be/DashboardWidgetViewHelper.php +++ b/Classes/ViewHelpers/Be/DashboardWidgetViewHelper.php @@ -1,80 +1,25 @@ - * - * - * - * List of all "Website user" records stored in the configured storage PID. - * Records will be editable, if the current BE user has got edit rights for the table "fe_users". - * Only the title column (username) will be shown. - * Context menu is active. - * - * - * - * - * - * - * List of "Website user" records with a text property of "foo" stored on PID 1 and two levels down. - * Clicking on a username will open the TYPO3 info popup for the respective record - * - */ class DashboardWidgetViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper { - - /** - * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface - * @inject - */ - protected $configurationManager; - /** * Renders a record list as known from the TYPO3 list module * Note: This feature is experimental! * - * @param \TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings $dashboardWidgetSetting + * @param \Pixelant\Dashboard\Domain\Model\Widget $widget * @return string the rendered content * @see \TYPO3\CMS\Recordlist\RecordList\DatabaseRecordList */ - public function render($dashboardWidgetSetting) + public function render($widget) { - $pageinfo = \TYPO3\CMS\Backend\Utility\BackendUtility::readPageAccess( - \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id'), - $GLOBALS['BE_USER']->getPagePermsClause(1) - ); - $widget = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$dashboardWidgetSetting->getWidgetIdentifier()]; - $widgetClassName = $widget['class']; + $widgetSettings = $widget->getSettings(); + $widgetClassName = $widgetSettings['class']; if (class_exists($widgetClassName)) { - $widgetClass = $this->objectManager->get($widgetClassName); - return $widgetClass->render($dashboardWidgetSetting); - } else { - return 'Class : ' . $widgetClassName .' could not be found!'; + $widgetController = $this->objectManager->get($widgetClassName); + return $widgetController->render($widget); } + return 'Class : ' . htmlspecialchars($widgetClassName) . ' could not be found!'; } } diff --git a/Classes/DashboardWidgets/ActionWidget.php b/Classes/Widget/ActionWidgetController.php similarity index 83% rename from Classes/DashboardWidgets/ActionWidget.php rename to Classes/Widget/ActionWidgetController.php index 47e4b32..ee72df5 100644 --- a/Classes/DashboardWidgets/ActionWidget.php +++ b/Classes/Widget/ActionWidgetController.php @@ -1,5 +1,5 @@ initialize($dashboardWidgetSetting); - $content = $this->generateContent(); - return $content; + $this->initialize($widget); + return $this->generateContent(); } /** * Initializes settings from flexform - * @param \TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings $dashboardWidgetSetting + * + * @param Widget $widget * @return void */ - private function initialize($dashboardWidgetSetting = null) + private function initialize($widget = null) { - $flexformSettings = $this->getFlexFormSettings($dashboardWidgetSetting); - $this->limit = (int)$flexformSettings['settings']['limit']; - $this->widget = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$dashboardWidgetSetting->getWidgetIdentifier()]; + $settings = $widget->getSettings(); + $this->limit = (int)$settings['limit']; + $this->widget = $settings; } /** * Generates the content + * @throws \Exception * @return string - * @throws 1910010001 */ private function generateContent() { if (!ExtensionManagementUtility::isLoaded('sys_action')) { - throw new \Exception("Extension sys_actions is not enabled", 1910010001); + throw new \Exception('Extension sys_actions is not enabled', 1910010001); } - $actionEntries = []; $widgetTemplateName = $this->widget['template']; $actionView = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class) ->get(StandaloneView::class); @@ -154,7 +160,7 @@ protected function getActions() . '&SET[function]=sys_action.' . \TYPO3\CMS\SysAction\ActionTask::class . '&show=' - . (int)$actionRow['uid'] + . (int)$actionRow['uid'], ]; } diff --git a/Classes/DashboardWidgets/IframeWidget.php b/Classes/Widget/IframeWidgetController.php similarity index 65% rename from Classes/DashboardWidgets/IframeWidget.php rename to Classes/Widget/IframeWidgetController.php index 6d326c6..6d06953 100644 --- a/Classes/DashboardWidgets/IframeWidget.php +++ b/Classes/Widget/IframeWidgetController.php @@ -1,5 +1,5 @@ initialize($dashboardWidgetSetting); - $content = $this->generateContent(); - return $content; + $this->initialize($widget); + return $this->generateContent(); } /** * Initializes settings from flexform - * @param DashboardWidgetSettings $dashboardWidgetSetting + * + * @param Widget $widget * @return void */ - private function initialize($dashboardWidgetSetting = null) + private function initialize($widget = null) { - $flexformSettings = $this->getFlexFormSettings($dashboardWidgetSetting); - $this->url = $flexformSettings['settings']['url']; - $this->scrolling = $flexformSettings['settings']['scrolling']; - $this->widget = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$dashboardWidgetSetting->getWidgetIdentifier()]; + $settings = $widget->getSettings(); + $this->url = $settings['url']; + $this->scrolling = $settings['scrolling']; + $this->widget = $settings; } /** @@ -80,10 +79,10 @@ private function generateContent() $actionView = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager')->get('TYPO3\\CMS\\Fluid\\View\\StandaloneView'); $template = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($widgetTemplateName); $actionView->setTemplatePathAndFilename($template); - $actionView->assignMultiple(array( + $actionView->assignMultiple([ 'url' => $this->url, - 'scrolling' => $this->scrolling - )); + 'scrolling' => $this->scrolling, + ]); return $actionView->render(); } } diff --git a/Classes/Widget/RssWidgetController.php b/Classes/Widget/RssWidgetController.php new file mode 100644 index 0000000..29a747c --- /dev/null +++ b/Classes/Widget/RssWidgetController.php @@ -0,0 +1,230 @@ +initialize($widget); + if ($this->cacheLifetime > 0) { + $content = $this->generateContent(); + } else { + /** @var \TYPO3\CMS\Core\Cache\CacheManager $cacheManager */ + $cacheManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager')->get('TYPO3\\CMS\\Core\\Cache\\CacheManager'); + $cacheIdentifier = 'dashboardWidget_' . (int)$widget->getUid(); + + if (true === $cacheManager->hasCache('dashboard') && true === $cacheManager->getCache('dashboard')->has($cacheIdentifier)) { + $content = $cacheManager->getCache('dashboard')->get($cacheIdentifier); + } else { + $content = $this->generateContent(); + $cacheManager->getCache('dashboard')->set($cacheIdentifier, $content, [], $this->cacheLifetime); + } + unset($cacheManager); + } + return $content; + } + + /** + * Initializes settings from flexform + * @param Widget $widget + * @return void + */ + private function initialize($widget = null) + { + $settings = $widget->getSettings(); + $this->feedUrl = $settings['feedUrl']; + $this->feedLimit = (int)$settings['feedLimit']; + $this->cacheLifetime = (int)$settings['cacheLifetime'] * 60; + $this->widget = $settings; + } + + /** + * Generates the content + * @return string + */ + private function generateContent() + { + $widgetTemplateName = $this->widget['template']; + $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); + $rssView = $objectManager->get('TYPO3\\CMS\\Fluid\\View\\StandaloneView'); + $template = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($widgetTemplateName); + $rssView->setTemplatePathAndFilename($template); + $feed = $this->getFeed(); + $rssView->assign('feed', $feed); + $rssView->assign('currentdate', time()); + $rssView->assign('cacheLifetime', $this->cacheLifetime); + return $rssView->render(); + } + + /** + * Loads feed and cuts unneeded items + * + * @return array Array from xml + */ + private function getFeed() + { + $feed = []; + $report = []; + if (\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($this->feedUrl)) { + $content = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl( + $this->feedUrl, + 0, + null, + $report + ); + if (!$content) { + if (isset($report['message'])) { + throw new \Exception($report['message'], $report['error']); + } + throw new \Exception('The response was empty', 1910020001); + } + if (!empty($content)) { + $simpleXmlElement = simplexml_load_string($content, 'SimpleXMLElement'); + if (!$simpleXmlElement) { + throw new \Exception('The response is not valid XML', 1910020003); + } + $feed['channel'] = $this->rssToArray($simpleXmlElement); + if ((int)$this->feedLimit > 0) { + $feed['channel']['item'] = array_splice($feed['channel']['item'], 0, $this->feedLimit); + } + } else { + throw new \Exception('An error occured', 1910020002); + } + } else { + throw new \Exception('The provided url is not valid', 1910020004); + } + return $feed; + } + + /** + * rssToArray RSS to array from a SimpleXMLElement + * @param \SimpleXmlElement $simpleXmlElement + * @return array + */ + private function rssToArray($simpleXmlElement) + { + $rss2Array = []; + $rss2Array = $this->sxeToArray($simpleXmlElement->channel); + foreach ($simpleXmlElement->channel->item as $simpleXmlElementItem) { + $simpleXmlElementArray = $this->sxeToArray($simpleXmlElementItem); + if ($simpleXmlElementArray) { + $rss2Array['item'][] = $simpleXmlElementArray; + } + } + return $rss2Array; + } + + /** + * sxeToArray Generates the base array for the element, also includes namespaces. + * @param \SimpleXMLElement $simpleXmlElement The element to create an array of + * @return array + */ + private function sxeToArray($simpleXmlElement) + { + $returnArray = false; + $children = $simpleXmlElement->children(); + $sxeChildrenToArray = $this->sxeChildrenToArray($children); + if ($sxeChildrenToArray) { + $returnArray = $sxeChildrenToArray; + } + $namespaces = $simpleXmlElement->getNamespaces(true); + foreach ($namespaces as $ns => $nsuri) { + $children = $simpleXmlElement->children($ns, true); + $sxeChildrenToArray = $this->sxeChildrenToArray($children); + if ($sxeChildrenToArray) { + $returnArray[$ns] = $sxeChildrenToArray; + } + } + return $returnArray; + } + + /** + * sxeChildrenToArray Returns an array of the elements children and attributes recursively + * @param mixed $children The children of a element + * @return array + */ + private function sxeChildrenToArray($children) + { + $nodeData = []; + if (count($children) > 0) { + foreach ($children as $elementName => $node) { + $nodeName = $this->stringToArrayKey((string)$elementName); + $nodeData[$nodeName] = []; + $nodeAttributes = $node->attributes(); + if (count($nodeAttributes) > 0) { + foreach ($nodeAttributes as $nodeAttributeName => $nodeAttributeValue) { + $arrayKey = $this->stringToArrayKey((string)$nodeAttributeName); + $arrayValue = trim((string)$nodeAttributeValue->__toString()); + $nodeData[$nodeName][$arrayKey] = $arrayValue; + } + } + $nodeValue = trim((string)$node); + if (strlen($nodeValue) > 0) { + if (count($nodeAttributes) == 0) { + $nodeData[$nodeName] = $nodeValue; + } else { + $nodeData[$nodeName]['value'] = $nodeValue; + } + } else { + if ($nodeName != 'item') { + $childs = $this->sxeToArray($node); + if ($childs) { + $nodeData[$nodeName] = $childs; + } + } + } + } + return $nodeData; + } + return false; + } + + /** + * stringToArrayKey Returns a string which is ok to use as array key + * @param string $key The array key to check + * @return string + */ + private function stringToArrayKey($key) + { + return str_replace('.', '_', trim((string)$key)); + } +} diff --git a/Classes/DashboardWidgets/SysNewsWidget.php b/Classes/Widget/SysNewsWidgetController.php similarity index 74% rename from Classes/DashboardWidgets/SysNewsWidget.php rename to Classes/Widget/SysNewsWidgetController.php index 6cf3086..3903828 100644 --- a/Classes/DashboardWidgets/SysNewsWidget.php +++ b/Classes/Widget/SysNewsWidgetController.php @@ -1,5 +1,5 @@ initialize($dashboardWidgetSetting); - $content = $this->generateContent(); - return $content; + $this->initialize($widget); + return $this->generateContent(); } /** * Initializes settings from flexform - * @param \TYPO3\CMS\Dashboard\Domain\Model\DashboardWidgetSettings $dashboardWidgetSetting + * + * @param Widget $widget * @return void */ - private function initialize($dashboardWidgetSetting = null) + private function initialize($widget = null) { - $flexformSettings = $this->getFlexFormSettings($dashboardWidgetSetting); - $this->limit = (int)$flexformSettings['settings']['limit']; - $this->widget = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dashboard']['widgets'][$dashboardWidgetSetting->getWidgetIdentifier()]; + $settings = $widget->getSettings(); + $this->limit = (int)$settings['limit']; + $this->widget = $settings; } /** @@ -77,7 +84,7 @@ private function generateContent() protected function getSystemNews() { $systemNewsTable = 'sys_news'; - $systemNews = array(); + $systemNews = []; $systemNewsRecords = $this->getDatabaseConnection()->exec_SELECTgetRows( 'title, content, crdate', $systemNewsTable, @@ -87,11 +94,11 @@ protected function getSystemNews() $this->getLimit() ); foreach ($systemNewsRecords as $systemNewsRecord) { - $systemNews[] = array( + $systemNews[] = [ 'date' => $systemNewsRecord['crdate'], 'header' => $systemNewsRecord['title'], - 'content' => $systemNewsRecord['content'] - ); + 'content' => $systemNewsRecord['content'], + ]; } return $systemNews; } diff --git a/Classes/Widget/WidgetControllerInterface.php b/Classes/Widget/WidgetControllerInterface.php new file mode 100644 index 0000000..8cec8cc --- /dev/null +++ b/Classes/Widget/WidgetControllerInterface.php @@ -0,0 +1,15 @@ + [ - 'title' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboard', + 'title' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboard', 'label' => 'title', 'tstamp' => 'tstamp', 'crdate' => 'crdate', @@ -18,14 +18,14 @@ 'starttime' => 'starttime', 'endtime' => 'endtime', ], - 'searchFields' => 'title,description,dashboard_widget_settings,beuser,', - 'iconfile' => 'EXT:dashboard/Resources/Public/Icons/tx_dashboard_domain_model_dashboard.gif' + 'searchFields' => 'title,description,widgets,beuser,', + 'iconfile' => 'EXT:dashboard/Resources/Public/Icons/tx_dashboard_domain_model_dashboard.gif', ], 'interface' => [ - 'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, title, description, dashboard_widget_settings, beuser', + 'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, title, description, widgets, beuser', ], 'types' => [ - '1' => ['showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, title, description, dashboard_widget_settings, beuser, --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access, starttime, endtime'], + '1' => ['showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, title, description, widgets, beuser, --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access, starttime, endtime'], ], 'palettes' => [ '1' => ['showitem' => ''], @@ -48,7 +48,7 @@ 'items' => [ [ '', - 0 + 0, ], ], 'foreign_table' => 'tx_dashboard_domain_model_dashboard', @@ -66,7 +66,6 @@ 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden', 'config' => [ 'type' => 'check', - ], ], 'starttime' => [ @@ -81,7 +80,7 @@ 'checkbox' => 0, 'default' => 0, 'range' => [ - 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) + 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), ], ], ], @@ -97,7 +96,7 @@ 'checkbox' => 0, 'default' => 0, 'range' => [ - 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) + 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), ], ], ], @@ -107,7 +106,7 @@ 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'trim,required' + 'eval' => 'trim,required', ], ], 'description' => [ @@ -116,26 +115,19 @@ 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'trim' + 'eval' => 'trim', ], ], - 'dashboard_widget_settings' => [ + 'widgets' => [ 'exclude' => 1, - 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboard.dashboard_widget_settings', + 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboard.widgets', 'config' => [ - 'type' => 'inline', - 'foreign_table' => 'tx_dashboard_domain_model_dashboardwidgetsettings', + 'type' => 'select', + 'renderType' => 'selectMultipleSideBySide', + 'foreign_table' => 'tx_dashboard_domain_model_widget', 'foreign_field' => 'dashboard', 'foreign_sortby' => 'sorting', - 'MM_opposite_field' => 'dashboard', 'maxitems' => 9999, - 'appearance' => [ - 'collapseAll' => 1, - 'levelLinksPosition' => 'top', - 'showSynchronizationLink' => 1, - 'showPossibleLocalizationRecords' => 1, - 'showAllLocalizationLink' => 1 - ], ], ], 'beuser' => [ @@ -152,7 +144,7 @@ 'levelLinksPosition' => 'top', 'showSynchronizationLink' => 1, 'showPossibleLocalizationRecords' => 1, - 'showAllLocalizationLink' => 1 + 'showAllLocalizationLink' => 1, ], ], ], diff --git a/Configuration/TCA/tx_dashboard_domain_model_dashboardwidgetsettings.php b/Configuration/TCA/tx_dashboard_domain_model_widget.php similarity index 69% rename from Configuration/TCA/tx_dashboard_domain_model_dashboardwidgetsettings.php rename to Configuration/TCA/tx_dashboard_domain_model_widget.php index dfc180c..f37dbb9 100644 --- a/Configuration/TCA/tx_dashboard_domain_model_dashboardwidgetsettings.php +++ b/Configuration/TCA/tx_dashboard_domain_model_widget.php @@ -1,7 +1,7 @@ [ - 'title' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboardwidgetsettings', + 'title' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_widget', 'label' => 'title', 'tstamp' => 'tstamp', 'crdate' => 'crdate', @@ -13,21 +13,21 @@ 'transOrigDiffSourceField' => 'l10n_diffsource', 'delete' => 'deleted', 'enablecolumns' => [], + 'requestUpdate' => 'widget_identifier', 'searchFields' => 'title,widget_identifier,position,settings_flexform,', - 'iconfile' => 'EXT:dashboard/Resources/Public/Icons/tx_dashboard_domain_model_dashboardwidgetsettings.gif' - + 'iconfile' => 'EXT:dashboard/Resources/Public/Icons/tx_dashboard_domain_model_widget.gif', ], 'interface' => [ 'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, title, widget_identifier, position, settings_flexform, dashboard, x, y, width, height', ], 'types' => [ '1' => [ - 'showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, title, widget_identifier, position, settings_flexform, dashboard, x, y, width, height, ' + 'showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, widget_identifier, title, position, settings_flexform, dashboard', ], ], 'palettes' => [ '1' => [ - 'showitem' => '' + 'showitem' => '', ], ], 'columns' => [ @@ -48,8 +48,8 @@ 'items' => [ ['', 0], ], - 'foreign_table' => 'tx_dashboard_domain_model_dashboardwidgetsettings', - 'foreign_table_where' => 'AND tx_dashboard_domain_model_dashboardwidgetsettings.pid=###CURRENT_PID### AND tx_dashboard_domain_model_dashboardwidgetsettings.sys_language_uid IN (-1,0)', + 'foreign_table' => 'tx_dashboard_domain_model_widget', + 'foreign_table_where' => 'AND tx_dashboard_domain_model_widget.pid=###CURRENT_PID### AND tx_dashboard_domain_model_widget.sys_language_uid IN (-1,0)', ], ], 'l10n_diffsource' => [ @@ -60,16 +60,16 @@ 'title' => [ 'exclude' => 1, - 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboardwidgetsettings.title', + 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_widget.title', 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'trim' + 'eval' => 'trim', ], ], 'widget_identifier' => [ 'exclude' => 1, - 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboardwidgetsettings.widget_identifier', + 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_widget.widget_identifier', 'config' => [ 'type' => 'select', 'readOnly' => 1, @@ -77,23 +77,23 @@ 'items' => [ [ '-- Label --', - '0' + '0', ], [ 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:dashboardWidget.rsswidget.name', - \TYPO3\CMS\Dashboard\DashboardWidgets\RssWidget::IDENTIFIER + \Pixelant\Dashboard\Widget\RssWidgetController::IDENTIFIER, ], [ 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:dashboardWidget.actionwidget.name', - \TYPO3\CMS\Dashboard\DashboardWidgets\ActionWidget::IDENTIFIER + \Pixelant\Dashboard\Widget\ActionWidgetController::IDENTIFIER, ], [ 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:dashboardWidget.sysnewswidget.name', - \TYPO3\CMS\Dashboard\DashboardWidgets\SysNewsWidget::IDENTIFIER + \Pixelant\Dashboard\Widget\SysNewsWidgetController::IDENTIFIER, ], [ 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:dashboardWidget.iframe.name', - \TYPO3\CMS\Dashboard\DashboardWidgets\IframeWidget::IDENTIFIER + \Pixelant\Dashboard\Widget\IframeWidgetController::IDENTIFIER, ], ], 'size' => 1, @@ -109,7 +109,7 @@ 'type' => 'input', 'readOnly' => 1, 'size' => 30, - 'eval' => 'int' + 'eval' => 'int', ], ], 'y' => [ @@ -117,9 +117,9 @@ 'label' => 'y', 'config' => [ 'type' => 'input', - 'readOnly' => 1, + 'readOnly' => 1, 'size' => 30, - 'eval' => 'int' + 'eval' => 'int', ], ], 'width' => [ @@ -127,9 +127,9 @@ 'label' => 'width', 'config' => [ 'type' => 'input', - 'readOnly' => 1, + 'readOnly' => 1, 'size' => 30, - 'eval' => 'int' + 'eval' => 'int', ], ], 'height' => [ @@ -137,27 +137,28 @@ 'label' => 'height', 'config' => [ 'type' => 'input', - 'readOnly' => 1, + 'readOnly' => 1, 'size' => 30, - 'eval' => 'int' + 'eval' => 'int', ], ], 'settings_flexform' => [ 'exclude' => 1, - 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboardwidgetsettings.settings_flexform', + 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_widget.settings_flexform', 'config' => [ 'type' => 'flex', 'ds_pointerField' => 'widget_identifier', 'ds' => [ - \TYPO3\CMS\Dashboard\DashboardWidgets\RssWidget::IDENTIFIER => 'FILE:EXT:dashboard/Configuration/FlexForms/flexform_rsswidget.xml', - \TYPO3\CMS\Dashboard\DashboardWidgets\ActionWidget::IDENTIFIER => 'FILE:EXT:dashboard/Configuration/FlexForms/flexform_actionwidget.xml', - \TYPO3\CMS\Dashboard\DashboardWidgets\SysNewsWidget::IDENTIFIER => 'FILE:EXT:dashboard/Configuration/FlexForms/flexform_sysnewswidget.xml', - \TYPO3\CMS\Dashboard\DashboardWidgets\IframeWidget::IDENTIFIER => 'FILE:EXT:dashboard/Configuration/FlexForms/flexform_iframewidget.xml', + \Pixelant\Dashboard\Widget\RssWidgetController::IDENTIFIER => 'FILE:EXT:dashboard/Configuration/FlexForms/flexform_rsswidget.xml', + \Pixelant\Dashboard\Widget\ActionWidgetController::IDENTIFIER => 'FILE:EXT:dashboard/Configuration/FlexForms/flexform_actionwidget.xml', + \Pixelant\Dashboard\Widget\SysNewsWidgetController::IDENTIFIER => 'FILE:EXT:dashboard/Configuration/FlexForms/flexform_sysnewswidget.xml', + \Pixelant\Dashboard\Widget\IframeWidgetController::IDENTIFIER => 'FILE:EXT:dashboard/Configuration/FlexForms/flexform_iframewidget.xml', 'default' => 'arraynone', ], ], ], 'dashboard' => [ + 'label' => 'LLL:EXT:dashboard/Resources/Private/Language/locallang_db.xlf:tx_dashboard_domain_model_dashboard', 'config' => [ 'type' => 'select', 'renderType' => 'selectSingle', diff --git a/Configuration/TypoScript/setup.txt b/Configuration/TypoScript/setup.txt index 1e92990..14b0f1a 100644 --- a/Configuration/TypoScript/setup.txt +++ b/Configuration/TypoScript/setup.txt @@ -15,14 +15,4 @@ module.tx_dashboard { default = {$module.tx_dashboard.view.layoutRootPath} } } - - settings { - stylesheets { - #gridList = EXT:dashboard/Resources/Public/Css/jquery.gridList.css - } - includeJsFiles { - #gridList = EXT:dashboard/Resources/Public/JavaScript/jquery.gridList.js - #draggableGridList = EXT:dashboard/Resources/Public/JavaScript/jquery.draggableGridList.js - } - } } diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf index 90dfdbf..4eda979 100644 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -24,29 +24,29 @@ Description - - Dashboard Widget Settings + + Widgets Beuser - - Dashboard Widget Settings + + Widget - + Title - + Widget Identifier - + State - + Position - - Settings Flexform + + Widget Settings Dashboard Widgets @@ -63,7 +63,7 @@ Message - + Add new widget @@ -90,9 +90,6 @@ An iframe module - - Dashboard Settings - No actions found diff --git a/Resources/Private/Language/locallang_csh_tx_dashboard_domain_model_dashboard.xlf b/Resources/Private/Language/locallang_csh_tx_dashboard_domain_model_dashboard.xlf index 20f1fb9..26f6572 100644 --- a/Resources/Private/Language/locallang_csh_tx_dashboard_domain_model_dashboard.xlf +++ b/Resources/Private/Language/locallang_csh_tx_dashboard_domain_model_dashboard.xlf @@ -9,8 +9,8 @@ Description - - Widgets Settings + + Widgets Widgets diff --git a/Resources/Private/Language/locallang_db.xlf b/Resources/Private/Language/locallang_db.xlf index d0ea3d5..891bad2 100644 --- a/Resources/Private/Language/locallang_db.xlf +++ b/Resources/Private/Language/locallang_db.xlf @@ -12,29 +12,29 @@ Description - - Dashboard Widget Settings + + Widgets Beuser - - Dashboard Widget Settings + + Widget - + Title - - Widget Identifier + + Widget Type - + State - + Position - - Settings Flexform + + Widget Settings Dashboard Widgets diff --git a/Resources/Private/Templates/Dashboard/Index.html b/Resources/Private/Templates/Dashboard/Index.html index 1dd61d3..ba8db25 100644 --- a/Resources/Private/Templates/Dashboard/Index.html +++ b/Resources/Private/Templates/Dashboard/Index.html @@ -1,13 +1,14 @@ -{namespace d=TYPO3\CMS\Dashboard\ViewHelpers} +{namespace d=Pixelant\Dashboard\ViewHelpers} - +