Loading...
Navigation überspringen
Bitte beachte, dass sich diese Dokumentation auf die neuste Version dieser Erweiterung bezieht. Wenn eine ältere Version eingesetzt wird, kann diese abweichen. Die jeweils passende Dokumentation befindet sich im Dokumentation-Verzeichnis der Erweiterung.

Vorbereitung

In dieser Anleitung wollen wir als TYPO3-Erweiterungs-Entwickler ein Frontend-Management für Immobilien in einer Erweiterung integrieren. Unsere Eckdaten sind dabei:

  • Extension-Key: openimmo
  • Objekt-Name: Immobilie

Vorbereitungen

Folgende Punkte müssen vorbereitet werden:

  • Frontend-Controller erstellen
  • Plugin integrieren
  • TypoScript Konfiguration bereitstellen
  • Datenmodel anpassen
  • Repository anpassen
  • Einrichtung im TYPO3

Frontend-Controller erstellen

Es muss ein Frontend-Controller bereitgestellt werden, welcher die Actions prepare, list, edit und create bereitstellt. Dieser Controller erbt von \CodingMs\Modules\Controller\FrontendController als FrontendBaseController. Hierin muss u.a. auch die Zugriffs-Restriktion stattfinden. Dieser Controller sollte am besten den Namen des Objektes bekommen, welches mit diesem bearbeitet wird - daher heißt er hier ImmobilieController.

Classes/Controller/Frontend/ImmobilieController.php

<?php

namespace CodingMs\OpenimmoPro\Controller\Frontend;

use CodingMs\Openimmo\Domain\Model\Immobilie;
use CodingMs\Openimmo\Domain\Repository\ImmobilieRepository;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException;
use CodingMs\Modules\Controller\FrontendController as FrontendBaseController;
use Exception;
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException;

/**
 * Immobilie Controller
 * @noinspection PhpUnused
 */
class ImmobilieController extends FrontendBaseController
{

    /**
     * @var Immobilie
     */
    protected $object = null;

    /**
     * @var ImmobilieRepository
     */
    protected $objectRepository;

    /**
     * @param ImmobilieRepository $objectRepository
     * @noinspection PhpUnused
     */
    public function injectObjectRepository(ImmobilieRepository $objectRepository)
    {
        $this->objectRepository = $objectRepository;
    }

    /**
     * @throws NoSuchArgumentException
     * @throws StopActionException
     */
    protected function prepareAction()
    {
        parent::prepareAction();
        $action = $this->request->getControllerActionName();
        //
        $this->list = $this->settings['lists']['immobilie'];
        $this->list['limit'] = $this->list['limit'] ?? 0;
        $this->list['offset'] = $this->list['offset'] ?? 0;
        $this->list['maxItems'] = $this->list['maxItems'] ?? 0;
        if($action === 'create') {
            $this->form = $this->settings['forms']['immobilieCreate'];
        }
        else {
            $this->form = $this->settings['forms']['immobilie'];
        }
        //
        // On this actions an object is required!
        if(in_array($action, $this->objectRequiredActions)) {
            if ($this->frontendUser->getUid() !== $this->object->getFrontendUser()->getUid()) {
                $this->addFlashMessage('Object not found (code:3)', 'Error', FlashMessage::ERROR);
                $this->forward('list');
            }
        }
        $this->list['frontendUser'] = $this->frontendUser;
    }

    /**
     * action list
     *
     * @return void
     * @throws NoSuchArgumentException
     * @throws StopActionException
     */
    public function listAction()
    {
        $this->prepareAction();
        // ...
    }

    /**
     * @throws Exception
     */
    public function editAction() {
        $this->prepareAction();
        // ...
    }

    /**
     * @throws StopActionException
     * @throws IllegalObjectTypeException
     * @throws Exception
     * @noinspection PhpUnused
     */
    public function createAction() {
        $this->prepareAction();
        // ...
    }

    /**
     * @param $key
     * @param array $arguments
     * @return NULL|string
     */
    protected function translate($key, $arguments = [])
    {
        return LocalizationUtility::translate($key, 'OpenimmoPro', $arguments);
    }

}

Plugin integrieren

Es muss ein Plugin integriert werden, über welches später die Bearbeitung stattfindet.

ext_tables.php

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
    'OpenimmoPro',
    'FrontendImmobilie',
    'Openimmo - Management'
);

