Edit tt_content in Frontend

https://github.com/wallpageNET/infochy_feeditexample

config.tx_extbase {
    persistence{
        enableAutomaticCacheClearing = 1
        updateReferenceIndex = 0
        classes {
            Infochy\InfochyContent\Domain\Model\Content {
                mapping {
                    tableName = tt_content
                    columns {
                        uid.mapOnProperty = uid
                        pid.mapOnProperty = pid
                        sorting.mapOnProperty = sorting
                        CType.mapOnProperty = contentType
                        header.mapOnProperty = header
                        bodytext.mapOnProperty = bodytext
                    }
                }
            }
        }
    }
}
class Content extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
   /**
    * uid
    *
    * @var string
    */
   protected $uid = '';

   /**
    * pid
    *
    * @var string
    */
   protected $pid = '';

   /**
    * header
    *
    * @var string
    */
   protected $header = '';

   /**
    * sorting
    *
    * @var string
    */
   protected $sorting = '';

   /**
    * contentType
    *
    * @var string
    */
   protected $contentType = '';

   /**
    * Gets the uid
    *
    * @return string $uid
    */
   public function getUid() {
      return $this->uid;
   }
   /**
    * Gets the pid
    *
    * @return string $pid
    */
   public function getPid() {
      return $this->pid;
   }

   /**
    * Returns the header
    *
    * @return string $header
    */
   public function getHeader() {
      return $this->header;
   }

   /**
    * Sets the header
    *
    * @param string $header
    * @return void
    */
   public function setHeader($header) {
      $this->header = $header;
   }

   /**
    * Returns the sorting
    *
    * @return string $sorting
    */
   public function getSorting() {
      return $this->sorting;
   }

   /**
    * Sets the sorting
    *
    * @param string $sorting
    * @return void
    */
   public function setSorting($sorting) {
      $this->sorting = $sorting;
   }

   /**
    * Returns the contentType
    *
    * @return string $contentType
    */
   public function getContentType() {
      return $this->contentType;
   }

   /**
    * Sets the contentType
    *
    * @param string $contentType
    * @return void
    */
   public function setContentType($contentType) {
      $this->contentType = $contentType;
   }

   /**
    * bodytext
    *
    * @var string
    */
   protected $bodytext = '';
   /**
    * Returns the bodytext
    *
    * @return string $bodytext
    */
   public function getBodytext() {
      return $this->bodytext;
   }

   /**
    * Sets the bodytext
    *
    * @param string $bodytext
    * @return void
    */
   public function setBodytext($bodytext) {
      $this->bodytext = $bodytext;
   }
}
class ContentRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{
    public function setStoragePageId($storagePid) {
        $querySettings = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings'); 
        $querySettings->setRespectStoragePage(FALSE); 
        $querySettings->setStoragePageIds(array($storagePid)); 
        $this->setDefaultQuerySettings($querySettings);
    }
    
}

Helper for Frontend-Editing Extensions

SETUP: ExampleFiles

Helper-Extension-GIT: infochy_helper
Helper-Extension-TER: infochy_helper

Example-Extension-TER:
infochy_feeditexample
Example-Extension-GIT: infochy_feeditexample

Installation

1. Installiere infochy_helper

2. Installiere infochy_feeditexample

3. Plugin (Private Plugin – Extbase Example/ Public Plugin – Extbase Example) anlegen und Record Storage Page defenieren im Plugin

4. Installiere fe_login und FeUser im Backend anlegen

Informationen für eigene Extension

1. Mit dem ExtensionBuilder ein Frontend plugin erzeugen. Model im „aggregate root“ anlegen, damit ein Controller angelegt wird. Im Model die Propertys User(int) und Image(image*) festlegen.

2. In der eigenen Extension den BaseHelperController erben und Einstellungen ($modelObjNameCreateAction,$modelObjNameUpdateAction,$fileadminFolder,$actionNameOnAccessFailed,$imagePropertyNameInModel) definieren.

3. Model für hiddenRecords freischalten: $hiddenRecordsObjectConverter + TypeConvert anlegen + Instanzieren in ext_localconf.php

4. PropertyMapper Action festlegen: $actionGetRecord, $actionModificationRecord, $actionCreateRecord

5. Domain erweiteren (BaseHelperModel,
BaseHelperRepository)

6. TCA definieren

7. Edit und New Fluid-Action-Template bearbeiten

8. Partial Template bearbeiten

8. FormErrors.html ersetzen.

9. Aktion anlegen + ext_localconf.php + Fluid

DateTimeConverter

