Given something like this:
/**
* #brief FuncA
*
* Data format:
* INT32 Date
* INT32 Time
* FLOAT Value
*
*/
void funcA()
{}
/**
* #brief FuncB
*
* Data format:
* INT32 Date
* INT32 Time
* FLOAT Value
*
*/
void funcB()
{}
How can I factor out the data format spec so it's not duplicated in multiple places? What I want is something like this:
/**
* #magictag Data Format
*
* INT32 Date
* INT32 Time
* FLOAT Value
*/
/**
* #brief FuncA
*
* Data format:
* #ref DataFormat
*
*/
void funcA()
{}
/**
* #brief FuncB
*
* Data format:
* #ref DataFormat
*
*/
void funcB()
{}
I just want to have a generic blob of documentation that I can reference from any number of places. Thanks.
The current version of doxygen is 1.8.16, it is advised to upgrade to this version. With version 1.8.11 the \snippetdoc does not work (command didn't exist in this version).
An example with \copydetails:
/** \file */
/**
* #brief FuncA
*
* Data format:
* - INT32 Date
* - INT32 Time
* - FLOAT Value
*
*/
void funcA();
/**
* #brief FuncB
*
* #copydetails funcA
*/
void funcB();
An example with \snippetdoc:
/** \file */
/**
* #brief FuncC
*
* #snippetdoc this snip_data
*
*/
void funcC();
/**
* #brief FuncD
*
* #snippetdoc this snip_data
*/
void funcD();
/*
[snip_data]
Data format:
- INT32 Date
- INT32 Time
- FLOAT Value
[snip_data]
*/
I extend feuser with custom fields. All work good. If I type integer value it was save good. But if I type string value I get error - 1332933658: "" is no integer. You can see this on the follow screenshots.
enter image description here
ext_tables.php
#
# Table structure for table 'fe_users'
#
CREATE TABLE fe_users (
aboutmyself varchar(255) DEFAULT '' NOT NULL,
aboutmypartner varchar(255) DEFAULT '' NOT NULL,
tx_extbase_type varchar(255) DEFAULT '0' NOT NULL,
);
Model:
<?php
namespace Fhk\Feusersplus\Domain\Model;
/***************************************************************
*
* Copyright notice
*
* (c) 2017
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* User
*/
class User extends \In2code\Femanager\Domain\Model\User
{
/**
* aboutmyself
*
* #var int
*/
protected $aboutmyself = '';
/**
* aboutmypartner
*
* #var int
*/
protected $aboutmypartner = '';
/**
* Returns the aboutmyself
*
* #return int $aboutmyself
*/
public function getAboutmyself()
{
return (string)$this->aboutmyself;
}
/**
* Returns the aboutmypartner
*
* #return int $aboutmypartner
*/
public function getAboutmypartner()
{
return (string)$this->aboutmypartner;
}
/**
* Sets the aboutmyself
*
* #return void
*/
public function setAboutmyself($aboutmyself)
{
$this->aboutmyself = (string)$aboutmyself;
}
/**
* Sets the aboutmypartner
*
* #return void
*/
public function setAboutmypartner($aboutmypartner)
{
$this->aboutmypartner = (string)$aboutmypartner;
}
/**
* __construct
*/
public function __construct()
{
//Do not remove the next line: It would break the functionality
$this->initStorageObjects();
}
/**
* Initializes all ObjectStorage properties
* Do not modify this method!
* It will be rewritten on each save in the extension builder
* You may modify the constructor of this class instead
*
* #return void
*/
protected function initStorageObjects()
{
}
}
The type hint for your fields aboutmyself and aboutmypartner is defined as
#var int
but you store a VARCHAR. Try changing the hint to
#var string
and clear all caches (also, emptying the typo3temp folder can't hurt).
My requirement is to implement a multiple fileupload field in TYPO3 Front-end Extension. Here is what I've used for a single file upload.
My Fields in Model
/**
* angebotuploaden
*
* #var \TYPO3\CMS\Extbase\Domain\Model\FileReference
*/
protected $angebotuploaden = NULL;
/**
* Returns the angebotuploaden
*
* #return \TYPO3\CMS\Extbase\Domain\Model\FileReference $angebotuploaden
*/
public function getAngebotuploaden() {
return $this->angebotuploaden;
}
/**
* Sets the angebotuploaden
*
* #param \TYPO3\CMS\Extbase\Domain\Model\FileReference $angebotuploaden
* #return void
*/
public function setAngebotuploaden(\TYPO3\CMS\Extbase\Domain\Model\FileReference $angebotuploaden) {
$this->angebotuploaden = $angebotuploaden;
}
Now I face issues in implementing multiple file-uploads for this field. Please help me to sort it out.
Use ObjectStorage to get an 1:n-Relation to the FileReference model. In your model that could look like this:
/**
* uploadFiles
*
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
* #cascade remove
*/
protected $uploadFiles = NULL;
/**
* __construct
*/
public function __construct() {
//Do not remove the next line: It would break the functionality
$this->initStorageObjects();
}
/**
* Initializes all ObjectStorage properties
* Do not modify this method!
* It will be rewritten on each save in the extension builder
* You may modify the constructor of this class instead
*
* #return void
*/
protected function initStorageObjects() {
$this->uploadFiles = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
}
/**
* Adds a UploadFile
*
* #param \TYPO3\CMS\Extbase\Domain\Model\FileReference $uploadFile
* #return void
*/
public function addUploadFile(\TYPO3\CMS\Extbase\Domain\Model\FileReference $uploadFile) {
$this->uploadFiles->attach($uploadFile);
}
/**
* Removes a UploadFile
*
* #param \TYPO3\CMS\Extbase\Domain\Model\FileReference $uploadFileToRemove The UploadFile to be removed
* #return void
*/
public function removeUploadFile(\TYPO3\CMS\Extbase\Domain\Model\FileReference $uploadFileToRemove) {
$this->uploadFiles->detach($uploadFileToRemove);
}
/**
* Returns the uploadFiles
*
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $uploadFiles
*/
public function getUploadFiles() {
return $this->uploadFiles;
}
/**
* Sets the uploadFiles
*
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $uploadFiles
* #return void
*/
public function setUploadFiles(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $uploadFiles) {
$this->uploadFiles = $uploadFiles;
}
There're still more things to do, especially in TCA, but I don't know them in detail because I didn't use that yet. See Hemult Hummels Upload Example an this question for more detailed information.
Is there any natural way or special tag to make parameter type as link?
/**
* My js app
* #module app
*/
/**
* Namespace for MYAPP classes and functions.
* #namespace HUMAN_RESOURCE
*/
var HUMAN_RESOURCE = HUMAN_RESOURCE || {};
/**
* #class JustClass
* #constructor
*/
HUMAN_RESOURCE.JustClass = function(){ }
/**
* Constructs Person objects
* #class Person
* #constructor
* #param {String} First name
* #param {String} Last name
*/
HUMAN_RESOURCE.Person = function (first, last) {
/**
* First name of the Person
* #property first_name
* #type String
*/
this.first_name = first;
/**
* #property f_createPerson
* #param {Person} [_person] açıklama
* #return {Person} Person type object
*/
this.f_createPerson = function(_person, _person2){ return new Person() }
};
/**
* Return Person's full name
* #alias getName
* #memberof! HUMAN_RESOURCE.Person#
* #return {String} First name + last name
*/
HUMAN_RESOURCE.Person.prototype.getName = function () {
return this.first_name + ' ' + this.last_name;
};
Fortunately yes, it is just not always obvious what the correct name path is (but you can basically see it at the top of your generated docs)
/**
* #property f_createPerson
* #param {module:app~HUMAN_RESOURCE.Person} [_person] açıklama
* #return {module:app~HUMAN_RESOURCE.Person} Person type object
*/
this.f_createPerson = function(_person, _person2){ return new Person() }
I need to put two objects in one form with fluid.
The background is: I have a userDomain and a ordering object. Both are not persistent. I want to send these two objects to an action without making one of them persistent. The userDomain object is handled by the form, the other is assigned to the view. If I add the ordering object to the arguments section in the Form, Typo3 throws me this error:
Oops, an error occurred!
Could not serialize Domain Object Whmcs\Registration\Domain\Model\Ordering. It is neither an Entity with identity properties set, nor a Value Object.
More information regarding this error might be available online.
This is because the object is non-persistent and does not have any ID.
So the question is, how I do pass these two objects to the next action?
In order to pass non persistent objects between multiple actions, I would suggest that you store the objects serialized in a TYPO3 session variable. Doing so, you can restore the objects in the target action.
Below you find a working example which can also be found here.
<?php
namespace derhansen\ValidationExamplesNew\Controller;
/***************************************************************
* Copyright notice
*
* (c) 2013 Torben Hansen <derhansen#gmail.com>
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Multiple Steps Controller
*
* #package validation_examples_new
* #license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
*
*/
class MultipleStepsController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* addressdataRepository
*
* #var \derhansen\ValidationExamplesNew\Domain\Repository\AddressdataRepository
* #inject
*/
protected $addressdataRepository;
/**
* API Service
*
* #var \derhansen\ValidationExamplesNew\Service\ExternalApiService
* #inject
*/
protected $apiService;
/**
* Step1
*
* #param \derhansen\ValidationExamplesNew\Domain\Model\Step1Data $step1data
* #dontvalidate $step1data
*/
public function step1Action(\derhansen\ValidationExamplesNew\Domain\Model\Step1Data $step1data = NULL) {
/* Check if step1data is available in session */
if ($GLOBALS['TSFE']->fe_user->getKey('ses', 'step1data') && $step1data == NULL) {
$step1data = unserialize($GLOBALS['TSFE']->fe_user->getKey('ses', 'step1data'));
}
$this->view->assign('step1data', $step1data);
}
/**
* Step1 redirect action
*
* #param \derhansen\ValidationExamplesNew\Domain\Model\Step1Data $step1data
*/
public function step1redirectAction(\derhansen\ValidationExamplesNew\Domain\Model\Step1Data $step1data) {
$GLOBALS['TSFE']->fe_user->setKey('ses', 'step1data', serialize($step1data));
$GLOBALS['TSFE']->fe_user->storeSessionData();
$this->redirect('step2');
}
/**
* Step2
*
* #param \derhansen\ValidationExamplesNew\Domain\Model\Step2Data $step2data
* #dontvalidate $step2data
*/
public function step2Action(\derhansen\ValidationExamplesNew\Domain\Model\Step2Data $step2data = NULL) {
/* Check if step2data is available in session */
if ($GLOBALS['TSFE']->fe_user->getKey('ses', 'step2data') && $step2data == NULL) {
$step2data = unserialize($GLOBALS['TSFE']->fe_user->getKey('ses', 'step2data'));
}
/* Set external validations errors if available */
$this->setApiValidationErrors('step2');
$this->view->assign('step2data', $step2data);
}
/**
* Step2 redirect action
*
* #param \derhansen\ValidationExamplesNew\Domain\Model\Step2Data $step2data
*/
public function step2redirectAction(\derhansen\ValidationExamplesNew\Domain\Model\Step2Data $step2data) {
$GLOBALS['TSFE']->fe_user->setKey('ses', 'step2data', serialize($step2data));
$GLOBALS['TSFE']->fe_user->storeSessionData();
$this->redirect('step3');
}
/**
* Step3
*
* #param \derhansen\ValidationExamplesNew\Domain\Model\Step3Data $step3data
* #dontvalidate $step3data
*/
public function step3Action(\derhansen\ValidationExamplesNew\Domain\Model\Step3Data $step3data = NULL) {
/* Check if step3data is available in session */
if ($GLOBALS['TSFE']->fe_user->getKey('ses', 'step3data') && $step3data == NULL) {
$step3data = unserialize($GLOBALS['TSFE']->fe_user->getKey('ses', 'step3data'));
}
/* Set external validations errors if available */
$this->setApiValidationErrors('step3');
$this->view->assign('step3data', $step3data);
}
/**
* Step3 redirect action
*
* #param \derhansen\ValidationExamplesNew\Domain\Model\Step3Data $step3data
*/
public function step3redirectAction(\derhansen\ValidationExamplesNew\Domain\Model\Step3Data $step3data) {
$GLOBALS['TSFE']->fe_user->setKey('ses', 'step3data', serialize($step3data));
$GLOBALS['TSFE']->fe_user->storeSessionData();
$this->redirect('create');
}
/**
* Create Action
*
* #return void
*/
public function createAction() {
$addressdata = $this->getAddressdataFromSession();
/* get validation results from API */
$apiresults = $this->apiService->validateMultipleSteps($addressdata);
if (count($apiresults) > 0) {
/* Save results to a session variable */
$GLOBALS['TSFE']->fe_user->setKey('ses', 'apiresults', $apiresults);
$GLOBALS['TSFE']->fe_user->storeSessionData();
/* Redirect to step with validation errors */
if (array_key_exists('step2', $apiresults)) {
$this->redirect('step2');
}
if (array_key_exists('step3', $apiresults)) {
$this->redirect('step3');
}
}
$this->addressdataRepository->add($addressdata);
$this->cleanUpSessionData();
$this->view->assign('message', 'Addressdata has been created');
}
/**
* Collects the addressdata from the multiple steps form stored in session variables
* and returns an addressdata object.
*
* #return \derhansen\ValidationExamplesNew\Domain\Model\Addressdata
*/
protected function getAddressdataFromSession() {
/** #var \derhansen\ValidationExamplesNew\Domain\Model\Step1Data $step1data */
$step1data = unserialize($GLOBALS['TSFE']->fe_user->getKey('ses', 'step1data'));
/** #var \derhansen\ValidationExamplesNew\Domain\Model\Step2Data $step2data */
$step2data = unserialize($GLOBALS['TSFE']->fe_user->getKey('ses', 'step2data'));
/** #var \derhansen\ValidationExamplesNew\Domain\Model\Step3Data $step3data */
$step3data = unserialize($GLOBALS['TSFE']->fe_user->getKey('ses', 'step3data'));
/** #var \derhansen\ValidationExamplesNew\Domain\Model\Addressdata $addressData */
$addressData = $this->objectManager->get('derhansen\ValidationExamplesNew\Domain\Model\Addressdata');
$addressData->setFirstname($step1data->getFirstname());
$addressData->setLastname($step1data->getLastname());
$addressData->setStreet($step2data->getStreet());
$addressData->setStreetnr($step2data->getStreetnr());
$addressData->setZip($step3data->getZip());
$addressData->setCity($step3data->getCity());
return $addressData;
}
/**
* Removes all session variables from the multiple steps form
*
* #return void
*/
protected function cleanUpSessionData() {
$GLOBALS['TSFE']->fe_user->setKey('ses', 'step1data', '');
$GLOBALS['TSFE']->fe_user->setKey('ses', 'step2data', '');
$GLOBALS['TSFE']->fe_user->setKey('ses', 'step3data', '');
$GLOBALS['TSFE']->fe_user->setKey('ses', 'apiresults', '');
$GLOBALS['TSFE']->fe_user->storeSessionData();
}
/**
* Sets validation errors for fields in the given step
*
* #param string $step The step
* #return void
*/
protected function setApiValidationErrors($step) {
$apiresults = $GLOBALS['TSFE']->fe_user->getKey('ses', 'apiresults');
if (array_key_exists($step, $apiresults)) {
/* Set Form Errors manually - get results from property mapper and add new errors */
$result = $this->getControllerContext()->getRequest()->getOriginalRequestMappingResults();
/* Add validation errors */
foreach ($apiresults[$step] as $key => $value) {
$error = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Validation\Error',
$apiresults[$step][$key], time());
$result->forProperty($step . 'data.' . $key)->addError($error);
}
$this->getControllerContext()->getRequest()->setOriginalRequestMappingResults($result);
}
}
}
?>
This example is part of a multiple step form validation example, but uses TYPO3 session variables in order to store the input of each form step.