public static function parseRelationDetails($field, $model_name) { // parse the body of the relator method and // get the relation type, related model name, // intermediate model name (if many to many), // and custom key field names (if any) list($relator_mtd, $related_model_field) = explode('.', $field); list($relator_mtd_body, $relator_mtd_doccomment) = Helpers::getMethodBodyAndDocComment($model_name, $relator_mtd); // parse doc comment and get @filter helper, if any if (preg_match('/@filter ([\\w=&,]+)/', $relator_mtd_doccomment, $matches)) { $filters = explode('&', $matches[1]); } else { $filters = array(); } // parse the function body and get relation_type, // related model name, intermediate table name, // and keys, if any. $match = preg_match('/return \\$this->([\\w_]+)\\(([\'"\\w,\\s]+)/', $relator_mtd_body, $matches); list($full_match, $rel_type, $args) = $matches; $args = array_map(function ($x) { return trim($x, ' \''); }, explode(',', $args)); $related_model_name = array_shift($args); $related_full_model_name = Model::$auto_prefix_models . $related_model_name; list($inter_model_name, $key1, $key2) = array(null, null, null); switch ($rel_type) { case 'belongs_to': list($key1) = array_merge($args, array(null)); $key1 = Model::buildForeignKeyName($key1, $related_full_model_name); break; case 'has_one': case 'has_many': list($key1) = array_merge($args, array(null)); $key1 = Model::buildForeignKeyName($key1, $model_name); break; case 'has_many_through': list($inter_model_name, $key1, $key2) = array_merge($args, array(null, null, null)); $inter_model_name = Model::buildJoinClassName($inter_model_name, $model_name, $related_full_model_name); $key1 = Model::buildForeignKeyName($key1, $model_name); $key2 = Model::buildForeignKeyName($key2, $related_model_name); break; } return array('relator_mtd' => $relator_mtd, 'related_model_field' => $related_model_field, 'type' => $rel_type, 'related_model_name' => $related_model_name, 'inter_model_name' => $inter_model_name, 'key1' => $key1, 'key2' => $key2, 'filters' => $filters); }