APIv4 explorer - move metadata into .ang.php file
[civicrm-core.git] / ang / api4Explorer / Explorer.js
index 5cc419a6461dd3709863328c71aee24befccdbd3..50e793565757df4ef12216ba6cd10ed38289883d 100644 (file)
     // Note: this function expects fieldList to be select2-formatted already
     function addJoins(fieldList, addWildcard, addPseudoconstant) {
       // Add entities specified by the join param
-      _.each(getExplicitJoins(), function(joinEntity, joinAlias) {
-        var wildCard = addWildcard ? [{id: joinAlias + '.*', text: joinAlias + '.*', 'description': 'All core ' + joinEntity + ' fields'}] : [],
-          joinFields = _.cloneDeep(entityFields(joinEntity));
+      _.each(getExplicitJoins(), function(join) {
+        var wildCard = addWildcard ? [{id: join.alias + '.*', text: join.alias + '.*', 'description': 'All core ' + join.entity + ' fields'}] : [],
+          joinFields = _.cloneDeep(entityFields(join.entity));
         if (joinFields) {
+          // Add fields from bridge entity
+          if (join.bridge) {
+            var bridgeFields = _.cloneDeep(entityFields(join.bridge)),
+              bridgeEntity = getEntity(join.bridge),
+              joinFieldNames = _.pluck(joinFields, 'name');
+            _.each(bridgeFields, function(field) {
+              if (
+                // Only include bridge fields that link back to the original entity
+                (!bridgeEntity.bridge[field.name] || field.fk_entity !== join.entity) &&
+                // Exclude fields with the same name as those in the original entity
+                !_.includes(joinFieldNames, field.name)
+              ) {
+                joinFields.push(field);
+              }
+            });
+          }
           if (addPseudoconstant) {
             addPseudoconstants(joinFields, addPseudoconstant);
           }
           fieldList.push({
-            text: joinEntity + ' AS ' + joinAlias,
-            description: 'Explicit join to ' + joinEntity,
-            children: wildCard.concat(formatForSelect2(joinFields, [], 'name', ['description'], joinAlias + '.'))
+            text: join.entity + ' AS ' + join.alias,
+            description: 'Explicit join to ' + join.entity,
+            children: wildCard.concat(formatForSelect2(joinFields, [], 'name', ['description'], join.alias + '.'))
           });
         }
       });
         path = alias.split('.');
       // First check explicit joins
       if (joins[alias]) {
-        return joins[alias];
+        return joins[alias].entity;
       }
       // Then lookup implicit links
       _.each(path, function(node) {
           }
         }
       });
+      _.each(params.join, function(join) {
+        // Add alias if not specified
+        if (!_.contains(join[0], 'AS')) {
+          join[0] += ' AS ' + join[0].toLowerCase();
+        }
+        // Remove EntityBridge from join if empty
+        if (!join[2]) {
+          join.splice(2, 1);
+        }
+      });
       _.each(objectParams, function(defaultVal, key) {
         if (params[key]) {
           var newParam = {};
             var val = _.cloneDeep(item[1]);
             // Remove blank items from "chain" array
             if (_.isArray(val)) {
-              _.eachRight(item[1], function(v, k) {
+              _.eachRight(item[1], function(v) {
                 if (v) {
                   return false;
                 }
               default:
                 format = 'raw';
             }
-            if (name === 'limit') {
+            if (name === 'limit' && $scope.action === 'get') {
               defaultVal = 25;
             }
             if (name === 'debug') {
             code += newLine + "->addChain('" + name + "', " + formatOOP(chain[0], chain[1], chain[2], 2 + indent);
             code += (chain.length > 3 ? ',' : '') + (!_.isEmpty(chain[2]) ? newLine : ' ') + (chain.length > 3 ? phpFormat(chain[3]) : '') + ')';
           });
+        } else if (key === 'join') {
+          _.each(param, function(join) {
+            code += newLine + "->addJoin(" + phpFormat(join).slice(1, -1) + ')';
+          });
         }
         else if (key !== 'checkPermissions') {
           code += newLine + "->set" + ucfirst(key) + '(' + phpFormat(param, 2 + indent) + ')';
         description: entityInfo.description,
         comment: entityInfo.comment,
         type: entityInfo.type,
+        since: entityInfo.since,
         see: entityInfo.see
       });
     }
 
   function getExplicitJoins() {
     return _.transform(params.join, function(joins, join) {
+      // Fix capitalization of AS
+      join[0] = join[0].replace(/ as /i, ' AS ');
       var j = join[0].split(' AS '),
         joinEntity = _.trim(j[0]),
         joinAlias = _.trim(j[1]) || joinEntity.toLowerCase();
-      joins[joinAlias] = joinEntity;
+      joins[joinAlias] = {
+        entity: joinEntity,
+        alias: joinAlias,
+        side: join[1] || 'LEFT',
+        bridge: _.isString(join[2]) ? join[2] : null
+      };
     }, {});
   }
 
         return comboName;
       }
       var linkName = fieldNames.shift(),
-        newEntity = getExplicitJoins()[linkName] || _.findWhere(links[entity], {alias: linkName}).entity;
+        join = getExplicitJoins()[linkName],
+        newEntity = join ? join.entity : _.findWhere(links[entity], {alias: linkName}).entity;
       return get(newEntity, fieldNames);
     }
   }