After TYPO3 Update from 6.2 to 7.6 still errors in TCA? - typo3

I've made an update from TYPO3 CMS 6.2 to TYPO3 CMS 7.6.16. After a few problems with other extensions (tx_newsand third party ext.) and the changes in the TCA. Everything works fine after import live-dump ...
Upgrade wizard / Database compare
Update reference Index
Flush Cache and empty typo3temp
Deactivate and reactivate the Extensions with problems
Everything? Unfortunately, no. The extension doesn't work. I don't written the extension by myself. If I try to add a new data record in backend with this ext., I'll get this error:
An item in field form of table tx_blah_domain_model_job is not an array as expected
But the database comprare is finished. All tables are correct?!
Where's the problem? I know it's hard to analyze this without source code. There's a database field wrong, but why? It's the same database like before?
Where's the fault .. ext_tables.php or still sth. in TCA is wrong? I really need a tip .. its frustrating ..
EDIT: sys_log entry
Core: Exception handler (WEB): Uncaught TYPO3 Exception: #1439288036: An item in field form of table tx_blah_domain_model_job is not an array as expected | UnexpectedValueException thrown in file /typo3_src/typo3_src-7.6.16/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php in line 1264.
EDIT 2: I think, there must be sth. in typo3conf/ext/blah/Configuration/TCA/tx_blah_domain_model_job.php
see TCA source code
and that's in line 1264
/**
* Sanitize incoming item array
*
* Used by TcaSelectItems and TcaSelectTreeItems data providers
*
* #param mixed $itemArray
* #param string $tableName
* #param string $fieldName
* #throws \UnexpectedValueException
* #return array
*/
public function sanitizeItemArray($itemArray, $tableName, $fieldName)
{
if (!is_array($itemArray)) {
$itemArray = [];
}
foreach ($itemArray as $item) {
if (!is_array($item)) {
throw new \UnexpectedValueException(
'An item in field ' . $fieldName . ' of table ' . $tableName . ' is not an array as expected',
1439288036
);
}
}
return $itemArray;
}

aTry to use this in the TCA tx_imappointments_domain_model_job.php
'form' => array(
'exclude' => 1,
'label' => 'LLL:EXT:im_appointments/Resources/Private/Language/locallang_db.xlf:tx_imappointments_domain_model_job.form',
'config' => array(
'type' => 'select',
'renderType' => 'selectSingle',
'items' => array(array('', 0)),
'foreign_table' => 'pages',
'foreign_table_where' => ' AND pages.pid = 293',
'minitems' => 0,
'maxitems' => 1,
),
),
'items' in 'form' has to be a array how your error message said:
https://docs.typo3.org/typo3cms/TCAReference/ColumnsConfig/Type/Select.html#items

Related

Query with orderings causing empty result - Extbase 6.2

I made an extbase extension and want to list my appointments ordered first by startDate and for those appointments that are on the same day I want to order them by the last name of the customer.
In my repository I made following working query:
public function findAppointmentsForList($future) {
$curtime = time();
$query = $this->createQuery();
$constraints = array();
if ($future !== NULL) {
$constraints[] = ($future) ?
$query->greaterThanOrEqual('startDate', $curtime) :
$query->lessThan('startDate', $curtime);
}
if ($constraints) {
$query->matching($query->logicalAnd($constraints));
} else {}
$orderings = array(
'startDate' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
// 'customer.lastName' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
);
$query->setOrderings($orderings);
return $query->execute();
}
It returns me some appointments so I assume it's working.
If I then uncomment the line 'customer.lastName... it returns 0 appointments.
What's going on? It's just the ordering, it can't possibly make the query smaller...
I don't even get any errors - I tried it with an invalid property for example and it gave me an error, so the property name is correct too.
And I debugged the working query and the last names in those customer objects where there.
This is my appointment model entry:
/**
* customer
*
* #var \vendor\extension\Domain\Model\Customer
*/
protected $customer = NULL;
And this is the TCA corresponding to it:
'customer' => array(
'exclude' => 1,
'label' => 'LLL:EXT:extension/Resources/Private/Language/locallang_db.xlf:tx_extension_domain_model_appointment.customer',
'config' => array(
'type' => 'select',
'foreign_table' => 'fe_users',
'minitems' => 0,
'maxitems' => 1,
),
),
EDIT: It's working now...but unfortunately I don't know why, changed too much in the meantime which I thought had nothing to do with this. One thing that might've affected this: startDate is of type Date and I noticed the query didn't filter it right so after I changed the curtime to new \DateTime('midnight') it was filtering correctly.
When you use related models in a query as part of the matching or orderBy then the query will be build with joins to the related tables. That means, that the result is actually smaller and will not include appointments without customers.
The strange thing is that you see the last names when you debug it, otherwise i would assume that you have some configuration errors in the TCA. Can you provide the TCA code from the apointment table and may be its model?