ext_localconf.php

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
    'OpenimmoPro',
    'FrontendImmobilie',
    ['Frontend\Immobilie' => 'list,create,edit,activate,deactivate,duplicate,delete'],
    ['Frontend\Immobilie' => 'list,create,edit,activate,deactivate,duplicate,delete']
);

TypoScript Konfiguration bereitstellen

Da die hauptsächliche Konfiguration via TypoScript stattfindet, muss hier auch ein statisches Template bereitgestellt werden. Dafür erstellen wir die folgende Verzeichnisstruktur:

openimmo_pro/Configuration/TypoScript/Frontend/
openimmo_pro/Configuration/TypoScript/Frontend/Library/
openimmo_pro/Configuration/TypoScript/Frontend/Translation/

Im Verzeichnis Configuration/TypoScript/Frontend/ wird eine Datei setup.typoscript mit dem folgenden Inhalt erstellt:

<INCLUDE_TYPOSCRIPT: source="DIR:EXT:openimmo_pro/Configuration/TypoScript/Frontend/Library/" extensions="typoscript">
<INCLUDE_TYPOSCRIPT: source="DIR:EXT:openimmo_pro/Configuration/TypoScript/Frontend/Translation/" extensions="typoscript">

Bereitgestellt wird das statische Template dann durch eine Einbindung in der ext_tables.php:

ext_tables.php

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile(
    'openimmo_pro',
    'Configuration/TypoScript/Frontend',
    'Openimmo-Pro - Frontend management'
);

Damit Deine Fluid-Templates später auch Partials von der Modules-Erweiterung verwenden können, musst Du die Fluid-Template-Pfad in der bereits bestehende Definition hinzufügen:

plugin.tx_openimmopro {
    view {
        templateRootPaths {
            100 = EXT:modules/Resources/Private/Templates/
            200 = EXT:openimmo/Resources/Private/Templates/
            250 = EXT:openimmo_pro/Resources/Private/Templates/
            300 = {$plugin.tx_openimmo.view.templateRootPath}
            400 = {$themes.resourcesPrivatePath}Extensions/Openimmo/Templates/
        }
        partialRootPaths {
            100 = EXT:modules/Resources/Private/Partials/
            200 = EXT:openimmo/Resources/Private/Partials/
            250 = EXT:openimmo_pro/Resources/Private/Partials/
            300 = {$plugin.tx_openimmo.view.partialRootPath}
            400 = {$themes.resourcesPrivatePath}Extensions/Openimmo/Partials/
        }
        layoutRootPaths {
            100 = EXT:modules/Resources/Private/Layouts/
            200 = EXT:openimmo/Resources/Private/Layouts/
            250 = EXT:openimmo_pro/Resources/Private/Layouts/
            300 = {$plugin.tx_openimmo.view.layoutRootPath}
            400 = {$themes.resourcesPrivatePath}Extensions/Openimmo/Layouts/
        }
    }
}

Wir haben dies jeweils im Knoten mit dem Index 100 gemacht.

Datenmodel anpassen

Da unsere Datensätze nur mit einen gültigen Frontend-Benutzer bearbeitet werden können, müssen wir ein Feld bzw. eine Eigenschaft für den Frontend-Benutzer hinzufügen.

Configuration/TCA/tx_openimmo_domain_model_immobilie.php

$GLOBALS['TCA']['tx_openimmo_domain_model_immobilie'] = [
    // ...
    'types' => [
        '1' => [
            'showitem' => '..., frontend_user',
        ],
    ],
    // ...
    'columns' => [
        // ...
        'frontend_user' => [
            'exclude' => 0,
            'label' => $lll . '.frontend_user',
            'config' => [
                'type' => 'group',
                'allowed' => 'fe_users',
                'foreign_table' => 'fe_users',
                'size' => '1',
                'maxitems' => '1',
                'minitems' => '0',
                'eval' => 'int',
            ],
        ],
    ],
];

Classes/Domain/Model/Immobilie.php

use TYPO3\CMS\Extbase\Domain\Model\FrontendUser;

class Immobilie extends AbstractEntity
{

    /**
     * @var \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
     */
    protected $frontendUser = null;

    /**
     * Returns the frontend user
     * @return \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
     */
    public function getFrontendUser(): ?FrontendUser
    {
        return $this->frontendUser;
    }

    /**
     * @param \TYPO3\CMS\Extbase\Domain\Model\FrontendUser $frontendUser
     */
    public function setFrontendUser(FrontendUser $frontendUser) : void
    {
        $this->frontendUser = $frontendUser;
    }

