User tests: Successful: Unsuccessful:
See #7127
As title says.
The _associations row should be deleted for the item as well as for the associated item if we have only 2 associated items.
To test:
Create a multilingual site and set associations to Yes in the Languagefilter plugin.
Create an article for each language (first with 2 languages) and associate them.
Note their id.
Send to trash. Don't empty trash yet.
With phpMyadmin look at the _associations table for rows with the id and the context "com_content.item"
Empty trash.
Reload the phpmyAdmin page: the 2 items are still there.
Recreate 2 articles and Patch.
re-test. Both rows are now deleted from the _associations table.
Then test with 3 languages, associating 3 articles.
Now, only the article deleted will be deleted from the associations table, letting the 2 others associated as should.
This is also working for menu items, categories, contacts, newsfeeds.
Status | New | ⇒ | Pending |
Labels |
Added:
?
|
Rel_Number | 0 | ⇒ | 7127 |
Relation Type | ⇒ | Pull Request for |
Easy | No | ⇒ | Yes |
Milestone |
Added: |
Category | ⇒ | Libraries Multilanguage |
I think it should be possible to get the count and key with one query instead of two using a join.
SELECT count(*), as1.key
FROM `k2wod_associations` as as1
LEFT jOIN `k2wod_associations` as as2 ON as1.key = as2.key
WHERE as1.context = "com_content.item"
AND as1.id = 3
Please propose a PR against mine as I am not familiar with Join
See infograf768#19
Another thing I noted: You're hardcoding the context as $this->option . '.item'. This makes this code useless for any extension which has more than one item type. Eg my own extension where I have com_sermonspeaker.sermon, com_sermonspeaker.speaker and com_sermonspeaker.serie.
I haven't found yet where that context is created when saving the item, but we should use the same code that is used there to determine the correct context
Another thing I noted: You're hardcoding the context as $this->option . '.item'
As far as I could see, all associations have that kind of context (look at the table). I tested with all core ones.
Will look where it is created
In fact the context is created in each component when code exist for associations. It is not fetched from any existing code. It is arbitrary defined.
Example for article:
$query->clear()
->insert('#__associations');
foreach ($associations as $id)
{
$query->values($id . ',' . $db->quote('com_content.item') . ',' . $db->quote($key));
}
Aww, crap. That should probably have used the available $context at the time when that code was written instead of creating an own one :(
So we basically have no clue if that context is true or not for any given extension.
So this code does only work for the extensions following that naming. For all others it will fail and maybe even create issues. Eg imagine an extension that has two contexts, one with .item and another with another suffix. Then this code could possibly delete the wrong asssociations.
I think best would be if we can specify the association context in the model as a property. If that is defined and Associations are enabled, then act. Otherwise do nothing.
This would mean that the code by default would not do anything if the extension didn't opt-in by defining the proper context.
Such a property could actually also be used in the saving part. I think the code there is always the same, with only the context changing in each model.
Thanks for the patch! It reduces the number of lines drastically.
I guess the reason of this context issue is that it was copied from the original associations which were only set for menu "item" in 2.5. When implementing the associations for other components, it was a sort of copy/paste.
As long as we are B/C by changing as you suggest (in another PR I guess), I am OK with it.
The way it is done is almost as if it was set in the model for core components.
I guess we would add to this delete functionality a call for the real defined context.
Would be good to get feedback from developers who have added multilingual associations to their components...
I need to think a bit and find time to do the PR then. If I forget, please poke me
we could do something like:
lets add for the core components (here for article model)
/**
* The associations context for this content type (for example, 'com_content.item').
*
* @var string
* @since 3.5
*/
public $associationsContext = 'com_content.item';
and then, in this PR, change:
$assoc_context = $this->option . '.item';
to
$assoc_context = $this->associationsContext ? $this->associationsContext : $this->option . '.item';
What do you think?
We could even implement it in this PR if judged B/C.
=>later:
hmm. not so simple: although it would work for delete, we do use com_content.item
(in the article example) in multiple places.
Thinking loudly: we anyway will be B/C as the _associations table was never touched when deleting an item... Therefore we can implement the associationsContext and get it known by developers in 3.5.
You want it in this PR or as a follow up once this is merged?
Your choice. We could consider it is a different topic as it is a small refactoring to simplify code (and help 3pd implement multilang in their extensions). So may be better to make it another PR, this one being merged first.
We need first another tester for this one.
Agreed, it's quite a different topic and different to test.
Lets get that one merged first and afterwards do next
tested ok with menu, category and article
Status | Pending | ⇒ | Ready to Commit |
Thanks for testing. RTC
Labels |
Added:
?
|
Status | Ready to Commit | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2015-08-03 09:31:29 |
Closed_By | ⇒ | Kubik-Rubik |
Labels |
Removed:
?
|
Thank you @infograf768! Merged with 76cef74
This PR does not purge an existing _associations table from existing orphans associations.