TYPO3 Extbase extension: Backend FAL Upload fails

I have set up an extension with the current extension_builder in TYPO3 6.2.11.
FAL File upload in the backend is not working.
extension_builder says that file upload isn't implemented at all in extbase, but as far as I understood (cf https://github.com/helhum/upload_example), this is regarding FE upload. Correct?
I only need completely regular BE file upload - select via "Create new relation" or "Select & upload files".
The direct upload fails with "Upload failed! A file with "*" extension is expected!" (or whatever extensions I specify in TCA).
The reference creation works, but the reference is lost after saving.
This screenshot shows the two tries before saving.
And after saving, empty again:
How do I make this work? Do I have to add extra code to the repo for saving the relation? Or might there be a basic setting missing?
For tt_content, FAL relations and upload work fine.
And: As a workaround, is it possible to use a regular "Pibase" 'type' => 'group','internal_type' => 'file' field? But how would getters and setters in the model look then? Just like a regular string?
TCA:
'apprenticeship_document' => array(
'exclude' => 1,
'label' => 'LLL:EXT:stellen/Resources/Private/Language/locallang_db.xlf:tx_stellen_domain_model_institution.apprenticeship_document',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'apprenticeshipDocument',
array('maxitems' => 1),
'*'
),
),
Model as created by extension_builder:
/**
* apprenticeshipDocument
*
* #var \TYPO3\CMS\Extbase\Domain\Model\FileReference
*/
protected $apprenticeshipDocument = NULL;
/**
* Returns the apprenticeshipDocument
*
* #return \TYPO3\CMS\Extbase\Domain\Model\FileReference $apprenticeshipDocument
*/
public function getApprenticeshipDocument() {
return $this->apprenticeshipDocument;
}
/**
* Sets the apprenticeshipDocument
*
* #param \TYPO3\CMS\Extbase\Domain\Model\FileReference $apprenticeshipDocument
* #return void
*/
public function setApprenticeshipDocument(\TYPO3\CMS\Extbase\Domain\Model\FileReference $apprenticeshipDocument) {
$this->apprenticeshipDocument = $apprenticeshipDocument;
}
I have also tried to use \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> instead of \TYPO3\CMS\Extbase\Domain\Model\FileReference $apprenticeshipDocument, but that doesn't make a difference either.
Your TCA definition has an error, the first argument of getFileFieldTCAConfig should be with lower underscore, not lowerCamelCase:
'apprenticeship_document' => array(
'exclude' => 1,
'label' => 'LLL:EXT:stellen/Resources/Private/Language/locallang_db.xlf:tx_stellen_domain_model_institution.apprenticeship_document',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'apprenticeship_document',
array('maxitems' => 1),
'pdf,doc,docx'
),
),
Apart from that, "*" is not a valid file extension. You need to define a comma-separated list of file extensions (e.g. 'doc,docx,pdf'). From reading the documentation, there is no wildcard for file extensions.
File upload in FE is not implemented in the Extension Builder, but perfectly possible with the solution provided by Helmut Hummel.