    /**
     * @var bool
     */
    protected $deleted = true;

    /**
     * @return bool
     */
    public function getDeleted(): bool
    {
        return $this->deleted;
    }

    /**
     * @return bool
     */
    public function isDeleted(): bool
    {
        return $this->deleted;
    }

    /**
     * @param bool $deleted
     */
    public function setDeleted(bool $deleted): void
    {
        $this->deleted = $deleted;
    }

    /**
     * @var boolean
     */
    protected $hidden;

    /**
     * @return bool
     */
    public function getHidden(): bool
    {
        return $this->hidden;
    }

    /**
     * @return bool
     */
    public function isHidden(): bool
    {
        return $this->hidden;
    }

    /**
     * @param bool $hidden
     */
    public function setHidden(bool $hidden): void
    {
        $this->hidden = $hidden;
    }

}

ext_tables.sql

CREATE TABLE tx_openimmo_domain_model_immobilie (
    # ...
    frontend_user int(11) DEFAULT '0' NOT NULL,
    # ...
}

Repository anpassen

Damit unser Controller alle notwendigen Aktionen ausführen kann, müssen ein paar Methoden am ImmobilieRepository hinzugefügt werden. Hierbei handelt es sich um eine Methode für die Liste und um eine Methode um einen Datensatz abzurufen. Wichtig dabei ist, dass diese immer den aktuellen Frontend-Benutzer mit abfragen!

Classes/Domain/Repository/ImmobilieRepository.php

class ImmobilieRepository extends Repository
{

    /**
     * @param array $filter
     * @param boolean $count
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface|int
     */
    public function findAllForFrontendList(array $filter = [], $count = false)
    {
        $query = $this->createQuery();
        $query->getQuerySettings()->setIgnoreEnableFields(true);
        $query->getQuerySettings()->setRespectStoragePage(true);
        $constraints = [];
        $constraints[] = $query->equals('frontendUser', $filter['frontendUser']->getUid());
        $query->matching($constraints[0]);
        if (!$count) {
            if (isset($filter['sortingField']) && $filter['sortingField'] !== '') {
                if ($filter['sortingOrder'] === 'asc') {
                    $query->setOrderings([$filter['sortingField'] => QueryInterface::ORDER_ASCENDING]);
                } else {
                    if ($filter['sortingOrder'] === 'desc') {
                        $query->setOrderings([$filter['sortingField'] => QueryInterface::ORDER_DESCENDING]);
                    }
                }
            }
            if ((int)$filter['limit'] > 0) {
                $query->setOffset((int)$filter['offset']);
                $query->setLimit((int)$filter['limit']);
            }
            return $query->execute();
        } else {
            return $query->execute()->count();
        }
    }

    /**
     * @param int $uid
     * @return object
     */
    public function findByIdentifierFrontend(int $uid, int $frontendUser)
    {
        $query = $this->createQuery();
        $query->getQuerySettings()->setIgnoreEnableFields(true);
        $query->getQuerySettings()->setRespectStoragePage(true);
        $constraints = [];
        $constraints[] = $query->equals('uid', $uid);
        $constraints[] = $query->equals('frontendUser', $frontendUser);
        $query->matching($query->logicalAnd($constraints));
        return $query->execute()->getFirst();
    }

}

Einrichtung im TYPO3

Nachdem diese Anpassungen im TYPO3 verfügbar sind, erstellst Du eine geschütze Seite, auf der nur Frontend-Benutzer mit entsprechender Berechtigung zugriff drauf haben. Hier platzierst Du das gerade erstellte Plugin und erstellst zusätzlich ein Erweiterungs-Template. In diesem TypoScript-Template wählst Du die statischen Templates Frontend-Basics (modules) und Openimmo-Pro - Frontend management (openimmo_pro) aus.

In diesem Template können später auch Anpassungen speziell für Dein jeweiliges Webseit-Projekt vorgenommen werden. Im nächsten Abschnitt erfahrst Du, wie Du mit ein wenig TypoScript eine Bearbeitungs-Liste konfigurieren kannst.

Kontaktanfrage

Du kannst uns jederzeit kontaktieren

Stop! Playing in the meantime?
Stop! Playing in the meantime?
Stop! Playing in the meantime?

Stop! Playing in the meantime?

Break the highscore

Press Start
Contact request
Screenreader label
Security question
EMQ_________8Y5______
C_6____T____O_C___H2K
JEK___FR1___F_6______
5_C____2____K_E___YHS
BGU_________2XW______