public function initializeCreateAction()
{
	$this->setDateTimePropertyDateTimeConverter('newModel','dateStart');
}    
public function initializeUpdateAction()
{
	$this->setDateTimePropertyDateTimeConverter('model','dateStart');
}
protected function setDateTimePropertyDateTimeConverter($modelName,$propertyName){
	$this->arguments[$modelName]
	->getPropertyMappingConfiguration()
	->forProperty($propertyName)
	->setTypeConverterOption('TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter', 
	\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT, 
	'd-m-y');		
}

ConjunctionValidator

public function initializeCreateAction() {
    if ($this->arguments->hasArgument('newModel')) {
        // \TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator 
        $conjunctionValidator = $this->arguments->getArgument('newModel')->getValidator();
        foreach ($conjunctionValidator->getValidators() as $validator) {
            $conjunctionValidator->removeValidator($validator);
        }
    }
}

Extbase FeUser Example Extension

GIT: https://github.com/wallpageNET/infochy_feuserexample
TER: https://typo3.org/extensions/repository/view/infochy_feuserexample

Model

    /**
     * user
     *
     * @var \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
     */
    protected $user;
    
    /**
     * Returns the user
     *
     * @return \TYPO3\CMS\Extbase\Domain\Model\FrontendUser $user
     */
    public function getUser() {
        return $this->user;
    }

    /**
     * Sets the user
     *
     * @param \TYPO3\CMS\Extbase\Domain\Model\FrontendUser $user
     * @return void
     */
    public function setUser($user) {
        $this->user = $user;
    }

Controller

    /**
     * action create
     *
     * @param \Infochy\InfochyFeuserexample\Domain\Model\MyData $newMyData
     * @return void
     */
    public function createAction(\Infochy\InfochyFeuserexample\Domain\Model\MyData $newMyData)
    {
        $this->addFlashMessage('createAction ADD FrontendUser', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR);       

		
	$newMyData->getUser()->addUsergroup($this->getFrontendUserGroup());          
        $this->myDataRepository->add($newMyData);
        $this->redirect('list');
    }
    
    private function getFrontendUserGroup(){
    	$frontendUserGroups = $this->frontendUserGroupRepository->findByTitle('InfochyFeuserexample');
		$frontendUserGroup = $frontendUserGroups->getFirst();
		if(!is_null($frontendUserGroup)){
			return $frontendUserGroup;
		}else{
			$frontendUserGroup = $this->objectManager->get('TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup');
			$frontendUserGroup->setTitle('InfochyFeuserexample');
			$frontendUserGroup->setDescription('Title display only on Sys-Pages');
			$this->frontendUserGroupRepository->add($frontendUserGroup);
			$persistenceManager =  $this->objectManager->get('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager');
			$persistenceManager->persistAll();	
	    	$frontendUserGroups = $this->frontendUserGroupRepository->findByTitle('InfochyFeuserexample');
			return $frontendUserGroups->getFirst();					
		}
    }

Controller -> frontendUserGroupRepository

    /**
     * frontendUserGroupRepository
     *
     * @var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserGroupRepository
     * @inject
     */
    protected $frontendUserGroupRepository = NULL;

TCA

		'user' => array(
			'exclude' => 1,
			'label' => 'Fe User',
			'config' => array(
				'type' => 'inline',
				'foreign_table' => 'fe_users',
				'minitems' => 0,
				'maxitems' => 1,
				'appearance' => array(
					'collapseAll' => 0,
					'levelLinksPosition' => 'top',
					'showSynchronizationLink' => 1,
					'showPossibleLocalizationRecords' => 1,
					'showAllLocalizationLink' => 1
				),
			),
		),	

Fluid-HTML

<label for="user.username">
	FeUser->username
</label><br />
	<f:form.textfield property="user.username" /><br />
	
<label for="user.password">
	FeUser->password
</label><br />
	<f:form.textfield property="user.password" /><br />
	
<label for="user.name">
	FeUser->name
</label><br />
	<f:form.textfield property="user.name" /><br />
	
<label for="user.email">
	FeUser->email
</label><br />
	<f:form.textfield property="user.email" /><br />

save FeUser To Model

/**
* action createFrontendUserAction
*
* @param \Vendor\extName\Domain\Model\Example $newExample
*/
public function createFrontendUserAction(\Vendor\extName\Domain\Model\Example $newExample) {
	$feuser = $this->objectManager->create('TYPO3\CMS\Extbase\Domain\Model\FrontendUser');
	$feuser->setName('Name');
	$feuser->setEmail('example@email.de');
	$feuser->setUsername('Username');
	$feuser->setPassword('Password');
	$newExample->setUser($feuser);
	$this->ExampleRepository->add($newExample);
}

FeUserService

class

