Skip to content
Snippets Groups Projects
TsrefController.php 14 KiB
Newer Older
damjan's avatar
damjan committed
<?php
damjan's avatar
damjan committed
namespace SGalinski\TypoScriptReferenceFrontend\Controller;

/*                                                                        *
 * This script belongs to the TYPO3 Flow package "SGalinski.TypoScriptReferenceFrontend".*
 *                                                                        *
 *                                                                        */

use SGalinski\TypoScriptReferenceFrontend\Domain\Model\Attribute;
use SGalinski\TypoScriptReferenceFrontend\Service\TsrefRestService;
damjan's avatar
damjan committed
use SGalinski\TypoScriptReferenceFrontend\Utilities\Conversion;
damjan's avatar
damjan committed
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Error\Message;
use TYPO3\Flow\Http\Response;
use TYPO3\Flow\Security\Context;
use TYPO3\Flow\Session\SessionInterface;
damjan's avatar
damjan committed

class TsrefController extends \TYPO3\Flow\Mvc\Controller\ActionController {
damjan's avatar
damjan committed
	/**
	 * @var TsrefRestService
	 */
	protected $tsrefRestService;

	 * @Flow\Inject
	 * @var Context
	/**
	 * @var SessionInterface
	 */
	protected $session;

	/**
	 * The constructor is used for dependency injection.
	 *
	 * @param TsrefRestService $service
	 * @param SessionInterface $session
	public function __construct(TsrefRestService $service, SessionInterface $session) {
		$this->tsrefRestService = $service;
		$this->session = $session;
		if (!$session->isStarted()) {
			$session->start();
			$session->putData('typoScriptGroup', Attribute::NORMAL_GROUP);
			$session->putData('typo3Version', TsrefRestService::TYPO3_CURRENT_VERSION_LABEL);
		}
	 * The action which fetches the data for typoScript reference page, and displays the page.
	 * @param string $typeUrlName - typeUrlName
damjan's avatar
damjan committed
	 * @param string $typo3Version
damjan's avatar
damjan committed
	 */
	public function indexAction(
		$typeUrlName = NULL, $typo3Version = TsrefRestService::TYPO3_CURRENT_VERSION_LABEL
damjan's avatar
damjan committed
		try {
			if ($typeUrlName !== NULL) {
				$selectedType = $this->tsrefRestService->getTypeByUrlName($typeUrlName);
				$this->session->putData('typoScriptGroup', $selectedType->typo3Group);
				$properties = $this->tsrefRestService->getPropertiesByParentId(
					$selectedType->id, $this->decodeTypo3Version($typo3Version), $selectedType->typo3Group
				);

				$this->view->assign('properties', $properties);
				$this->view->assign('selectedType', $selectedType);
				$this->view->assign('typo3Groups', $this->tsrefRestService->getAllTypo3Groups());

				// If the type extends a type (superType), the superType name is being fetched among other fields
				if (isset($selectedType->parent_id)) {
					$superType = $this->tsrefRestService->getAttributeById($selectedType->parent_id);
					$this->view->assign('superType', $superType);
				}
damjan's avatar
damjan committed
		} catch (\Exception $exception) {
			$this->addFlashMessage($exception->getMessage(), 'Error', Message::SEVERITY_ERROR);
damjan's avatar
damjan committed

		$urlName = isset($selectedType) ? (isset($selectedType->urlName) ? $selectedType->urlName : NULL) : NULL;
		$this->prepareTypeMenu($urlName, $typo3Version);
damjan's avatar
damjan committed
	}
	 * Adds a new type or saves changes in edited type.
	 *
	 * @param Attribute $theType
damjan's avatar
damjan committed
	 * @param boolean $editForm
damjan's avatar
damjan committed
	 * @param string $typo3Version
	 * @throws \TYPO3\Flow\Mvc\Exception\ForwardException
	 * @return void
	 */
	public function submitTypeAction( //TODO: Use session for typo3Version
damjan's avatar
damjan committed
		Attribute $theType, $editForm = NULL, $typo3Version = TsrefRestService::TYPO3_CURRENT_VERSION_LABEL
damjan's avatar
damjan committed
	) {
damjan's avatar
damjan committed
		try {
			$this->checkEditPermission($typo3Version);
damjan's avatar
damjan committed
			if ($theType->getParent() === -1) {
				$theType->setParent(NULL);
			}
			if ($editForm) {
				$result = $this->tsrefRestService->editAttribute($theType);
			} else {
				$result = $this->tsrefRestService->addNewAttribute($theType);
			}
			$this->addFlashMessage('The type is successfully submitted.', 'Success', Message::SEVERITY_OK);

			// TODO: get edited type and use its urlName to redirect to

		} catch (\Exception $exception) {
			$this->addFlashMessage($exception->getMessage(), 'Error', Message::SEVERITY_ERROR);

			$this->redirect(
				'editType', 'tsref', 'SGalinski.TypoScriptReferenceFrontend',
				['typeId' => $theType->getId(), 'typo3Version' => $typo3Version]
			);
damjan's avatar
damjan committed

damjan's avatar
damjan committed
			'index', 'tsref', 'SGalinski.TypoScriptReferenceFrontend',
			['typeUrlName' => $theType->getUrlName(), 'typo3Version' => $typo3Version]
damjan's avatar
damjan committed
		);
	}

	/**
	 * Prepares and opens the page for adding new / editing the type
	 * @param int $typeId
damjan's avatar
damjan committed
	 * @param string $typo3Version
	 * @return void
	public function editTypeAction($typeId = NULL, $typo3Version = TsrefRestService::TYPO3_CURRENT_VERSION_LABEL
	) { //TODO: Use session for typo3Version
		$theType = new Attribute();
damjan's avatar
damjan committed
		try {
			$this->checkEditPermission($typo3Version);
damjan's avatar
damjan committed
			$typoScriptGroup = (int) $this->session->getData('typoScriptGroup');
damjan's avatar
damjan committed
			if ($typeId !== NULL) {
				// Edit type
				$selectedTypeAsStdClass = $this->tsrefRestService->getAttributeById($typeId);
				$theType->initialiseAttribute($selectedTypeAsStdClass);
			} else {
				$theType->setTypo3Group($typoScriptGroup);
			}

			$selectMenuTypes = $this->tsrefRestService->getTypesWithNull(
				$this->decodeTypo3Version($typo3Version), $typoScriptGroup
			);

			$categories = $this->tsrefRestService->getCategories();
			$selectBoxCategories = Conversion::categoriesToAssociativeNameArray($categories);

			$this->view->assign('typo3Groups', $this->tsrefRestService->getAllTypo3Groups());
			$this->view->assign('theType', $theType);
			$this->view->assign('editForm', ($typeId !== NULL));
			$this->view->assign('selectMenuTypes', $selectMenuTypes);
			$this->view->assign('selectBoxCategories', $selectBoxCategories);
		} catch (\Exception $exception) {
			$this->addFlashMessage($exception->getMessage(), 'Error', Message::SEVERITY_ERROR);
		}
damjan's avatar
damjan committed
		$this->prepareTypeMenu($theType->getUrlName(), $typo3Version);
damjan's avatar
damjan committed

	/**
	 * Adds a new property or saves the changes in edited property.
	 *
	 * @param Attribute $theProperty
	 * @param boolean $editForm
damjan's avatar
damjan committed
	 * @param string $typo3Version
	 * @throws \TYPO3\Flow\Mvc\Exception\ForwardException
	public function submitPropertyAction( //TODO: Use session for typo3Version
		Attribute $theProperty, $editForm, $typo3Version = TsrefRestService::TYPO3_CURRENT_VERSION_LABEL
damjan's avatar
damjan committed
	) {
damjan's avatar
damjan committed
		$parentType = NULL;
		try {
			$this->checkEditPermission($typo3Version);

			if ($editForm) {
				$result = $this->tsrefRestService->editAttribute($theProperty);
			} else {
				$result = $this->tsrefRestService->addNewAttribute($theProperty);
			}
damjan's avatar
damjan committed
			$this->addFlashMessage('The property is successfully submitted.', 'Success', Message::SEVERITY_OK);
			$parentType = $this->tsrefRestService->getAttributeById($theProperty->getParent());

		} catch (\Exception $exception) {
			$this->addFlashMessage($exception->getMessage(), 'Error', Message::SEVERITY_ERROR);

			$this->redirect(
				'editProperty', 'tsref', 'SGalinski.TypoScriptReferenceFrontend',
				['parentTypeId' => $theProperty->getParent(), 'thePropertyId' => $theProperty->getId(),
					'typo3Version' => $typo3Version]
			);
damjan's avatar
damjan committed
		$urlName = (isset($parentType) ? (isset($parentType->urlName) ? $parentType->urlName : NULL) : NULL);
damjan's avatar
damjan committed
			'index', 'tsref', 'SGalinski.TypoScriptReferenceFrontend',
damjan's avatar
damjan committed
			['typeUrlName' => $urlName, 'typo3Version' => $typo3Version]
damjan's avatar
damjan committed
	/**
	 * Prepares and opens the page for adding new / editing the property
	 *
	 * @param int $parentTypeId
	 * @param int $thePropertyId
damjan's avatar
damjan committed
	 * @param string $typo3Version
	 * @return void
damjan's avatar
damjan committed
	 */
	public function editPropertyAction( //TODO: Use session for typo3Version
		$parentTypeId, $thePropertyId = NULL, $typo3Version = TsrefRestService::TYPO3_CURRENT_VERSION_LABEL
damjan's avatar
damjan committed
	) {
damjan's avatar
damjan committed
		$parentType = NULL;
		try {
			$this->checkEditPermission($typo3Version);

			$theProperty = new Attribute();
			$typoScriptGroup = (int) $this->session->getData('typoScriptGroup');

			if ($thePropertyId !== NULL) {
				// Edit type
				$selectedPropertyAsStdClass = $this->tsrefRestService->getAttributeById($thePropertyId);
				$theProperty->initialiseAttribute($selectedPropertyAsStdClass);
			} else {
				$theProperty->setTypo3Group($typoScriptGroup);
			}
damjan's avatar
damjan committed
			$theProperty->setParent($parentTypeId);
			$parentType = $this->tsrefRestService->getAttributeById($parentTypeId);
damjan's avatar
damjan committed
			$selectMenuTypes = Conversion::attributesToAssociativeIdArray(
				$this->tsrefRestService->getTypes(TRUE, $this->decodeTypo3Version($typo3Version), NULL)
			);
damjan's avatar
damjan committed
			$this->view->assign('typo3Groups', $this->tsrefRestService->getAllTypo3Groups());
			$this->view->assign('theProperty', $theProperty);
			$this->view->assign('editForm', ($thePropertyId !== NULL));
			$this->view->assign('selectMenuTypes', $selectMenuTypes);
		} catch (\Exception $exception) {
			$this->addFlashMessage($exception->getMessage(), 'Error', Message::SEVERITY_ERROR);
		}
damjan's avatar
damjan committed
		$urlName = isset($parentType) ? (isset($parentType->urlName) ? $parentType->urlName : NULL) : NULL;
		$this->prepareTypeMenu($urlName, $typo3Version);
damjan's avatar
damjan committed
	}
	/**
	 * Deletes attribute by $attributeId.
	 * If the attribute is a type, $parentTypeUrlName should be NULL.
	 * If the attribute is a property, $parentTypeUrlName should be specified,
	 * and then that type will be presented after deletion of the property.
	 *
	 * @param int $attributeId
	 * @param string $parentTypeUrlName
damjan's avatar
damjan committed
	 * @param string $typo3Version
	 * @return void
	public function deleteAttributeAction( //TODO: Use session for typo3Version
		$attributeId, $parentTypeUrlName = NULL, $typo3Version = TsrefRestService::TYPO3_CURRENT_VERSION_LABEL
damjan's avatar
damjan committed
	) {
damjan's avatar
damjan committed
		try {
			$this->checkEditPermission($typo3Version, $parentTypeUrlName);
			$result = $this->tsrefRestService->patchAttribute($attributeId, ['deleted' => TRUE]);

			$this->addFlashMessage('Successfully deleted.', 'Success', Message::SEVERITY_OK);
		} catch (\Exception $exception) {
			$this->addFlashMessage($exception->getMessage(), 'Error', Message::SEVERITY_ERROR);
		}
damjan's avatar
damjan committed
			'index', 'tsref', 'SGalinski.TypoScriptReferenceFrontend',
			['typeUrlName' => $parentTypeUrlName, 'typo3Version' => $typo3Version]
damjan's avatar
damjan committed
		);
	}

	/**
	 * Submits typo3 version to be used in filtering.
	 *
	 * @param string $submittedTypo3Version
	 * @param int $submittedTypoScriptGroup
damjan's avatar
damjan committed
	 * @throws \TYPO3\Flow\Mvc\Exception\ForwardException
	 * @return void
	 */
	public function submitTypo3VersionAndGroupAction($submittedTypo3Version, $submittedTypoScriptGroup) {
		$this->storeToSession($submittedTypo3Version, $submittedTypoScriptGroup);
damjan's avatar
damjan committed
		$this->redirect(
			'index', 'tsref', 'SGalinski.TypoScriptReferenceFrontend', ['typo3Version' => $submittedTypo3Version]
	/**
	 * Download action for tsref.xml
	 *
	 * @param string $typo3Version
	 * @param int $typoScriptGroup
	 */
	public function downloadTsrefAction(
		$typo3Version = TsrefRestService::TYPO3_CURRENT_VERSION_LABEL, $typoScriptGroup = Attribute::NORMAL_GROUP
damjan's avatar
damjan committed
		try {
			$typo3DecodedVersion = $this->decodeTypo3Version($typo3Version);
			$tsrefXml = $this->tsrefRestService->getTsrefXml($typo3DecodedVersion, $typoScriptGroup);
			$this->response->setContent($tsrefXml);

			$this->response->setHeader('Content-Type', 'xml');
			$this->response->setHeader('Content-Disposition', 'attachment;filename="tsref.xml"');
			$this->view = NULL;
		} catch (\Exception $exception) {
			$this->addFlashMessage($exception->getMessage(), 'Error', Message::SEVERITY_ERROR);
			$this->redirect(
				'index', 'tsref', 'SGalinski.TypoScriptReferenceFrontend', ['typo3Version' => $typo3Version]
			);
		}
	/**
	 * Sets view variables needed for type menu.
	 *
	 * @param int $selectedTypeUrlName
damjan's avatar
damjan committed
	 * @param string $selectedTypo3Version
	 * @return void
	protected function prepareTypeMenu($selectedTypeUrlName, $selectedTypo3Version) {
damjan's avatar
damjan committed
		try {
			$typo3VersionFilter = $this->decodeTypo3Version($selectedTypo3Version);
damjan's avatar
damjan committed
			$types = $this->tsrefRestService->getTypes(
				TRUE, $typo3VersionFilter, $this->session->getData('typoScriptGroup')
			);
			$typo3Versions = $this->tsrefRestService->getTypo3Versions();
			$groupedTypes = Conversion::groupTypesForSidebar($types);

			$this->view->assign('menuTypes', $groupedTypes);
			$this->view->assign('selectedTypeUrlName', $selectedTypeUrlName);
			$this->view->assign('typo3Versions', $typo3Versions);
			$this->view->assign('selectedTypo3Version', $selectedTypo3Version);
			$this->view->assign('typoScriptGroups', $this->tsrefRestService->getAllTypo3Groups());
			$this->view->assign('selectedTypoScriptGroup', $this->session->getData('typoScriptGroup'));
		} catch (\Exception $exception) {
			$this->addFlashMessage($exception->getMessage(), 'Error', Message::SEVERITY_ERROR);
		}

	/**
	 * Translates TYPO3 version selection from user-friendly value to actual value
	 * which is used in backend for filtering.
	 *
	 * @param string $selectedTypo3Version
	 * @return null|string
	 */
	protected function decodeTypo3Version($selectedTypo3Version) {
		if (strcasecmp($selectedTypo3Version, TsrefRestService::TYPO3_CURRENT_VERSION_LABEL) === 0) {
			return TsrefRestService::TYPO3_DEFAULT_VERSION;
		}
		if (strcasecmp($selectedTypo3Version, 'all') === 0) {
			return NULL;
		}
		return $selectedTypo3Version;
	}

	/**
	 * Stores to session $submittedTypo3Version and $submittedTypoScriptGroup.
	 *
	 * @param $submittedTypo3Version
	 * @param $submittedTypoScriptGroup
	 * @return void
	 */
	protected function storeToSession($submittedTypo3Version, $submittedTypoScriptGroup) {
		$this->session->putData('typo3Version', $submittedTypo3Version);
		$this->session->putData('typoScriptGroup', $submittedTypoScriptGroup);
	}

	/**
	 * Checks if client is authenticated and if he has privileges to edit the data.
	 * Sets error message if client can't edit the data, and redirects to index action.
damjan's avatar
damjan committed
	 *
	 * @param $typo3Version
	 * @param $parentTypeUrlName
	 * @return void
	 */
	protected function checkEditPermission(
		$typo3Version = TsrefRestService::TYPO3_CURRENT_VERSION_LABEL, $parentTypeUrlName = NULL
	) {
		if (!$this->securityContext->hasRole('SGalinski.TypoScriptReferenceFrontend:Admin')) {
			$this->addFlashMessage('You don\'t have permission to edit the data.', 'Error', Message::SEVERITY_ERROR);
			$this->redirect(
				'index', 'tsref', 'SGalinski.TypoScriptReferenceFrontend',
				['typeUrlName' => $parentTypeUrlName, 'typo3Version' => $typo3Version]
			);
		}
	}
damjan's avatar
damjan committed
}