CRM-17795 - Validate nested input
authorColeman Watts <coleman@civicrm.org>
Mon, 11 Jan 2016 15:15:00 +0000 (10:15 -0500)
committerColeman Watts <coleman@civicrm.org>
Mon, 11 Jan 2016 15:15:00 +0000 (10:15 -0500)
Civi/API/SelectQuery.php

index 3c0a7228f54f315c8e578131809c4788c00161a2..1743e90049a38e19408029602f7353b4cd20bc22 100644 (file)
@@ -228,6 +228,7 @@ class SelectQuery {
         $fkInfo = $this->addFkField($key);
         if ($fkInfo) {
           list($table_name, $column_name) = $fkInfo;
+          $this->validateNestedInput($key, $value);
         }
       }
       // I don't know why I had to specifically exclude 0 as a key - wouldn't the others have caught it?
@@ -450,6 +451,36 @@ class SelectQuery {
     return NULL;
   }
 
+  /**
+   * FIXME: This should more properly be done at the api wrapper level
+   *
+   * @param $fieldName
+   * @param $value
+   * @throws \Exception
+   */
+  private function validateNestedInput($fieldName, &$value) {
+    list($entity, $name, $spec) = $this->getNestedField($fieldName);
+    $params = array($name => $value);
+    \_civicrm_api3_validate_fields($entity, 'get', $params, $spec);
+    $value = $params[$name];
+  }
+
+  /**
+   * Helper function for validateNestedInput - should be removed when that function is
+   * @param $fieldName
+   * @return array
+   */
+  private function getNestedField($fieldName) {
+    $stack = explode('.', $fieldName);
+    $spec = $this->apiFieldSpec;
+    $fieldName = array_pop($stack);
+    foreach ($stack as $depth => $name) {
+      $entity = $spec[$name]['FKApiName'];
+      $spec = $spec[$name]['FKApiSpec'];
+    }
+    return array($entity, $fieldName, $spec);
+  }
+
   /**
    * Check permission to join onto another api entity
    *