I have an extbase extension, where I have a model A with a relation to another model B. Model B has a lot of entries, so I dont want to assign every single value by clicking on it. So it would be nice if I would have a possibility to somehow select all entries.
I tried to do this like in the page settings the "Usergroup Accsess Rights" area (http://docs.typo3.org/typo3cms/TCAReference/Reference/Columns/Select/Index.html#columns-select-examples-multiple). To have mixed values (static and dynamic) the field has to be a CSV field. I use an itemsProcFunc, where i build my array and put the static value in. The "All Entries" entry has a -1 id.
BACKEND FORM OF MODEL A
Field of modal A Model B values
_______________________ _______________________
|All Entries | | All Entries |
| | |-----------------------|
| | | First |
| | | Second |
| | | Third |
| | | Fourth |
| | | ... |
|_______________________| |_______________________|
TCA of Model A for the field of Model B relations
$TCA['tx_myext_domain_model_promotion']['columns']['relToB'] = array(
'exclude' => 0,
'label' => relToB,
'config' => array(
'type' => 'select',
'foreign_table' => 'tx_myext_domain_model_modelB',
'size' => 10,
'autoSizeMax' => 30,
'maxitems' => 9999,
'multiple' => 0,
'itemsProcFunc' => 'myFunc',
'exclusiveKeys' => '-1',
),
);
So far so good, this is working now and i get the selected "All Entries" value in my DB. But now the problem is, that the extbase property mapping functionality is broken and I have to write manual SQL everywhere I used this field.
How would you solve this issue? Is there an other way to get the "Select all entries" use case solved?
Personally I would be in favor of a true MM relation instead of comma-separated lists that are considered bad style.
You could go for the following approaches:
Add a checkbox to your TCA called e.g. "use all entries". Then use a TCEmain (4.x)/DataHandler (6.x) hook to assign all entries to Model A if this checkbox is checked. On unchecking, remove all of them.
Use an itemsProcFunc in the TCA definition to create an own fieldtype that is identical with select, but adds an additional "select all entries" button that adds all entries by JavaScript.
If you need additional information on how to do it, comment the answer and I can elaborate.
Related
Im trying to setup a form with Gravity forms that automatically populates the field "Name of person" based on a quantity field.
So lets say a user sets product quantity to 1:
Then the list field shows 1 row with Name | Last name | Date of birth
But when a users sets product quantity to 4 im trying to achieven that automatically 4 rows are displayed like:
Row 1.
Name | Last name | Date of birth
Row 2.
Name | Last name | Date of birth
Row 3.
Name | Last name | Date of birth
Row 4.
Name | Last name | Date of birth
Im really hoping somebody can help me out with this issue.
Im stuck.
Thanks in advance.
We have a free snippet for that here:
https://gravitywiz.com/set-number-of-list-field-rows-by-field-value/
For your setup, you'll want to target the Product's quantity input:
new GWAutoListFieldRows( array(
'form_id' => {FORM_ID},
'list_field_id' => {LIST_FIELD_ID},
'input_html_id' => '#input_{PRODUCT_FIELD_ID}_3'
) );```
I use TYPO3 version 9.
I am trying to configure TCA selectMultipleSideBySide. I want to use without foreign table, I want to pass my own items. It displays correctly, but when I try to add more then 1 item, I get error:
These fields of record 3 in table "tx_scout24_domain_model_vehicle" have not been saved correctly: equipment! The values might have changed due to type casting of the database.
It because TYPO3 try to save data to main table, but not in mm table.
My current TCA:
'equipment' => array(
'label' => 'LLL:EXT:scout24/Resources/Private/Language/locallang_db.xlf:equipment',
'config' => array(
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'items' => \Istar\Scout24\Service\FieldService::getFields('equipment'),
'MM' => 'tx_scout24_vehicle_equipment_mm',
),
),
According to the documentation the values are stored as comma-separated values. It is not possible to use a MM relation table. To store the values the columns must be of type varchar. Because you can store one value it seems that the type of your columns is an int, which can be stored without a problem.
So you have to do:
Remove the MM relation in your configuration
Change your table column to varchar
I'm working on some application, and we're using postgres as our DB. I don't a lot of experience with SQL at all, and now i encountered a problem, that i can't find answer to.
So here's a problem:
We have privacy settings stored in separate table, and accessibility of each row of data depends on few rows of this privacy table.
Basically structure of privacy table is:
entityId | entityType | privacyId | privacyType | allow | deletedAt
-------------------------------------------------------------------
5 | user | 6 | user | f | //example entry
5 | user | 1 | user_all | t |
In two words, this settings mean, that user id5 allows to have access to his data to everybody except user id6.
So i get available data by query like:
SELECT <some_relevant_fields> FROM <table>
JOIN <join>
WHERE
(privacy."privacyId"=6 AND privacy."privacyType"='user' AND privacy.allow=true)
OR (
(privacy."privacyType"='user_all' AND privacy."deletedAt" IS NOT NULL)
AND
(privacy."privacyType"='user' AND privacy."privacyId"=6 AND privacy.allow!=false)
);
I know that this query is incorrect in this form, but i want you to get idea of what i try to achieve.
So it must check for field with its type/id and allow=true, OR check that user_all is not deleted(deletedAt field is null) and there is no field restricting access with allow=false to this user.
But it seems like postgres is chaining all expressions, so it overrides privacy."privacyType"='user_all' with 'user' at the end of expression, and returns no results, or returns data even if user "blocked", because 'user_all' exist.
Is there a way to write WHERE clause to return result if AND expression is true for 2 different rows, for example in code above: (privacy."privacyType"='user_all' AND privacy."deletedAt" IS NOT NULL) is true for one row AND (privacy."privacyType"='user' AND privacy."privacyId"=6 AND privacy.allow!=false) is true for other, or maybe check for absence of row with this values.
Is this what you want?
select <some_fields> from <table> where
privacyType='user_all' AND deletedAt IS NOT NULL
union
select <some_fields> from <table> where
privacyType='user' AND privacyId=6 AND allow<>'f';
You left join the table with itself and found what element doesnt have a match using the where.
SELECT p1.*
FROM privacy p1
LEFT JOIN privacy p2
ON p1."entityId" = p2."entityId"
AND p1."privacyType" = 'user_all'
AND p1."deletedAt" IS NULL
AND p2."privacyType"='user' AND
AND p2."privacyId"= 6
AND p2.allow!=false
WHERE
p2.privacyId IS NOT NULL
I have the following table structure with matching relations:
,---------. ,--------------. ,---------.
| Threads | | ThreadsUsers | | Users |
|---------| |--------------| |---------|
| id | | id | | id |
'---------' | thread_id | '---------'
| user_id |
'--------------'
This custom query in ThreadsTable is meant to find threads with a given number of participants. It works fine on mysql
public function findWithUserCount(Query $query, array $options)
{
return $query
->matching('Users')
->select([
'Threads.id',
'count' => 'COUNT(Users.id)'
])
->group('Threads.id HAVING count = ' . $options['count']);
}
However it fails on postgresql with the following error
PDOException: SQLSTATE[42703]: Undefined column: 7
ERROR: column "count" does not exist
LINE 1: ...ThreadsUsers.user_id)) GROUP BY Threads.id HAVING count = 2
The HAVING clause cannot reference column aliases defined in the SELECT clause. The documentation says:
Each column referenced in condition must unambiguously reference a grouping column, unless the reference appears within an aggregate function or the ungrouped column is functionally dependent on the grouping columns.
Since count is neither a "grouping column" (i.e. the subject of the GROUP BY clause) nor an aggregate function, it can't be used there.
So the correct form would presumably be (I don't know CakePHP, and the fact that you can inject SQL into the group call at all seems like a massively broken design for a query builder):
->group('Threads.id HAVING COUNT(Users.id) = ' . $options['count']);
On my database table I have
Key | Value
a | 1
a | 2
b | 11
c | 1
d | 2
b | 3
But I just need to get the items which keys are not duplicates of the previous rows. The desired result should be:
Key | Value
a | 1
b | 11
c | 1
d | 2
How could we get the desired result using entity-framework?
Note: we need the first value. Thank you very much.
var q = from e in Context.MyTable
group e by e.Key into g
select new
{
Key = g.Key,
Value = g.OrderBy(v => v.Value).FirstOrDefault()
};
You should look at either writing a View in the database and mapping your entity to that.
Or creating a DefiningQuery in the part of your EDMX (aka the bit that ends up in the SSDL file).
See Tip 34 for more information.
Conceptually both approaches allow you to write a view that excludes the 'duplicate rows'. The difference is just where the view lives.
If you have control over the database - I'd put the view in the database
If not you can put the view in your inside the and then map to that.
Hope this helps
Alex