/** * Changes database results into REST API entities * @param \EEM_Base $model * @param array $db_row like results from $wpdb->get_results() * @param string $include string indicating which fields to include in the response, * including fields on related entities. * Eg, when querying for events, an include string like: * "...&include=EVT_name,EVT_desc,Datetime, Datetime.Ticket.TKT_ID, Datetime.Ticket.TKT_name, Datetime.Ticket.TKT_price" * instructs us to only include the event's name and description, * each related datetime, and each related datetime's ticket's name and price. * Eg json would be: * '{ * "EVT_ID":12, * "EVT_name":"star wars party", * "EVT_desc":"this is the party you are looking for...", * "datetimes":[{ * "DTT_ID":123,..., * "tickets":[{ * "TKT_ID":234, * "TKT_name":"student rate", * "TKT_price":32.0 * },...] * }] * }', * ie, events with all their associated datetimes * (including ones that are trashed) embedded in the json object, * and each datetime also has each associated ticket embedded in its json object. * @param string $context one of the return values from EEM_Base::valid_cap_contexts() * @return array ready for being converted into json for sending to client */ public function create_entity_from_wpdb_result($model, $db_row, $include, $context) { if ($include == null) { $include = '*'; } if ($context == null) { $context = \EEM_Base::caps_read; } $result = $model->deduce_fields_n_values_from_cols_n_values($db_row); $result = array_intersect_key($result, $this->get_model_version_info()->fields_on_model_in_this_version($model)); foreach ($result as $field_name => $raw_field_value) { $field_obj = $model->field_settings_for($field_name); $field_value = $field_obj->prepare_for_set_from_db($raw_field_value); if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) { unset($result[$field_name]); } elseif ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format())) { $result[$field_name] = array('raw' => $field_obj->prepare_for_get($field_value), 'rendered' => $field_obj->prepare_for_pretty_echoing($field_value)); } elseif ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format())) { $result[$field_name] = array('raw' => $field_obj->prepare_for_get($field_value), 'pretty' => $field_obj->prepare_for_pretty_echoing($field_value)); } elseif ($field_obj instanceof \EE_Datetime_Field) { if ($raw_field_value instanceof \DateTime) { $raw_field_value = $raw_field_value->format('c'); } $result[$field_name] = mysql_to_rfc3339($raw_field_value); } else { $value_prepared = $field_obj->prepare_for_get($field_value); $result[$field_name] = $value_prepared === INF ? EE_INF_IN_DB : $value_prepared; } } if ($model instanceof \EEM_CPT_Base) { $attachment = wp_get_attachment_image_src(get_post_thumbnail_id($db_row[$model->get_primary_key_field()->get_qualified_column()]), 'full'); $result['featured_image_url'] = !empty($attachment) ? $attachment[0] : null; $result['link'] = get_permalink($db_row[$model->get_primary_key_field()->get_qualified_column()]); } //add links to related data $result['_links'] = array('self' => array(array('href' => $this->get_versioned_link_to(\EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) . '/' . $result[$model->primary_key_name()]))), 'collection' => array(array('href' => $this->get_versioned_link_to(\EEH_Inflector::pluralize_and_lower($model->get_this_model_name()))))); global $wp_rest_server; if ($model instanceof \EEM_CPT_Base && $wp_rest_server instanceof \WP_REST_Server && $wp_rest_server->get_route_options('/wp/v2/posts')) { $result['_links'][\EED_Core_Rest_Api::ee_api_link_namespace . 'self_wp_post'] = array(array('href' => rest_url('/wp/v2/posts/' . $db_row[$model->get_primary_key_field()->get_qualified_column()]), 'single' => true)); } //filter fields if specified $includes_for_this_model = $this->extract_includes_for_this_model($include); if (!empty($includes_for_this_model)) { if ($model->has_primary_key_field()) { //always include the primary key $includes_for_this_model[] = $model->primary_key_name(); } $result = array_intersect_key($result, array_flip($includes_for_this_model)); } //add meta links and possibly include related models $relation_settings = apply_filters('FHEE__Read__create_entity_from_wpdb_result__related_models_to_include', $model->relation_settings()); foreach ($relation_settings as $relation_name => $relation_obj) { $related_model_part = $this->get_related_entity_name($relation_name, $relation_obj); if (empty($includes_for_this_model) || isset($includes_for_this_model['meta'])) { $result['_links'][\EED_Core_Rest_Api::ee_api_link_namespace . $related_model_part] = array(array('href' => $this->get_versioned_link_to(\EEH_Inflector::pluralize_and_lower($model->get_this_model_name()) . '/' . $result[$model->primary_key_name()] . '/' . $related_model_part), 'single' => $relation_obj instanceof \EE_Belongs_To_Relation ? true : false)); } $related_fields_to_include = $this->extract_includes_for_this_model($include, $relation_name); if ($related_fields_to_include) { $pretend_related_request = new \WP_REST_Request(); $pretend_related_request->set_query_params(array('caps' => $context, 'include' => $this->extract_includes_for_this_model($include, $relation_name))); $related_results = $this->get_entities_from_relation($result[$model->primary_key_name()], $relation_obj, $pretend_related_request); $result[$related_model_part] = $related_results instanceof \WP_Error ? null : $related_results; } } $result = apply_filters('FHEE__Read__create_entity_from_wpdb_results__entity_before_inaccessible_field_removal', $result, $model, $context); $result_without_inaccessible_fields = Capabilities::filter_out_inaccessible_entity_fields($result, $model, $context, $this->get_model_version_info()); $this->_set_debug_info('inaccessible fields', array_keys(array_diff_key($result, $result_without_inaccessible_fields))); return apply_filters('FHEE__Read__create_entity_from_wpdb_results__entity_return', $result_without_inaccessible_fields, $model, $context); }
/** * Creates a REST entity array (JSON object we're going to return in the response, but * for now still a PHP array, but soon enough we'll call json_encode on it, don't worry), * from $wpdb->get_row( $sql, ARRAY_A) * @param \EEM_Base $model * @param array $db_row * @return array entity mostly ready for converting to JSON and sending in the response */ protected function _create_bare_entity_from_wpdb_results(\EEM_Base $model, $db_row) { $result = $model->deduce_fields_n_values_from_cols_n_values($db_row); $result = array_intersect_key($result, $this->get_model_version_info()->fields_on_model_in_this_version($model)); foreach ($result as $field_name => $raw_field_value) { $field_obj = $model->field_settings_for($field_name); $field_value = $field_obj->prepare_for_set_from_db($raw_field_value); if ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_ignored())) { unset($result[$field_name]); } elseif ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_rendered_format())) { $result[$field_name] = array('raw' => $field_obj->prepare_for_get($field_value), 'rendered' => $field_obj->prepare_for_pretty_echoing($field_value)); } elseif ($this->is_subclass_of_one($field_obj, $this->get_model_version_info()->fields_that_have_pretty_format())) { $result[$field_name] = array('raw' => $field_obj->prepare_for_get($field_value), 'pretty' => $field_obj->prepare_for_pretty_echoing($field_value)); } elseif ($field_obj instanceof \EE_Datetime_Field) { $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json($field_obj, $field_value, $this->get_model_version_info()->requested_version()); } else { $result[$field_name] = Model_Data_Translator::prepare_field_value_for_json($field_obj, $field_obj->prepare_for_get($field_value), $this->get_model_version_info()->requested_version()); } } return $result; }