Get information about an objects MySQL table
public get_table_info ( string $object_type, string $object, null $name = null, array $pod = null, array $field = null ) : array | boolean | ||
$object_type | string | |
$object | string | The object to look for |
$name | null | (optional) Name of the pod to load |
$pod | array | (optional) Array with pod information |
$field | array | (optional) Array with field information |
return | array | boolean |
/** * Recursively join tables based on fields * * @param array $traverse_recurse Array of traversal options * * @return array Array of table joins * * @since 2.0 */ function traverse_recurse($traverse_recurse) { global $wpdb; $defaults = array('pod' => null, 'fields' => array(), 'joined' => 't', 'depth' => 0, 'joined_id' => 'id', 'joined_index' => 'id', 'params' => new stdClass(), 'last_table_info' => array()); $traverse_recurse = array_merge($defaults, $traverse_recurse); $joins = array(); if (0 == $traverse_recurse['depth'] && !empty($traverse_recurse['pod']) && !empty($traverse_recurse['last_table_info']) && isset($traverse_recurse['last_table_info']['id'])) { $pod_data = $traverse_recurse['last_table_info']; } elseif (empty($traverse_recurse['pod'])) { if (!empty($traverse_recurse['params']) && !empty($traverse_recurse['params']->table) && 0 === strpos($traverse_recurse['params']->table, $wpdb->prefix)) { if ($wpdb->posts == $traverse_recurse['params']->table) { $traverse_recurse['pod'] = 'post_type'; } elseif ($wpdb->terms == $traverse_recurse['params']->table) { $traverse_recurse['pod'] = 'taxonomy'; } elseif ($wpdb->users == $traverse_recurse['params']->table) { $traverse_recurse['pod'] = 'user'; } elseif ($wpdb->comments == $traverse_recurse['params']->table) { $traverse_recurse['pod'] = 'comment'; } else { return $joins; } $pod_data = array(); if (in_array($traverse_recurse['pod'], array('user', 'comment'))) { $pod = $this->api->load_pod(array('name' => $traverse_recurse['pod'], 'table_info' => true)); if (!empty($pod) && $pod['type'] == $pod) { $pod_data = $pod; } } if (empty($pod_data)) { $pod_data = array('id' => 0, 'name' => '_table_' . $traverse_recurse['pod'], 'type' => $traverse_recurse['pod'], 'storage' => 'taxonomy' == $traverse_recurse['pod'] ? 'none' : 'meta', 'fields' => array(), 'object_fields' => $this->api->get_wp_object_fields($traverse_recurse['pod'])); $pod_data = array_merge($this->api->get_table_info($traverse_recurse['pod'], ''), $pod_data); } $traverse_recurse['pod'] = $pod_data['name']; } else { return $joins; } } else { $pod_data = $this->api->load_pod(array('name' => $traverse_recurse['pod'], 'table_info' => true), false); if (empty($pod_data)) { return $joins; } } if (isset($pod_data['object_fields'])) { $pod_data['fields'] = array_merge($pod_data['fields'], $pod_data['object_fields']); } $tableless_field_types = PodsForm::tableless_field_types(); $simple_tableless_objects = PodsForm::field_method('pick', 'simple_objects'); $file_field_types = PodsForm::file_field_types(); if (!isset($this->traversal[$traverse_recurse['pod']])) { $this->traversal[$traverse_recurse['pod']] = array(); } if ((empty($pod_data['meta_table']) || $pod_data['meta_table'] == $pod_data['table']) && (empty($traverse_recurse['fields']) || !isset($traverse_recurse['fields'][$traverse_recurse['depth']]) || empty($traverse_recurse['fields'][$traverse_recurse['depth']]))) { return $joins; } $field = $traverse_recurse['fields'][$traverse_recurse['depth']]; $ignore_aliases = array('wpml_languages', 'polylang_languages'); $ignore_aliases = $this->do_hook('traverse_recurse_ignore_aliases', $ignore_aliases, $field, $traverse_recurse); if (in_array($field, $ignore_aliases)) { return $joins; } $meta_data_table = false; if (!isset($pod_data['fields'][$field]) && 'd' == $field && isset($traverse_recurse['fields'][$traverse_recurse['depth'] - 1])) { $field = $traverse_recurse['fields'][$traverse_recurse['depth'] - 1]; $field_type = 'pick'; if (isset($traverse_recurse['last_table_info']['pod']['fields'][$field])) { $field_type = $traverse_recurse['last_table_info']['pod']['fields'][$field]['type']; } elseif (isset($traverse_recurse['last_table_info']['pod']['object_fields'][$field])) { $field_type = $traverse_recurse['last_table_info']['pod']['object_fields'][$field]['type']; } $pod_data['fields'][$field] = array('id' => 0, 'name' => $field, 'type' => $field_type, 'pick_object' => $traverse_recurse['last_table_info']['pod']['type'], 'pick_val' => $traverse_recurse['last_table_info']['pod']['name']); $meta_data_table = true; } // Fallback to meta table if the pod type supports it if (!isset($pod_data['fields'][$field])) { $last = end($traverse_recurse['fields']); if ('post_type' == $pod_data['type'] && !isset($pod_data['object_fields'])) { $pod_data['object_fields'] = $this->api->get_wp_object_fields('post_type', $pod_data); } if ('post_type' == $pod_data['type'] && isset($pod_data['object_fields'][$field]) && in_array($pod_data['object_fields'][$field]['type'], $tableless_field_types)) { $pod_data['fields'][$field] = $pod_data['object_fields'][$field]; } elseif (in_array($pod_data['type'], array('post_type', 'media', 'user', 'comment')) && 'meta_value' == $last) { $pod_data['fields'][$field] = PodsForm::field_setup(array('name' => $field)); } else { if ('post_type' == $pod_data['type']) { $pod_data['object_fields'] = $this->api->get_wp_object_fields('post_type', $pod_data, true); if ('post_type' == $pod_data['type'] && isset($pod_data['object_fields'][$field]) && in_array($pod_data['object_fields'][$field]['type'], $tableless_field_types)) { $pod_data['fields'][$field] = $pod_data['object_fields'][$field]; } else { return $joins; } } else { return $joins; } } } $traverse = $pod_data['fields'][$field]; if ('taxonomy' == $traverse['type']) { $traverse['table_info'] = $this->api->get_table_info($traverse['type'], $traverse['name']); } elseif (in_array($traverse['type'], $file_field_types)) { $traverse['table_info'] = $this->api->get_table_info('post_type', 'attachment'); } elseif (!in_array($traverse['type'], $tableless_field_types)) { $traverse['table_info'] = $this->api->get_table_info($pod_data['type'], $pod_data['name'], $pod_data['name'], $pod_data); } elseif (empty($traverse['table_info']) || in_array($traverse['pick_object'], $simple_tableless_objects) && !empty($traverse_recurse['last_table_info'])) { if (in_array($traverse['pick_object'], $simple_tableless_objects) && !empty($traverse_recurse['last_table_info'])) { $traverse['table_info'] = $traverse_recurse['last_table_info']; if (!empty($traverse['table_info']['meta_table'])) { $meta_data_table = true; } } elseif (!in_array($traverse['type'], $tableless_field_types) && isset($traverse_recurse['last_table_info']) && !empty($traverse_recurse['last_table_info']) && 0 == $traverse_recurse['depth']) { $traverse['table_info'] = $traverse_recurse['last_table_info']; } else { $traverse['table_info'] = $this->api->get_table_info($traverse['pick_object'], $traverse['pick_val'], null, $traverse['pod'], $traverse); } } if (isset($this->traversal[$traverse_recurse['pod']][$traverse['name']])) { $traverse = array_merge($traverse, (array) $this->traversal[$traverse_recurse['pod']][$traverse['name']]); } $traverse = $this->do_hook('traverse', $traverse, compact('pod', 'fields', 'joined', 'depth', 'joined_id', 'params')); if (empty($traverse)) { return $joins; } $traverse = pods_sanitize($traverse); $traverse['id'] = (int) $traverse['id']; if (empty($traverse['id'])) { $traverse['id'] = $field; } $table_info = $traverse['table_info']; $this->traversal[$traverse_recurse['pod']][$field] = $traverse; $field_joined = $field; if (0 < $traverse_recurse['depth'] && 't' != $traverse_recurse['joined']) { if ($meta_data_table && ('pick' != $traverse['type'] || !in_array(pods_var('pick_object', $traverse), $simple_tableless_objects))) { $field_joined = $traverse_recurse['joined'] . '_d'; } else { $field_joined = $traverse_recurse['joined'] . '_' . $field; } } $rel_alias = 'rel_' . $field_joined; if (pods_var('search', $traverse_recurse['params'], false) && empty($traverse_recurse['params']->filters)) { if (0 < strlen(pods_var('filter_' . $field_joined, 'get'))) { $val = absint(pods_var('filter_' . $field_joined, 'get')); $search = "`{$field_joined}`.`{$table_info['field_id']}` = {$val}"; if ('text' == $this->search_mode) { $val = pods_var('filter_' . $field_joined, 'get'); $search = "`{$field_joined}`.`{$traverse['name']}` = '{$val}'"; } elseif ('text_like' == $this->search_mode) { $val = pods_sanitize(pods_sanitize_like(pods_var_raw('filter_' . $field_joined))); $search = "`{$field_joined}`.`{$traverse['name']}` LIKE '%{$val}%'"; } $this->search_where[] = " {$search} "; } } $the_join = null; $joined_id = $table_info['field_id']; $joined_index = $table_info['field_index']; if ('taxonomy' == $traverse['type']) { $rel_tt_alias = 'rel_tt_' . $field_joined; if ($meta_data_table) { $the_join = "\n LEFT JOIN `{$table_info['pod_table']}` AS `{$field_joined}` ON\n `{$field_joined}`.`{$table_info['pod_field_id']}` = `{$traverse_recurse['rel_alias']}`.`{$traverse_recurse['joined_id']}`\n "; } else { $the_join = "\n LEFT JOIN `{$wpdb->term_relationships}` AS `{$rel_alias}` ON\n `{$rel_alias}`.`object_id` = `{$traverse_recurse['joined']}`.`ID`\n\n LEFT JOIN `{$wpdb->term_taxonomy}` AS `{$rel_tt_alias}` ON\n `{$rel_tt_alias}`.`taxonomy` = '{$traverse['name']}'\n AND `{$rel_tt_alias}`.`term_taxonomy_id` = `{$rel_alias}`.`term_taxonomy_id`\n\n LEFT JOIN `{$table_info['table']}` AS `{$field_joined}` ON\n `{$field_joined}`.`{$table_info['field_id']}` = `{$rel_tt_alias}`.`{$table_info['field_id']}`\n "; // Override $rel_alias $rel_alias = $field_joined; $joined_id = $table_info['field_id']; $joined_index = $table_info['field_index']; } } elseif (in_array($traverse['type'], $tableless_field_types) && ('pick' != $traverse['type'] || !in_array(pods_var('pick_object', $traverse), $simple_tableless_objects))) { if (pods_tableless()) { $the_join = "\n LEFT JOIN `{$table_info['meta_table']}` AS `{$rel_alias}` ON\n `{$rel_alias}`.`{$table_info['meta_field_index']}` = '{$traverse['name']}'\n AND `{$rel_alias}`.`{$table_info['meta_field_id']}` = `{$traverse_recurse['joined']}`.`{$traverse_recurse['joined_id']}`\n\n LEFT JOIN `{$table_info['meta_table']}` AS `{$field_joined}` ON\n `{$field_joined}`.`{$table_info['meta_field_index']}` = '{$traverse['name']}'\n AND `{$field_joined}`.`{$table_info['meta_field_id']}` = CONVERT( `{$rel_alias}`.`{$table_info['meta_field_value']}`, SIGNED )\n "; $joined_id = $table_info['meta_field_id']; $joined_index = $table_info['meta_field_index']; } elseif ($meta_data_table) { $the_join = "\n LEFT JOIN `{$table_info['pod_table']}` AS `{$field_joined}` ON\n `{$field_joined}`.`{$table_info['pod_field_id']}` = `{$traverse_recurse['rel_alias']}`.`{$traverse_recurse['joined_id']}`\n "; } else { $the_join = "\n LEFT JOIN `@wp_podsrel` AS `{$rel_alias}` ON\n `{$rel_alias}`.`field_id` = {$traverse['id']}\n AND `{$rel_alias}`.`item_id` = `{$traverse_recurse['joined']}`.`{$traverse_recurse['joined_id']}`\n\n LEFT JOIN `{$table_info['table']}` AS `{$field_joined}` ON\n `{$field_joined}`.`{$table_info['field_id']}` = `{$rel_alias}`.`related_item_id`\n "; } } elseif ('meta' == $pod_data['storage']) { if ($traverse_recurse['depth'] + 2 == count($traverse_recurse['fields']) && ('pick' != $traverse['type'] || !in_array(pods_var('pick_object', $traverse), $simple_tableless_objects)) && $table_info['meta_field_value'] == $traverse_recurse['fields'][$traverse_recurse['depth'] + 1]) { $the_join = "\n LEFT JOIN `{$table_info['meta_table']}` AS `{$field_joined}` ON\n `{$field_joined}`.`{$table_info['meta_field_index']}` = '{$traverse['name']}'\n AND `{$field_joined}`.`{$table_info['meta_field_id']}` = `{$traverse_recurse['joined']}`.`{$traverse_recurse['joined_id']}`\n "; $table_info['recurse'] = false; } else { $the_join = "\n LEFT JOIN `{$table_info['meta_table']}` AS `{$field_joined}` ON\n `{$field_joined}`.`{$table_info['meta_field_index']}` = '{$traverse['name']}'\n AND `{$field_joined}`.`{$table_info['meta_field_id']}` = `{$traverse_recurse['joined']}`.`{$traverse_recurse['joined_id']}`\n "; $joined_id = $table_info['meta_field_id']; $joined_index = $table_info['meta_field_index']; } } $traverse_recursive = array('pod' => pods_var_raw('name', pods_var_raw('pod', $table_info)), 'fields' => $traverse_recurse['fields'], 'joined' => $field_joined, 'depth' => $traverse_recurse['depth'] + 1, 'joined_id' => $joined_id, 'joined_index' => $joined_index, 'params' => $traverse_recurse['params'], 'rel_alias' => $rel_alias, 'last_table_info' => $table_info); $the_join = $this->do_hook('traverse_the_join', $the_join, $traverse_recurse, $traverse_recursive); if (empty($the_join)) { return $joins; } $joins[$traverse_recurse['pod'] . '_' . $traverse_recurse['depth'] . '_' . $traverse['id']] = $the_join; if ($traverse_recurse['depth'] + 1 < count($traverse_recurse['fields']) && !empty($traverse_recurse['pod']) && false !== $table_info['recurse']) { $joins = array_merge($joins, $this->traverse_recurse($traverse_recursive)); } return $joins; }
/** * Find items of a pod, much like WP_Query, but with advanced table handling. * * @param array $params An associative array of parameters * @param int $limit (optional) (deprecated) Limit the number of items to find, use -1 to return all items with no limit * @param string $where (optional) (deprecated) SQL WHERE declaration to use * @param string $sql (optional) (deprecated) For advanced use, a custom SQL query to run * * @return \Pods The pod object * @since 2.0 * @link http://pods.io/docs/find/ */ public function find($params = null, $limit = 15, $where = null, $sql = null) { $tableless_field_types = PodsForm::tableless_field_types(); $simple_tableless_objects = PodsForm::field_method('pick', 'simple_objects'); $this->params = $params; $select = '`t`.*'; if (!in_array($this->pod_data['type'], array('pod', 'table')) && 'table' == $this->pod_data['storage']) { $select .= ', `d`.*'; } if (empty($this->data->table)) { return $this; } $defaults = array('table' => $this->data->table, 'select' => $select, 'join' => null, 'where' => $where, 'groupby' => null, 'having' => null, 'orderby' => null, 'limit' => (int) $limit, 'offset' => null, 'page' => (int) $this->page, 'page_var' => $this->page_var, 'pagination' => (bool) $this->pagination, 'search' => (bool) $this->search, 'search_var' => $this->search_var, 'search_query' => null, 'search_mode' => $this->search_mode, 'search_across' => false, 'search_across_picks' => false, 'search_across_files' => false, 'filters' => $this->filters, 'sql' => $sql, 'expires' => null, 'cache_mode' => 'cache'); if (is_array($params)) { $params = (object) array_merge($defaults, $params); } if (is_object($params)) { $params = (object) array_merge($defaults, get_object_vars($params)); } else { $defaults['orderby'] = $params; $params = (object) $defaults; } $params = $this->do_hook('find', $params); $params->limit = (int) $params->limit; if (0 == $params->limit) { $params->limit = -1; } $this->limit = (int) $params->limit; $this->offset = (int) $params->offset; $this->page = (int) $params->page; $this->page_var = $params->page_var; $this->pagination = (bool) $params->pagination; $this->search = (bool) $params->search; $this->search_var = $params->search_var; $params->join = (array) $params->join; if (empty($params->search_query)) { $params->search_query = pods_var($this->search_var, 'get', ''); } // Allow orderby array ( 'field' => 'asc|desc' ) if (!empty($params->orderby) && is_array($params->orderby)) { foreach ($params->orderby as $k => &$orderby) { if (!is_numeric($k)) { $key = ''; $order = 'ASC'; if ('DESC' == strtoupper($orderby)) { $order = 'DESC'; } if (isset($this->fields[$k]) && in_array($this->fields[$k]['type'], $tableless_field_types)) { if (in_array($this->fields[$k]['pick_object'], $simple_tableless_objects)) { if ('table' == $this->pod_data['storage']) { if (!in_array($this->pod_data['type'], array('pod', 'table'))) { $key = "`d`.`{$k}`"; } else { $key = "`t`.`{$k}`"; } } else { $key = "`{$k}`.`meta_value`"; } } else { $pick_val = $this->fields[$k]['pick_val']; if ('__current__' == $pick_val) { $pick_val = $this->pod; } $table = $this->api->get_table_info($this->fields[$k]['pick_object'], $pick_val); if (!empty($table)) { $key = "`{$k}`.`" . $table['field_index'] . '`'; } } } if (empty($key)) { if (!in_array($this->pod_data['type'], array('pod', 'table'))) { if (isset($this->pod_data['object_fields'][$k])) { $key = "`t`.`{$k}`"; } elseif (isset($this->fields[$k])) { if ('table' == $this->pod_data['storage']) { $key = "`d`.`{$k}`"; } else { $key = "`{$k}`.`meta_value`"; } } else { foreach ($this->pod_data['object_fields'] as $object_field => $object_field_opt) { if ($object_field == $k || in_array($k, $object_field_opt['alias'])) { $key = "`t`.`{$object_field}`"; } } } } elseif (isset($this->fields[$k])) { if ('table' == $this->pod_data['storage']) { $key = "`t`.`{$k}`"; } else { $key = "`{$k}`.`meta_value`"; } } if (empty($key)) { $key = $k; if (false === strpos($key, ' ') && false === strpos($key, '`')) { $key = '`' . str_replace('.', '`.`', $key) . '`'; } } } $orderby = $key; if (false === strpos($orderby, ' ')) { $orderby .= ' ' . $order; } } } } // Add prefix to $params->orderby if needed if (!empty($params->orderby)) { if (!is_array($params->orderby)) { $params->orderby = array($params->orderby); } foreach ($params->orderby as &$prefix_orderby) { if (false === strpos($prefix_orderby, ',') && false === strpos($prefix_orderby, '(') && false === stripos($prefix_orderby, ' AS ') && false === strpos($prefix_orderby, '`') && false === strpos($prefix_orderby, '.')) { if (false !== stripos($prefix_orderby, ' DESC')) { $k = trim(str_ireplace(array('`', ' DESC'), '', $prefix_orderby)); $dir = 'DESC'; } else { $k = trim(str_ireplace(array('`', ' ASC'), '', $prefix_orderby)); $dir = 'ASC'; } $key = $k; if (!in_array($this->pod_data['type'], array('pod', 'table'))) { if (isset($this->pod_data['object_fields'][$k])) { $key = "`t`.`{$k}`"; } elseif (isset($this->fields[$k])) { if ('table' == $this->pod_data['storage']) { $key = "`d`.`{$k}`"; } else { $key = "`{$k}`.`meta_value`"; } } else { foreach ($this->pod_data['object_fields'] as $object_field => $object_field_opt) { if ($object_field == $k || in_array($k, $object_field_opt['alias'])) { $key = "`t`.`{$object_field}`"; } } } } elseif (isset($this->fields[$k])) { if ('table' == $this->pod_data['storage']) { $key = "`t`.`{$k}`"; } else { $key = "`{$k}`.`meta_value`"; } } $prefix_orderby = "{$key} {$dir}"; } } } $this->data->select($params); return $this; }