TYPO3 Extbase: How to sort child objects

I have an Extbase Model Article and a 1:n Relation Product. In Article TCA i have an inline field configuered. In my Article Template I want to display all related Products. These are oredered by uid. How can i change the ordering of the child objects to the field sorting to be able to manually sort them. ( In the backend form the sorting is possible, only diplaying them sorted by field sorting is not possible )
thanks,
Lukas
The easiest way to sort child elements in a object storage is to manipulate the TCA.
Example:
$TCA['tx_myext_domain_model_ordering'] = array(
...
'columns' => array(
'services' => array(
'exclude' => 0,
'label' => 'LLL:EXT:myext/Resources/Private/Language/locallang_db.xml:tx_myext_domain_model_ordering.services',
'config' => array(
'type' => 'inline',
'foreign_table' => 'tx_myext_domain_model_service',
'foreign_field' => 'ordering',
'foreign_sortby' => 'sorting',
'maxitems' => 9999,
'appearance' => array(
'collapseAll' => 0,
'levelLinksPosition' => 'top',
'showSynchronizationLink' => 1,
'showPossibleLocalizationRecords' => 1,
'showAllLocalizationLink' => 1
),
),
),
),
...
);
With the filed 'foreign_sortby' => 'sorting', you can easily say on which field the childs should be ordered.
Using the dot notation you can sort by properties of subobjects:
$query->setOrderings(array(
'sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
'subobject.sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
));
edit: Caught me off guard, I think I read your question wrong. Yes, this sorts by child objet, but it applies that to the parent object, of course. If you want to sort the child objects themselves, you have to set that sorting in the repository of the child object, as #Urs explained.
Here's how I do it, in the repository class:
class ItemRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
/**
* http://www.typo3.net/forum/thematik/zeige/thema/114160/?show=1
* Returns items of this repository, sorted by sorting
*
* #return array An array of objects, empty if no objects found
* #api
*/
public function findAll() {
$orderings = array(
'sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
);
$query = $this->createQuery();
$query->setOrderings($orderings);
$query->getQuerySettings()->setRespectSysLanguage(FALSE);
$query->getQuerySettings()->setSysLanguageUid(0);
$result = $query->execute();
return $result;
}
}
I dont't really like the idea of doing basic sorting inside the view (mvc).
The Downside of most Database abstraction Layers ist, that you are quite often restricted to either mixup mvc or have a (sometimes slightly) lower performance.
I am at the same point right now. I am thinking about retrieving the parents (with their children attached). Then go into every single parent and get children for this parent in a sorted way.
public function findAllSorted() {
$query = $this->createQuery();
/* sort parents */
$query->setOrderings(array('name' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));
$parents = $query->execute();
foreach($parents as $parent){
/* get children for every parent */
$children = $this->getChildrenSorted($parent);
// add children to parent TBD
}
/* Debug output */
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($parents);
}
public function getChildrenSorted(\mynamespace\ $parent) {
/* Generate an object manager and use dependency injection to retrieve children repository */
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('\TYPO3\CMS\Extbase\Object\ObjectManager');
$childrenRepository= $objectManager->get('MYNAME\Extname\Domain\Repository\Repository');
$children = $versionRepository->findSortedByName($parent);
return $children;
}
The function findSortedByName inside the children repos is using
$query->matching($query->equals('parent', $parent));
to retrieve only children of this parent and
$query->setOrderings(array('name' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));
to be able to give them back in an ordered way.
Warning: Depending on the size and quantity of all retrieved objects, this way might arise a huge performance issue.

In CakePHP am getting this error: "Fixture invalid: Count of fields does not match count of values"

