TYPO3 FAL (file abstraction layer) in Extbase/Fluid extension

Recently I came across to implement extbase plugin having multiple file upload FE form.

My Typo3 version was 6.1
The extension was created using Extension Builder

File ext_tables.sql

CREATE TABLE tx_clientside_domain_model_orderitems (
:
files int(11) unsigned DEFAULT ‘0’ NOT NULL,
:

);

File Configuration/TCA/OrderItems.php

$TCA[‘tx_clientside_domain_model_orderitems’] = array(
//…… removed code

‘files’ => array(
‘exclude’ => 1,
‘label’ => ‘Files’,
‘config’ => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(‘files’, array(
‘appearance’ => array(
‘createNewRelationLinkTitle’ => ‘LLL:EXT:cms/locallang_ttc.xlf:images.addFileReference’
),
), $GLOBALS[‘TYPO3_CONF_VARS’][‘GFX’][‘imagefile_ext’]),
),

//…..

);

File Classes/Domain/Model/OrderItems.php

class OrderItems extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {

/**
* Files
*
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
*/
protected $files;

/**
* __construct
*
* @return AbstractObject
*/
public function __construct() {
$this->files = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
}
/**
* Returns the files
*
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
*/
public function getFiles() {
return $this->files;
}

}

I have not used function setFiles here.

File Classes/Controller/OrderItemsController.php

class OrderItemsController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {

/**
* orderItemsRepository
*
* @var \TYPO3\Clientside\Domain\Repository\OrderItemsRepository
* @inject
*/
protected $orderItemsRepository;

/**
* action create
*
* @param \TYPO3\Clientside\Domain\Model\OrderItems $newOrderItems
* @dontvalidate $newOrderItems
* @return void
*/
public function createAction(\TYPO3\Clientside\Domain\Model\OrderItems $newOrderItems) {

$this->orderItemsRepository->add($newOrderItems);

$persistenceManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(‘Tx_Extbase_Persistence_Manager’);
$persistenceManager->persistAll();
$uidNew = $newOrderItems->getUid();

if ($_FILES[‘tx_clientside_orderitems’]) {
for ($i = 0; $i < count($_FILES[‘tx_clientside_orderitems’][‘name’][‘myfiles’]); $i++) {
$file = array();
$file[‘name’] = $_FILES[‘tx_clientside_orderitems’][‘name’][‘myfiles’][$i];
$file[‘type’] = $_FILES[‘tx_clientside_orderitems’][‘type’][‘myfiles’][$i];
$file[‘tmp_name’] = $_FILES[‘tx_clientside_orderitems’][‘tmp_name’][‘myfiles’][$i];
$file[‘size’] = $_FILES[‘tx_clientside_orderitems’][‘size’][‘myfiles’][$i];
if ($file[‘name’]) {
$files = $this->uploadFile($file[‘name’], $file[‘type’], $file[‘tmp_name’], $file[‘size’]);
$sysFileCreate = $this->orderItemsRepository->myFileOperationsFal($files, $file[‘type’], $file[‘size’], $uidNew);
}
}
}

$this->flashMessageContainer->add(‘Your new OrderItems was created.’);
$this->redirect(‘list’);
}

protected function uploadFile($name, $type, $temp, $size) {
if($size > 0) {
$basicFileFunctions = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(‘t3lib_basicFileFunctions’);

$name = $basicFileFunctions->cleanFileName($name);
$uploadPath = $basicFileFunctions->cleanDirectoryName(‘fileadmin/user_upload/’);
$uniqueFileName = $basicFileFunctions->getUniqueName($name, $uploadPath);
$fileStored = move_uploaded_file($temp, $uniqueFileName);

$returnValue = basename($uniqueFileName);
}

return $returnValue;
}

}

 

File Classes/Romain/Repository/OrderItemsRepository.php

class OrderItemsRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {

public function myFileOperationsFal($filename, $filetype, $filesize, $uidNew){

$newSysFields = array(
‘pid’ => 0,
‘identifier’ =>’/user_upload/’.$filename,
‘mime_type’ => $filetype,
‘name’ => $filename,
‘size’ => $filesize,
‘storage’ => 1,
‘crdate’ => $GLOBALS[‘EXEC_TIME’],
‘tstamp’ => $GLOBALS[‘EXEC_TIME’]
);

$newSysRes = $GLOBALS[‘TYPO3_DB’]->exec_INSERTquery(‘sys_file’, $newSysFields);

$uid_local = $GLOBALS[‘TYPO3_DB’]->sql_insert_id($newSysRes);
$newRefFields = array(
‘pid’ => 88,
‘tablenames’ => ‘tx_clientside_domain_model_orderitems’,
‘uid_foreign’ => $uidNew,
‘uid_local’ => $uid_local,
‘table_local’ => ‘sys_file’,
‘fieldname’ => ‘files’,
‘crdate’ => $GLOBALS[‘EXEC_TIME’],
‘tstamp’ => $GLOBALS[‘EXEC_TIME’]
);

$GLOBALS[‘TYPO3_DB’]->exec_INSERTquery(‘sys_file_reference’, $newRefFields);
}

}

Here I am writing custom File operation function, that creates new entry in table sys_file and mm relation to table sys_file_reference.
I have searched google for any other good way, without success 🙁

Suggestions are welcome 🙂

File Resources/Private/Templates/Root/New.html

<f:form action=”create” enctype=”multipart/form-data” name=”newOrderItems” object=”{newOrderItems}” >
<input name=”tx_clientside_orderitems[myfiles][]” type=”file” /><br />
<input name=”tx_clientside_orderitems[myfiles][]” type=”file” /><br />
<f:form.submit value=”Create new” /></f:form>

 

Here is how to dispaly that images in frontend

File Resources/Private/Templates/Root/Show.html

<f:for each=”{orderItems.files}” as=”file”>
<f:image src=”{file.uid}” alt=”” width=’101′ height=”67″ treatIdAsReference=”1″/>
</f:for>

 

Open Graph Tags example for use with Facebook

page.headerData.120 = COA
page.headerData.120 {
10 = TEXT
10 {
typolink.parameter.data = TSFE:id
typolink.forceAbsoluteUrl = 1
typolink.returnLast = url
typolink.additionalParams.cObject = COA
typolink.additionalParams.cObject {
10 = TEXT
10.dataWrap = &tx_ttnews[tt_news]={GP:tx_ttnews|tt_news}
10.if.isTrue.data = GP:tx_ttnews|tt_news
20 = TEXT
20.dataWrap = &tx_ttnews[cat]={GP:tx_ttnews|cat}
20.if.isTrue.data = GP:tx_ttnews|cat
}
wrap = <meta property=”og:url” content=”|”/>
}
20 < page.headerData.1
20 {
wrap = <meta property=”og:title” content=”| {$siteTitle}”/>
}

30 = TEXT
30.value =
30.wrap = <meta property=”og:site_name” content=”|{$siteTitle}”/>

40 = TEXT
40.value = <meta property=”og:description” content=”” />
40.wrap = <meta property=”og:type” content=”website” />|

}

In additions to the above, we can also set the og:image property on a news detail page like given below:
This new updated Code also includes a default image when news has no image.

page.headerData.120.50 = COA
page.headerData.120.50 {
20 = CONTENT
20 {
table = tt_news
select {
pidInList = 18
andWhere = uid={GP:tx_ttnews|tt_news}
andWhere.insertData =1
selectFields = uid,pid,image
}
renderObj = COA
renderObj {
10 = TEXT
10.value =<meta property=”og:image” content=”http://www.mydomain.com/uploads/pics/
20 = TEXT
20 {
field = image
split {
token = ,
max = 1
cObjNum = 1
1.current = 1
}
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value = alt-image.jpg
}

}
30 = TEXT
30.value = ” />
}
}
}