Ok,
After some investigation into the problem I found a non-upgrade safe solution that during local tests permanently fixes the problem. I am providing code here and a walk through of this for posterity sake since other developers may want to implement this on their end should they encounter this problem.
First:
The problem stems from how /modules/ModuleBuilder/parsers/parser.label.php operates. The addLabel method does not completely rebuild the labels, neither do any of the other methods, although they will read into them when changes are made.
Second:
This is a non-upgrade safe change and it is customer centric. It is designed for use by those who want Users driving development rather than developers pushing files into the system directly. I have tested the core functions of the label saves from multiple ways and it seems to work, but I have not done an exhaustive regression test.
Third:
Because it works from the user perspective first, it behaves much more like users expect in that both the views and ui are updated immediately and completely. Allowing them to export their changes in their entirety to packages for deployment to other sites.
Last:
This is a pseudo destructive approach to the problem in that I assume the user is right and the final authority on what ALL labels should be, not just the ones being changed.
The solution:
At line 275 of the 7.10.11 build of this a community fix to bug #51 makes a change very similar to this fix for relationship labels. After this block I put a call to a new method of self called “updateExtLabelLibraryFile” then place the following code block at the bottom of the class file as a new method.
public function updateExtLabelLibraryFile($moduleName='Accounts', $language='en_us', $changed_values=array())
{
//if there are changes, go ahead and update the array and save the work
if (count($changed_values) > 0) {
$extension_basepath = 'custom/Extension/modules/' . $moduleName . '/Ext/Language';
$module_path = 'custom/modules/'. $moduleName. '/Language/'. $language.'.lang.php';
$module_ext_path = 'custom/modules/'. $moduleName. '/Ext/Language/'. $language.'.lang.ext.php';
$rolled_up_modstrings_file = $language . '.' . $moduleName . 'Customizations.php';
$GLOBALS['log']->debug("ParserLabel::updateExtLabelLibraryFile: Updating the " . $moduleName . " module's extension roll up file [" . $extension_basepath . '/' . $rolled_up_modstrings_file . "].");
//Update the extension framework file
$rolled_up_mod_strings = array();
$iterator = new DirectoryIterator($extension_basepath);
foreach ($iterator as $fileinfo) {
if ($fileinfo->isFile()) {
include($fileinfo->getPathname());
if(count($mod_strings)>0){
$rolled_up_mod_strings = array_replace_recursive($rolled_up_mod_strings, $mod_strings);
}
}
}
$rolled_up_mod_strings = array_replace_recursive($rolled_up_mod_strings, $changed_values);
//dump the contents of the updated mod string array to an out variable for write to files
$date = new DateTime;
$date_string = $date->format('Y-m-d H:i:s');
$headerString = "<?php\n//This file was updated by the studio on ". $date_string. "\n";
$out = $headerString;
foreach ($rolled_up_mod_strings as $key => $val) {
$out .= override_value_to_string_recursive2('mod_strings', $key, $val);
}
//Overwrite the extension file
$handle_ext = fopen($extension_basepath . '/' . $rolled_up_modstrings_file, 'w');
fwrite($handle_ext, $out);
fclose($handle_ext);
//Overwrite the module file
$handle_mod = fopen($module_path, 'w');
fwrite($handle_mod, $out);
fclose($handle_mod);
//Overwrite the extension file
$handle_mod_ext = fopen($module_ext_path, 'w');
fwrite($handle_mod_ext, $out);
fclose($handle_mod_ext);
}
return true;
}
This block makes some assumptions, the most critical being that all of the mod_strings will be “rolled” up into a single custom file named Customizations.php in the custom/Extensions/modules//Ext/Language/ directory. The method will use php directory iterator to go over the other files and merge all of the mod_strings in this directory to a core array and then merge that with the changed elements of that array.
Since I’m more interested in providing a workable solution to my customer than some more elegant solution for every possible custom these assumptions are acceptable and future features can extend this to be more flexible.
However, of key function here is the roll up of changes. We assume that the admin user’s wishes trump everything else and Studio is in charge, NOT an ftp’er or deployment tool for individual files. Therefore, this method wipes all three locations for the file and forces the updated array to be put into all three locations. This way, future QRR’s will not change the files and Studio changes always win any contest of file version.