/**
  * Builds the javascript file used by the clients
  *
  * @param array $data The metadata to build from
  * @param boolean $onlyReturnModuleComponents Indicator to return only module
  *                                            components
  * @return string A url to the file that was just built
  */
 protected function buildJavascriptComponentFile(&$data, $onlyReturnModuleComponents = false)
 {
     $platform = $this->platforms[0];
     $js = "(function(app) {\n SUGAR.jssource = {";
     $compJS = $this->buildJavascriptComponentSection($data);
     if (!$onlyReturnModuleComponents) {
         $js .= $compJS;
     }
     if (!empty($data['modules'])) {
         if (!empty($compJS) && !$onlyReturnModuleComponents) {
             $js .= ",";
         }
         $js .= "\n\t\"modules\":{";
         $allModuleJS = '';
         //Grab the keys this way rather than through $key => $value to preserve pass by reference for $data
         $modules = array_keys($data['modules']);
         foreach ($modules as $module) {
             $moduleJS = $this->buildJavascriptComponentSection($data['modules'][$module], true);
             if (!empty($moduleJS)) {
                 $allModuleJS .= ",\n\t\t\"{$module}\":{{$moduleJS}}";
             }
         }
         //Chop off the first comma in $allModuleJS
         $js .= substr($allModuleJS, 1);
         $js .= "\n\t}";
     }
     $js .= "}})(SUGAR.App);";
     $hash = md5($js);
     //If we are going to be using uglify to minify our JS, we should minify the entire file rather than each component separately.
     if (!inDeveloperMode() && SugarMin::isMinifyFast()) {
         $js = SugarMin::minify($js);
     }
     $path = "cache/javascript/{$platform}/components_{$hash}.js";
     if (!file_exists($path)) {
         mkdir_recursive(dirname($path));
         sugar_file_put_contents_atomic($path, $js);
     }
     return $this->getUrlForCacheFile($path);
 }