/** * Get results from the database. * * @param int $value * @param string $repeater_slug * @param int $post_id * * @return array */ protected function get_results($value, $repeater_slug, $post_id) { global $wpdb; if ($this->is_option_page()) { $table = $wpdb->prefix . 'options'; $query = $wpdb->prepare("SELECT * FROM `{$table}` WHERE `option_name` LIKE '%s' ORDER BY `option_id` ASC", $repeater_slug . '_%'); } else { $table = sprintf('%s%smeta', $wpdb->prefix, $this->get_meta_type()); $column = papi_get_meta_id_column($this->get_meta_type()); $query = $wpdb->prepare("SELECT * FROM `{$table}` WHERE `meta_key` LIKE '%s' AND `{$column}` = %s ORDER BY `meta_id` ASC", $repeater_slug . '_%', $post_id); } $dbresults = $wpdb->get_results($query); $value = intval($value); // Do not proceed with empty value or columns. if (empty($value)) { return [[], []]; } $values = []; $results = []; $trash = []; // Get row results. $rows = $this->get_row_results($dbresults); // Get columns, divde all items with two. $columns = array_map(function ($row) { return count($row) / 2; }, $rows); $rows = array_values($rows); // Add repeater slug with number of rows to the values array. $values[$repeater_slug] = $value; for ($i = 0; $i < $value; $i++) { $no_trash = []; if (!isset($columns[$i]) || !isset($rows[$i])) { continue; } foreach ($rows[$i] as $slug => $meta) { if (!is_string($slug) || !isset($rows[$i][$slug])) { continue; } // Do not deal with layout meta object here since the property meta object will deal with it later. if (is_string($meta->meta_value) && preg_match($this->layout_value_regex, $meta->meta_value)) { if (!isset($values[$slug])) { $values[$slug] = $meta->meta_value; } continue; } // Add meta object to the no trash array. // so it won't be deleted. $no_trash[$slug] = $meta; // Serialize value if needed. $meta->meta_value = papi_maybe_json_decode(maybe_unserialize($meta->meta_value)); // Add property value and property type value. $values[$meta->meta_key] = $meta->meta_value; if (isset($rows[$i][$slug])) { // Add the meta value. $values[$slug] = $rows[$i][$slug]->meta_value; } } // Get the meta keys to delete. $trash_diff = array_diff(array_keys($rows[$i]), array_keys($no_trash)); if (!empty($trash_diff)) { // Find all trash meta objects from results array. foreach ($trash_diff as $slug) { if (!isset($results[$i]) || !isset($rows[$i][$slug])) { continue; } $trash[$results[$i][$slug]->meta_key] = $rows[$i][$slug]; } } } // Fetch one layout per row. // Since 3.0.0 this is backward compatibility. $dblayouts = []; foreach (array_keys($values) as $slug) { if ($this->is_layout_key($slug)) { $num = str_replace($repeater_slug . '_', '', $slug); $num = explode('_', $num); $num = intval($num[0]); if (!isset($dblayouts[$num])) { $dblayouts[$num] = $num . $values[$slug]; } } } $layouts = $this->get_settings_layouts(); // Add empty rows that isn't saved to database. for ($i = 0; $i < $value; $i++) { foreach ($layouts as $layout) { $layout_slug = sprintf('%s_%d%s', $this->get_slug(true), $i, $this->layout_key); // Since 3.0.0 the `$dblayouts` check is only for backward compatibility. if (isset($layout['slug']) && (isset($values[$layout_slug]) || in_array($i . $layout['slug'], $dblayouts, true))) { foreach ($layout['items'] as $prop) { $slug = sprintf('%s_%d_%s', $repeater_slug, $i, unpapify($prop->slug)); if (!isset($values[$slug])) { $values[$slug] = null; } } } } } return [$values, $trash]; }
/** * Get results from the database. * * @param int $value * @param string $repeater_slug * @param int $post_id * * @return array */ protected function get_results($value, $repeater_slug, $post_id) { global $wpdb; if ($this->is_option_page()) { $table = $wpdb->prefix . 'options'; $query = $wpdb->prepare("SELECT * FROM `{$table}` WHERE `option_name` LIKE '%s' ORDER BY `option_id` ASC", $repeater_slug . '_%'); } else { $table = sprintf('%s%smeta', $wpdb->prefix, $this->get_meta_type()); $column = papi_get_meta_id_column($this->get_meta_type()); $query = $wpdb->prepare("SELECT * FROM `{$table}` WHERE `meta_key` LIKE '%s' AND `{$column}` = %s ORDER BY `meta_id` ASC", $repeater_slug . '_%', $post_id); } $dbresults = $wpdb->get_results($query); $value = intval($value); // Do not proceed with empty value. if (empty($value)) { return [[], []]; } $values = []; $results = []; $trash = []; // Get row results. $rows = array_values($this->get_row_results($dbresults)); // Add repeater slug with number of rows to the values array. $values[$repeater_slug] = $value; for ($i = 0; $i < $value; $i++) { $no_trash = []; if (!isset($no_trash[$i])) { $no_trash[$i] = []; } if (!isset($rows[$i])) { continue; } foreach ($rows[$i] as $slug => $meta) { if (!is_string($slug) || !isset($rows[$i][$slug])) { continue; } // Add meta object to the no trash array. // so it won't be deleted. $no_trash[$slug] = $meta; // Add property value. $values[$meta->meta_key] = papi_maybe_json_decode(maybe_unserialize($meta->meta_value)); } // Get the meta keys to delete. $trash_diff = array_diff(array_keys($rows[$i]), array_keys($no_trash[$i])); if (!empty($trash_diff)) { // Find all trash meta objects from results array. foreach ($trash_diff as $slug) { if (!isset($results[$i]) || !isset($rows[$i][$slug])) { continue; } $trash[$results[$i][$slug]->meta_key] = $rows[$i][$slug]; } } } $properties = $this->get_settings_properties(); // Add empty rows that isn't saved to database. for ($i = 0; $i < $value; $i++) { foreach ($properties as $prop) { if (!isset($prop->slug)) { continue; } $slug = sprintf('%s_%d_%s', $repeater_slug, $i, unpapify($prop->slug)); if (!isset($values[$slug])) { $values[$slug] = null; } } } return [$values, $trash]; }