joomla-cms icon indicating copy to clipboard operation
joomla-cms copied to clipboard

[6.0] Add a global master language for Multilingual Associations

Open lavipr opened this issue 5 years ago • 101 comments

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: image

  • Articles List View without a global Master Language: image

  • Set a global Master Language in the Languagefilter Plugin: SetGlobalMaster

  • Associations List View with Global Master Language: image

  • Articles List View with Global Master Language: image

  • New Update/Edit View for outdated items with versions enabled: image

Actual result

  • No global Master Language Setting in the Languagefilter Plugin.
  • No 'outdated' or 'up-to-date' association states.
  • Associations List View: FirstEntryAssociations
  • Articles List View: image

Documentation Changes Required

Yes

lavipr avatar Jul 02 '19 11:07 lavipr

@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?

richard67 avatar Jul 02 '19 12:07 richard67

@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?

@richard67 Thank you. Indeed I need help or advice. That would be very helpful. I wasn't aware of that.

lavipr avatar Jul 02 '19 12:07 lavipr

@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 avatar Jul 02 '19 13:07 richard67

@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.

lavipr avatar Jul 02 '19 13:07 lavipr

This looks like a lot of work - thanks

I will try to find some time tomorrow to do a real test

brianteeman avatar Jul 02 '19 13:07 brianteeman

@brianteeman Thank you for your code review and your test. @SharkyKZ Thank you too.

lavipr avatar Jul 02 '19 13:07 lavipr

@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.

richard67 avatar Jul 02 '19 13:07 richard67

@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.

richard67 avatar Jul 02 '19 13:07 richard67

@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?

richard67 avatar Jul 02 '19 13:07 richard67

@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.

@richard67 You are right. I'll change it. Thanks for your explanation.

lavipr avatar Jul 02 '19 13:07 lavipr

@lavipr Ok, I'll wait with the schema updates. Ping me here when ready.

richard67 avatar Jul 02 '19 13:07 richard67

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.

SharkyKZ avatar Jul 02 '19 14:07 SharkyKZ

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 avatar Jul 02 '19 14:07 infograf768

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!

bembelimen avatar Jul 02 '19 14:07 bembelimen

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 avatar Jul 02 '19 14:07 lavipr

@lavipr I would prefer as it is anyway impossible to use com_associations if items associations is not set.

infograf768 avatar Jul 02 '19 14:07 infograf768

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...

infograf768 avatar Jul 02 '19 14:07 infograf768

@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 avatar Jul 02 '19 19:07 lavipr

@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 avatar Jul 02 '19 19:07 richard67

@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 avatar Jul 02 '19 19:07 lavipr

@lavipr Hmm, just right now I have finished the update sqls, see https://github.com/lavipr/joomla-cms/pull/6

richard67 avatar Jul 02 '19 19:07 richard67

@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.

lavipr avatar Jul 02 '19 19:07 lavipr

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.

richard67 avatar Jul 02 '19 19:07 richard67

thank you for this big enhancement..and if you need any help on prepared statements, don't hesitate to ping me

alikon avatar Jul 02 '19 19:07 alikon

Ah, and I forgot the PHP changes for datetime data type. Still a bit work, but on a good way.

richard67 avatar Jul 02 '19 19:07 richard67

Thank you!

lavipr avatar Jul 02 '19 19:07 lavipr

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 avatar Jul 02 '19 20:07 lavipr

@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.

richard67 avatar Jul 02 '19 20:07 richard67

@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: #25386.

Oh my bad... I think I've seen enough code today :D Thanks.

lavipr avatar Jul 02 '19 20:07 lavipr

@lavipr No, not your bad, Harald's bad ;-) He gave you the example in the wrong way.

richard67 avatar Jul 02 '19 20:07 richard67