When I am running test cases I am getting the above error: "Fixture invalid: Count of fields does not match count of values".
Can anyone say why I would be getting that? And how to fix it?
I must note that for my fixtures, I am automatically importing the table definition like so:
/**
* Import table definition
*
* #var string
*/
public $import = 'Category';
/**
* Records
*
* #var array
*/
public $records = array(
array(
'id' => 1,
'name' => 'Science',
'post_count' => 0
),
array(
'id' => 2,
'name' => 'Information Technology',
'post_count' => 0
),
array(
'id' => 3,
'name' => 'Philosophy',
'post_count' => 0
)
);
I am using CakePHP 2.5, xampp.
Ah, the error was explicit. I was importing the table definition for the model automatically, but had the wrong list of fields in the records section.

Extbase ObjectStorage returns a hashcode. But why?

I was just extending an existing Typo3 4.7 Extension with two own Model classes.
It runs quite well, Backendforms look like expected BUT when I try to access some SubObjects of my Model Classes in the templates via Object Accessor {class.subclass.attribute} I am not able to access the attribute. The problem that showed me, is that the Object for the Attribute "mainColor" for example in the Object Storage is a HashCode, which contains the Actual Object I want to access ( the object following the hashcode is the correct related object from the database ).
Does anyone of you have an Idea where the problem might be ?
If any more Code Snippets are needed, I will deliver them. But since I really don't know where the problem comes from, I prefer to not deliver a wall of Code.
Domain/Model/Cluster.php
/**
* Main Color of Cluster
* #var Tx_Extbase_Persistence_ObjectStorage<Tx_Alp_Domain_Model_ColorCombination> $mainColor
*/
protected $mainColor;
/**
* Subcolors of Cluster
* #var Tx_Extbase_Persistence_ObjectStorage<Tx_Alp_Domain_Model_ColorCombination> $subColors
*/
protected $subColors;
/**
* Constructor
* #return void
*/
public function __construct() {
$this->initStorageObjects();
}
/**
* Initializes all Tx_Extbase_Persistence_ObjectStorage properties.
* #return void
*/
protected function initStorageObjects() {
$this->subColors = new Tx_Extbase_Persistence_ObjectStorage();
$this->mainColor = new Tx_Extbase_Persistence_ObjectStorage();
}
TCA/Cluster.php
'sub_colors' => array(
'exclude' => 1,
'label' => 'Sub-Colors',
'config' => array(
// edited
'type' => 'inline',
'internal_type' => 'db',
'allowed' => 'tx_alp_domain_model_colorcombination',
'foreign_table' => 'tx_alp_domain_model_colorcombination',
'MM' => 'tx_alp_cluster_subcolorcombination_mm',
'MM_opposite_field' => 'parent_cluster',
'size' => 6,
'autoSizeMax' => 30,
'maxitems' => 9999,
'multiple' => 0,
'selectedListStyle' => 'width:250px;',
'wizards' => array(
'_PADDING' => 5,
'_VERTICAL' => 1,
'suggest' => array(
'type' => 'suggest',
),
),
),
),
Fluid Debug Output can be found here:
http://i60.tinypic.com/28kluub.jpg
Thanks for any help :(
And sorry for my bad English and this is my first question here, hope I did it right ;)
Unless you have a 1:1 relation from a model to a sub model, you cannot access the sub model because the sub model is an ObjectStorage.
Example:
Domain/Model/Cluster.php
/**
* Main Color of Cluster
* #var Tx_Alp_Domain_Model_ColorCombination $mainColor
*/
protected $mainColor;
This means that the Cluster model has exacly one main color (mind the annotation), this is a 1:1 relation.
Therefore using {cluster.mainColor.property} will work.
What you are doing is:
Domain/Model/Cluster.php
/**
* Main Color of Cluster
* #var Tx_Extbase_Persistence_ObjectStorage<Tx_Alp_Domain_Model_ColorCombination> $mainColor
*/
protected $mainColor;
This means that every Cluster can have multiple main colors, this is a 1:n relation. Therefore you must iterate through the mainColors (and call the property $mainColors):
<f:for each="{cluster.mainColors}" as="mainColor">
{mainColor.property}
</f:for>