Iāve been combing through old posts all day on this topic, reviewing the code and the database tables trying to figure out whatās going on without any luck (or direction to go in!). Thought it might be a good idea to start a new thread rather than bump a bunch of old ones.
I can add group email accounts, I can see them as administrator but canāt assign them to users properly or have the users be able to see the group inbox folders.
Does anyone have this working? If so, please help! Iāve seen all the existing threads and also the bug report on Github. Kind of looking for something new if anyone has insight.
Hereās what Iāve found so farā¦
I can confirm there is still an issue here. 7.12.8. Iāve done a bunch of testing as well. What Iāve found so farā¦
My folders_subscription is getting populated properly in the DB
An older group email that I added has no issues.
A recent group email I canāt have users see it. (Admin works no problem).
I can add the folder subscriptions by logging in as admin to the user. (However, the popup says āsavedā but they are never saved, if I re-open the user, they are gone).
The folder subscriptions are not available for the user when logged in as the user!!!
Iāve added a video here demonstrating whatās happening.
Iāve tried the usual stuff like file permissions/ownership and examining the folder_subscription table in the Database (which looks like itās properly associating the folder with the user.
The only errors I get are about duplicate folders being detected. Iāve checked, there are no duplicate folders. I think when I save, itās trying to re-add the folders that are already in the table, and thus the error. Which I donāt think is a problem, because the folder ARE in the table.
I found this screen shot from SugarCRM from 9 years ago. Wondering if its from CE? It appears some functionality is missing in SuiteCRM that was there to select the team the group email was assigned to.
Anyone know the history on this and how we got to where we are now?
āTeamsā were SugarCRM Pro features, if Iām not mistaken.
I think that Group Emails should work in SuiteCRM, though these configurations are always a bit fragile. I would recommend trying things out with a really simple email account, nothing Gmail or Hotmail or Azure, nothing OAuth or whatever. Just plain user/password account. I use gmx.com emails for all my tests.
Another thing that you might want to check is how things are saved in the DB. Double-check everything in inbound_email, outbound_email, including the fields that are Base64 encoded.
Thanks for pointing me in the right direction @pgr Iāll have a look at that file.
Iām using just a standard imap email from cpanel. It works no problem if Iām signed in as admin, itās only when signed in as a user that doesnāt work. Iāve checked all the database tables and they appear to have the correct associations. This blog article on how the email folders work was super helpful in understanding it.
One other bug Iāve found while troubleshooting this is that if Admin creates the āpersonalā inbound or outbound email account for a user, itās not available for the user either. This I solved because the āassigned userā of the email account ends up being admin and then the user doesnāt have access. By changing it to the user in the DB solves this issue, and this is what happens when the user creates their own email account. However, this is not the same thing going on with group emails. Itās super puzzling because it seems itās making the correct entries in the DB for it to work. Iām suspecting it might be a security group or role issue thatās preventing the inboxes from showing. However, I canāt find a way to associate the inbound email account with a security group or role.
Where the id is the folder ID of the inbox, the user can see the inbox! So the issue (I think?) is with the email account switcher in the email module. For whatever reason, it doesnāt show the group email inbox as an option. However, the user clearly has access to it!
Ok need a little help here. Iām so close to fixing the group emails problem (I think!!!). I found exactly where the problem is, actually there are a few problems.
in the folders table āis_groupā is not getting populated. Thatās a problem for another day, I just manually changed to ā1ā for now.
There is an error in the code āisgroupā should be āis_groupā. I fixed that. Easy. Now the real problemā¦
In SugarFolders.php in the function retrieveFoldersForProcessingā¦
There is a filter I guess to filter out non group folders. In fact, if I change it up to not equal to one, I can see all folders as a user. I think we want the condition to be only IF, itās the account created by the user OR if itās a group account. However, the condition for āis_groupā never returns true. My php skills to deal with arrays of arrays are not that great. Please help if you can!!! Here is the filter as well as the output (example) from the $return array:
So I want to show this one because group_id=1, the other two conditions seem to work of āis adminā and ācreated byā Itās just this one thatās not returning true on this line:
Iāve tried a bunch of different things and just canāt get it to return true for āis_groupā Iām sure itās PHP 101 type thing, I just canāt get it.
Iāve tried this too and it doesnāt return true:
if ($item['is_group'] === 1 || $item['created_by'] === $user->id ) {
This works and shows subscribed folders that are marked as āis_groupā =1 Now I just have to tackle the problem of why the āis_groupā is not getting populated when a group account is created.
The strict comparison === requires that the data types are exactly the same, not just āequivalentā. I am not sure, but perhaps it would be better, instead of giving it the string datatype with === '1' like you did, to just relax the comparison to == 1.
This would depend on the rest of the code that writes the value into the array.
Itās possible that a similar issue is breaking the code regarding the other issues you found.
Writing $item['is_group'] should be equivalent here to $item->is_group.
So, if this works, thatās how Iād suggest leaving it:
Thanks for that insight! I was going crazy why it didnāt return true. I never even thought to look at the equivalency. I tried your suggestion, it does not return true. However, I modified my change to be less restrictive as you suggest, and it works, and also the other issue I was having was after the change it was crashing out the folder selection in the user profile. That seems to work. Iāll do some more testing around this. Also my next problem is that when you create or update a group account, it doesnāt write āis_groupā = 1 to the folders table. Iām going to work on that next.
Ok for those following along in this thread⦠Whooo hoo! Iāve solved the second problem that group email folders donāt get marked with āis_group=1ā when create or updated. So now with the below and my previous change, users should see group email folders .
Still issues:
I noticed inbound email folders donāt get deleted when the inbound email account is deleted. Iāll have to figure that out.
In the user settings, selecting the subscribed folders does not save correctly and gives user access to all group folders.
Anyway, hereās what Iāve done to fix the āis_groupā problem.
public function save($addSubscriptions = true)
{
$this->dynamic_query = $this->db->quote($this->dynamic_query);
// //////////////////////////////////////////////////////////////CHANGE
// Retrieve the value of 'is_personal' for the current folder
// Check if the current folder is a parent folder
if (!empty($this->parent_folder)) {
$query2 = "SELECT is_personal FROM inbound_email WHERE id = " . $this->db->quoted($this->parent_folder);
} else {
$query2 = "SELECT is_personal FROM inbound_email WHERE id = " . $this->db->quoted($this->id);
}
$r2 = $this->db->query($query2);
$is_personal = $this->db->fetchByAssoc($r2)['is_personal'];
// Set the value of 'is_group' based on the value of 'is_personal'
if ($is_personal == 1) {
$is_group = 0;
} else {
$is_group = 1;
}
////////////////////////////////////END CHANGES
if ((!empty($this->id) && $this->new_with_id == false) || (empty($this->id) && $this->new_with_id == true)) {
if (empty($this->id) && $this->new_with_id == true) {
$guid = create_guid();
$this->id = $guid;
}
$query = "INSERT INTO folders (id, name, folder_type, parent_folder, has_child, is_group, " .
"is_dynamic, dynamic_query, assign_to_id, created_by, modified_by, deleted) VALUES (" .
$this->db->quoted($this->id) . ", " .
$this->db->quoted($this->name) . ", " .
$this->db->quoted($this->folder_type) . ", " .
$this->db->quoted($this->parent_folder) . ", " .
$this->db->quoted($this->has_child) . ", " .
////////////////////////////////////////////////////////CHANGE
// $this->db->quoted($this->is_group) . ", " .//remove
$this->db->quoted($is_group) . ", " . // set the value of is_group here
//////////////////////////////////////////////////////////////END CHANGE
$this->db->quoted($this->is_dynamic) . ", " .
$this->db->quoted($this->dynamic_query) . ", " .
$this->db->quoted($this->assign_to_id) . ", " .
$this->db->quoted($this->currentUser->id) . ", " .
$this->db->quoted($this->currentUser->id) . ", 0)";
if ($addSubscriptions) {
// create default subscription
$this->addSubscriptionsToGroupFolder();
}
// if parent_id is set, update parents has_child flag
if (!empty($this->parent_folder)) {
$query3 = "UPDATE folders SET has_child = 1 WHERE id = " . $this->db->quoted($this->parent_folder);
$r3 = $this->db->query($query3);
}
} else {
$query = "UPDATE folders SET " .
"name = " . $this->db->quoted($this->name) . ", " .
"parent_folder = " . $this->db->quoted($this->parent_folder) . ", " .
"dynamic_query = " . $this->db->quoted($this->dynamic_query) . ", " .
"assign_to_id = " . $this->db->quoted($this->assign_to_id) . ", " .
"modified_by = " . $this->db->quoted($this->currentUser->id) . ", " .
// CHANGE
"is_group = " . $is_group . " " .
// END CHANGE
"WHERE id = " . $this->db->quoted($this->id);
}
return $this->db->query($query, true);
}
Ok working on problem #3:When an inbound email account is deleted it doesnāt remove them from the folders table or the folders_subscription table and the users can see deleted inbound accounts in their listview (assuming 1 and 2 are fixed above) . There is a function to do this in SugarFolders.php but is never gets called.
I found that when an inbound email address getās deleted, it runs \suitecrm\modules\InboundEmail/Delete.php
This is great! Now I know where to call the function delete() from SugarFolders.php.
HOWEVER, there is no relationship between the inbound email account and the Folders!!!
I donāt know how to pass the ID of the parent folder because there is no relation I can see to the inbound email account!
As an example Inbound email account ID = 9fd6f2b6-d27e-3a30-3860-646916d7b037
It has: Group Folder ID = 995b9d97-1d42-ef53-d1a6-64691630c162
and Group ID = 9959fa3c-0e7f-103d-5416-6469165df7eb (in inbound_email table)
Neither of which correspond to anything else in the database!
The ID of the parent folder (in folders table) that should be related to this is:
a6ae099b-15d2-f2bc-9a67-64691642f9bf
Thereās no way to ID the folders to be deleted from the inbound email account. I guess I could look for the email address, but thatās not exact. Am I missing something does anyone know how Iād relate the Inbound email record in the DB to the folder record? (youād think it would be by group folder ID but itās not!). Maybe thatās another problem!!! When folders get created youād think the group folder ID should reference the inbound email account ID.
Iām thinking to use the email address to match. I donāt really like that because it stores the email login (which in most cases is the email address) to match the folder. So Iād have to match on email address and is_group =1. I think that would pretty much limit it. Iād much rather match on an ID. I was thinking in a case for example where a user added sales@domain.com as a personal and the admin also setup a group account sales@domian.com. I guess though if I limit it to is_group=1 and deleted=0 then for the most part, Iām getting the right parent folder associated with the email account. It would be so much easier if there was a key to match on. Itās too bad the groupfolder_id isnāt the inbound email account ID.
Ok got it duh, the āinboxā folder ID = the inbound account id and then the sub folders, have a parent ID of the inbox folder!!! OK this works. I was looking at the top level folder. Not sure why this has a different ID, but anyway, I think I can use to solve.
Paul, I think itās great that youāre taking the time to really dive into this.
If you have any PHP questions that I can help with, feel free to ask. My time is well spent helping you because you help others, and because youāre clearly a good learner and making good progress as a developer.
Thanks @pgr, youāve been a huge help over the years with SuiteCRM and given me just the right kind of feedback to keep me going in the right direction. While Iāve done a lot of front end web stuff with HTML and CSS, Iāve been really learning a lot of PHP over the last year or so mostly. Diving into these kinds of problems really helps me learn a ton, plus itās the least I can do to give back to the community for a great CRM! I get most of the coding structures, (I learned them on a PET computer in BASIC 40 years ago if you can believe it!), I just donāt have the day to day experience with all the syntax of PHP yet, which is where I struggle.
Still trying to get the deleted folders of a deleted email account marked as deleted. There seems to be functionality to do this in SugarFolders.php = public function delete()
Ok, I think Iām fundamentally misunderstanding something here.
When an inbound email account gets deleted. modules/InboundEmail/delete.php is called. Great.
I need to now run delete() public function in /include/SugarFolders/SugarFolders.php
Iāve already figured out how to get $inboundEmailID of the current account being deleted and the $current_user.
Iām trying to call the public function delete like thisā¦
require_once('include/SugarFolders/SugarFolders.php');
$sugarFolders = new SugarFolder();
$sugarFolders->id = $inboundEmailId; // Set the ID of the folder to be deleted
$sugarFolders->currentUser = $current_user; // Set the current user object
$sugarFolders->delete();
I have an object when I echo out $sugarFolders, but the delete function is just not getting executed (I have a log there too).
Not sure, do I need to do something like $sugarFolders->retrieve($inboundEmailId); first (I tried that too and didnāt work)?
Ok, making progress! Never fails, as soon as I post a question another idea pops into my head.
Ok so trying to set the currentUser messed it up.
require_once('include/SugarFolders/SugarFolders.php');
$sugarFolder = new SugarFolder();
$sugarFolder->retrieve($inboundEmailId); // Get the folder to be deleted
$sugarFolder->delete();
}
Whoo hoo! delete is now being executed. Still not marking the folders deleted = ā1ā but thatā s tomorrowās problem. Now I have to troubleshoot the delete() function and deleteChildrenCascade() function.
I would try (in the new SugarFolders command) calling the constructor with as many arguments as you have available.
Check those defaults there, no use in passing values if they are the same as those.
You can see thereās preparatory code there in the constructor, you should get a more functional object if you initialize it properly, not just add values to member properties.
Thanks @pgr problem #3 solved. Iāve successfully called the delete() function and it works as intended without any further modification. All related folders to the parent INBOX that is being deleted get marked deleted =1, including the parent INBOX folder. Ok on to problem #4.
This is what I added to Delete.php. Iām going to to a pull request. Iāve tested a couple of times. Just want to test with a user that is not admin and see what happens.
//delete related folders by calling delete() in SugarFolders.php
// Retrieve the ID of the inbound email account being deleted
$inboundEmailId = $focus->id;
// Create an instance of the SugarFolders class
require_once('include/SugarFolders/SugarFolders.php');
$sugarFolder = new SugarFolder();
$sugarFolder->retrieve($inboundEmailId); // Get the folder to be deleted
$sugarFolder->delete();
}