joomla-cms
joomla-cms copied to clipboard
[6.0] Add a global master language for Multilingual Associations
This adds an optional global master language for the multilingual associations. The topic that had its beginnings in the two PR's #17881 and #17802 was tackled from scratch.
This gives each association a "Master-Child" relationship. This means that an associated item set with the master language is set as master and the items in the other languages are set as children. This makes it possible to add new association statuses to the already existing 'not associated' and 'associated' ones: the 'outdated' and 'up-to-date' status. These new statuses maintain the child elements in relation to their master. When associations are created, the children are given up-to-date status. If the master item is changed, the children will be set to outdated (if they were up-to-date until then). A distinction is made between whether the content history is enabled or not. The difference: content history only saves entries in which changes are really made. In the Associations List View a new filter for the Association States has been added.
To update an outdated child to up-to-date a new edit view is called, in which it is only possible to save and update the target (i.e. the outdated child). Here, too, a distinction is made between whether the content history is activated or not. If content history is activated, a customized Compare View of contenthistory is displayed. The changes of the master are displayed since the moment the child was set to outdated and to the current master. If it is content history disabled, the normal edit view of the reference/master is displayed. The user has to determine whether there are changes to the master or not. Advantage over before: by the status outdated you at least know that someone has saved the master.
Summary of Changes
- The Associations List View is the only List View in the backend that has the behavior that no content is displayed the first time this view is called. This is confusing, especially for users who have not yet spent long time with associations. To adapt this list view to the others so that a more uniform behavior is achieved in the backend, the filters for itemtype and language are filled with default values. This means that the two buttons 'delete all associations' and 'delete orphans' must always be displayed accordingly (otherwise they were hidden as soon as a list appears - see #21869). Delete All Associations no longer deletes all associations, but all associations with matching context.
- The colors for the association states 'associated' and 'not associated' have now changed everywhere: gray for 'not associated' and green for associated and 'up-to-date'. Orange now stands for 'outdated'.
- The option to set the global master language has been added to the languagefilter plugin.
- New columns in #__associations:
- master_id' in which the ID of the master item is stored for the child items otherwise 0 for the master item itself and
- 'master_date' where either the modified date or the save date of the history table of the master item is stored. The child item gets the same master date as its master item if they are newly associated or when the child item gets updated.
- Fix bug where newsfeeds and contacts get the same assoc key. To prevent associations from receiving the same association key, since id and language can be the same in different contexts, the context is also added as differentiation. As the bug appears only after my new queries (key query only), this is fixed here.
- For the masterlanguage see above.
Testing Instructions
- Install a new instance because there are changes in the sql.
- Install at least two languages. For example, install the multilingual sample data and then the normal sample data (so there is sample data for associated and non-associated items).
- Now no global master language is set yet. The behaviour of the associations should be the same as before. Only the colors have changed. No empty list appears in the Associations List View and the delete buttons are now always displayed.
- Go to the Languagefilter plugin and activate a global master language. Go back to the Associations List View. A new filter appears and the associations are displayed differently, also in other List Views with associations.
- Change a master item. With versions enabled (default) you need to really make changes and save the master in order to check if children gets 'outdated'. Update a child element.
Expected result
-
Associations List View without a global Master Language:
-
Articles List View without a global Master Language:
-
Set a global Master Language in the Languagefilter Plugin:
-
Associations List View with Global Master Language:
-
Articles List View with Global Master Language:
-
New Update/Edit View for outdated items with versions enabled:
Actual result
- No global Master Language Setting in the Languagefilter Plugin.
- No 'outdated' or 'up-to-date' association states.
- Associations List View:
- Articles List View:
Documentation Changes Required
Yes
@lavipr Looks good at a first look. But new schema update SQL scripts (name e.g. 4.0.0-2019-07-02.sql
) below folder administrator/components/com_admin/sql/updates
are missing for the database changes in joomla.sql. Will you add them later? Or do you need some help or advise with that?
@lavipr Looks good at a first look. But new schema update SQL scripts (name e.g.
4.0.0-2019-07-02.sql
) below folderadministrator/components/com_admin/sql/updates
are missing for the database changes in joomla.sql. Will you add them later? Or do you need some help or advise with that?
@richard67 Thank you. Indeed I need help or advice. That would be very helpful. I wasn't aware of that.
@lavipr I can make a PR for the schema updates against your branch, which you then can merge so it goes into this PR. Is that ok for you?
@lavipr I can make a PR for the schema updates against your branch, which you then can merge so it goes into this PR. Is that ok for you?
@richard67 That would be great! Thank you.
This looks like a lot of work - thanks
I will try to find some time tomorrow to do a real test
@brianteeman Thank you for your code review and your test. @SharkyKZ Thank you too.
@lavipr Before I make any schema update: Why did you use data type text
for the master_date
column? I would have expected date
for MySQL and timestamp without time zone
for postgresql if it really is a date. If you save there the string representation of a date, then it needs to check your code it that string representation will always be of same format, regardless of current language.
@lavipr In addition to my comment above about data type of master_date
column, I see that you use string
data type in your PHP functions for that master date value. And in PHP code you build SQL queries with master date comparisons in the where clauses. Such comparisons for smaller or larger (<
, >
) and so on work with string representations of dates and time only when format is always so that alphabetical order is always equal to numerical order, like it is e.g. for format YYYY-MM-DD hh:mm:ss
with hh
= 24 hour format.
@lavipr I strongly recommend to use date and time data types for dates and time in PHP and also in SQL and not string data types. Or do you have a really good reason why you did it differently?
@lavipr Before I make any schema update: Why did you use data type
text
for themaster_date
column? I would have expecteddate
for MySQL andtimestamp without time zone
for postgresql if it really is a date. If you save there the string representation of a date, then it needs to check your code it that string representation will always be of same format, regardless of current language.
@richard67 You are right. I'll change it. Thanks for your explanation.
@lavipr Ok, I'll wait with the schema updates. Ping me here when ready.
We currently don't support uppercase letters in layouts (IDK if there's a reason for this). So administrator/components/com_contenthistory/tmpl/compare/compareMaster.php
needs to be renamed.
Eager to test, but atm just a question: is it necessary to define the master/reference language in the language filter plugin, instead of com_associations Options?
I really like the idea of a master language and this whole PR is an awesome piece of code. Thanks for that!
But now the "but": I would really like to see this going further. Not one global master language but unlimited local master languages. Every item decides "automatically" their own master language (probably via parameter). Because I think on big news portals different languages could be the master language depending on the article (one original article is French, so French would be master here, other is English etc.).
So tl;tr: Don't stop here, but go deeper on item level for a more flexible approach!
Eager to test, but atm just a question: is it necessary to define the master/reference language in the language filter plugin, instead of com_associations Options?
@infograf768 The idea was that because the master language depends on the fact that item_associations is set, this can be also done there.
@lavipr I would prefer as it is anyway impossible to use com_associations if items associations is not set.
Not one global master language but unlimited local master languages
Beware as this is what blocked the gsoc project as it is extremely complex and confusing...
@lavipr Ok, I'll wait with the schema updates. Ping me here when ready.
Could you please have a look to my database changes: 5c321cb ? Thanks!
@lavipr Data type in database looks ok now. I will make the PR for the schema updates in a minute or two. But still in PHP you use string data type. How it should be done you can look up in other PHP code dealing with date/timestamp columns, like e.g. columns published_up
in several db tables.
@lavipr Data type in database looks ok now. I will make the PR for the schema updates in a minute or two. But still in PHP you use string data type. How it should be done you can look up in other PHP code dealing with date/timestamp columns, like e.g. columns
published_up
in several db tables.
@richard67 I also added update sqls. I will look for dealing with date/timestamps. Thanks!
@lavipr Hmm, just right now I have finished the update sqls, see https://github.com/lavipr/joomla-cms/pull/6
@lavipr Hmm, just right now I have finished the update sqls, see lavipr#6
Ah I forgot to add the new files to git... So I merged your PR. Thank you very much.
Welcome. I always try to help when desired. Now you have a lot to do with this prepared statement stuff from Harald, but I am sure you will manage that, too.
thank you for this big enhancement..and if you need any help on prepared statements, don't hesitate to ping me
Ah, and I forgot the PHP changes for datetime data type. Still a bit work, but on a good way.
Thank you!
thank you for this big enhancement..and if you need any help on prepared statements, don't hesitate to ping me
@alikon In fact, I would need help with the prepared statements. I'm trying to use them, but I always get an error when using ParameterType::Integer: 'Undefined class constant 'Integer'. I don't understand what the problem is.
I did import use Joomla\Database\ParameterType;
And used it like this for example:
$query = $db->getQuery(true)
->select($db->quoteName('master_date'))
->from($db->quoteName('#__associations'))
->where($db->quoteName('id') . ' = :id')
->where($db->quoteName('context') . ' = :context')
->bind(':id', $id, ParameterType::Integer)
->bind(':context', $context);
$db->setQuery($query);
@lavipr You have to use ParameterType::INTEGER
, i.e. the INTEGER
in capital letters..
See an example PR for the change to prepared statements here: https://github.com/joomla/joomla-cms/pull/25386.
@lavipr You have to use
ParameterType::INTEGER
, i.e. theINTEGER
in capital letters.. See an example PR for the change to prepared statements here: #25386.
Oh my bad... I think I've seen enough code today :D Thanks.
@lavipr No, not your bad, Harald's bad ;-) He gave you the example in the wrong way.