namespace Infochy\InfochyFeuserexample\Domain\Service;

use TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface;

class FeUserService implements \TYPO3\CMS\Core\SingletonInterface {

  /**
   * @var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository
   * @inject
   */
  protected $frontendUserRepository;

  /**
   * @return boolean
   */
  public function isUserActive() {
    return $this->getFrontendController()->loginUser;
  }

  /**
   * @return FrontendUser
   */
  public function getFrontendUser() {
    return $this->frontendUserRepository->findByIdentifier($this->getFrontendController()->fe_user->user['uid']);
  }

  /**
   * @param DomainObjectInterface $user
   * @return void
   */
  public function setFeUserActiv(DomainObjectInterface $user) {
    $frontendController = $this->getFrontendController();
    $frontendController->fe_user->createUserSession($user->_getCleanProperties());
    $frontendController->fe_user->loginSessionStarted = TRUE;
    $frontendController->fe_user->user = $frontendController->fe_user->fetchUserSession();
    $frontendController->loginUser = TRUE;
  }

  /**
   * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
   */
  protected function getFrontendController() {
    return $GLOBALS['TSFE'];
  }
}

inject

    /**
     * @var \Infochy\InfochyFeuserexample\Domain\Service\FeUserService
     * @inject
     */
    protected $feUserService;

FluidMail

class

use TYPO3\CMS\Extbase\Object\ObjectManager;

class FluidMail {
    protected $templateFolder = 'Resources/Private/Templates/Email/';

    protected $objectManager;
    protected $extKey;

    protected $recipient = array();
    protected $sender = array();
    protected $subject = '';

    protected $templateName;
    protected $viewArrayMultiple = array();

    public function __construct() {
        $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
    }
    public function setObjectManager($objectManager){
        $this->objectManager = $objectManager;
    }
    public function setExtKey($extKey){
        $this->extKey = $extKey;
    }
    public function setTemplateName($templateName){
        $this->templateName = $templateName;
    }
    public function setArrayToViewObject($viewArrayMultiple){
        $this->viewArrayMultiple = $viewArrayMultiple;
    }
    public function setTemplateFolder($templateFolder){
        $this->templateFolder = $templateFolder;
    }
    public function setMailParams(array $recipient, array $sender, $subject){
        $this->recipient = $recipient;
        $this->sender = $sender;
        $this->subject = $subject;
    }
    public function send(){
        $emailBody = $this->getHtmlTemplate();
        $message = $this->objectManager->get('TYPO3\CMS\Core\Mail\MailMessage');
        $message->setTo($this->recipient)
            ->setFrom($this->sender)
            ->setSubject($this->subject);
        $message->setBody($emailBody, 'text/html');
        $message->send();
        return $message->isSent();
    }
    protected function getHtmlTemplate(){
        $emailView = $this->objectManager->get('TYPO3\CMS\Fluid\View\StandaloneView');
        $emailView->setTemplatePathAndFilename($this->getTemplatePathAndFilename());
        $emailView->assignMultiple($this->viewArrayMultiple);
        return $emailView->render();

    }
    protected function getTemplatePathAndFilename(){
        return \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName('EXT:'.$this->extKey.'/'.$this->templateFolder ) . $this->templateName . '.html';
    }
}

Use FluidMail

$fluidMail = new \Vendor\extName\Utility\FluidMail();
$fluidMail->setExtKey($this->extKey);
$fluidMail->setTemplateName('templateName');
$fluidMail->setArrayToViewObject(array('key' => 'value'));
$fluidMail->setMailParams(array('mail@to.de' => 'To'),array('mail@from.de' => 'From'),'hallo');
$fluidMail->send();

Tca Hook

ext_localconf.php

$hookPath = "EXT:extName/Classes/TcaHooks/class.Tx_extName_tcemainprocdm.php:Tx_extName_tcemainprocdm";
$GLOBALS["TYPO3_CONF_VARS"]["SC_OPTIONS"]["t3lib/class.t3lib_tcemain.php"]["processDatamapClass"][] = $hookPath;

Tx_extName_tcemainprocdm

class Tx_extName_tcemainprocdm {
    function processDatamap_postProcessFieldArray($status, $table, $id, &$fieldArray) {
        if ($status == 'update' && $table == 'fe_users') {
        }
    }
}

Simple FeUser Session

$GLOBALS['TSFE']->fe_user->setKey('ses', 'extensionKey', $data);
$GLOBALS['TSFE']->fe_user->storeSessionData();	
$GLOBALS['TSFE']->fe_user->setKey('ses', 'extensionKey', null);
$GLOBALS['TSFE']->fe_user->storeSessionData();