/** * Get property meta value. * * @param string $slug * * @return mixed */ public function get_property_meta_value($slug) { $slug = strtolower($slug); if (isset($this->meta_values[$slug])) { return $this->meta_values[$slug]; } return papi_get_property_meta_value($this->id, $slug, $this->get_type()); }
/** * Delete value from the database. * * @param string $slug * @param int $post_id * @param string $type * * @return bool */ public function delete_value($slug, $post_id, $type) { $rows = intval(papi_get_property_meta_value($post_id, $slug)); $value = $this->load_value($rows, $slug, $post_id); $value = papi_to_property_array_slugs($value, $slug); $result = true; foreach (array_keys($value) as $key) { $out = papi_delete_property_meta_value($post_id, $key, $type); $result = $out ? $result : $out; } return $result; }
/** * Update value before it's saved to the database. * * @param mixed $values * @param string $repeater_slug * @param int $post_id * * @return array */ public function update_value($values, $repeater_slug, $post_id) { $rows = intval(papi_get_property_meta_value($post_id, $repeater_slug)); if (!is_array($values)) { $values = []; } list($results, $trash) = $this->get_results($rows, $repeater_slug, $post_id); // Delete trash values. foreach ($trash as $meta) { papi_delete_property_meta_value($post_id, $meta->meta_key); } $values = papi_to_property_array_slugs($values, $repeater_slug); foreach ($values as $slug => $value) { if (papi_is_property_type_key($slug)) { continue; } $property_type_slug = papi_get_property_type_key_f($slug); if (!isset($values[$property_type_slug])) { continue; } // Get real property slug $property_slug = $this->get_child_slug($repeater_slug, $slug); // Get property type $property_type_value = $values[$property_type_slug]->type; $property_type = papi_get_property_type($property_type_value); // Unserialize if needed. $value = papi_maybe_json_decode(maybe_unserialize($value)); // Run update value on each property type class. $value = $property_type->update_value($value, $property_slug, $post_id); // Run update value on each property type filter. $values[$slug] = papi_filter_update_value($property_type_value, $value, $property_slug, $post_id, papi_get_meta_type()); if (is_array($values[$slug])) { foreach ($values[$slug] as $key => $val) { if (!is_string($key)) { continue; } unset($values[$slug][$key]); $key = preg_replace('/^\\_/', '', $key); $values[$slug][$key] = $val; } } } // Find out which keys that should be deleted. $trash = array_diff(array_keys(papi_to_array($results)), array_keys(papi_to_array($values))); // Delete unwanted (trash) values. foreach (array_keys($trash) as $trash_key) { papi_delete_property_meta_value($post_id, $trash_key); } // It's safe to remove all rows in the database here. $this->remove_repeater_rows($post_id, $repeater_slug); // Remove unnecessary property type keys if any is left. foreach (array_keys($values) as $slug) { if (papi_is_property_type_key($slug)) { unset($values[$slug]); } } return $values; }
/** * 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; $option_page = $this->is_option_page(); if ($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 = $wpdb->prefix . 'postmeta'; $query = $wpdb->prepare("SELECT * FROM `{$table}` WHERE `meta_key` LIKE '%s' AND `post_id` = %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_prefix_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; // Get property type key and value. $property_type_key = papi_get_property_type_key_f($meta->meta_key); $property_type_value = papi_get_property_meta_value($post_id, $property_type_key); // 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; $values[$property_type_key] = $property_type_value; // Add the flexible layout for the property. if (!preg_match('/\\_layout$/', $slug) && is_string($rows[$i][$slug]->meta_value) && !preg_match($this->layout_prefix_regex, $rows[$i][$slug]->meta_value)) { $slug .= '_layout'; } 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]; } } } $dblayouts = []; // Fetch one layout per row. foreach (array_keys($values) as $slug) { if (preg_match('/\\' . $this->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) { if (isset($layout['slug']) && in_array($i . $layout['slug'], $dblayouts)) { foreach ($layout['items'] as $prop) { $slug = sprintf('%s_%d_%s', $repeater_slug, $i, papi_remove_papi($prop->slug)); if (!isset($values[$slug])) { $values[$slug] = null; } } } } } return [$values, $trash]; }
/** * Get value from property. * * @param string $slug * * @return mixed */ public function get_value($slug) { $slug = unpapify($slug); $value = papi_get_property_meta_value($this->id, $slug, static::TYPE); return $this->convert($slug, $value); }
/** * Load value from database. * * @param mixed $value * @param string $slug * @param int $post_id * * @return array */ public function load_value($value, $slug, $post_id) { $values = $this->link_fields; if (is_array($value) || is_object($value)) { $values = (array) $value; foreach ($values as $key => $val) { unset($values[$key]); $key = preg_replace('/^' . $slug . '\\_/', '', $key); $values[$key] = $val; } } else { $type = $post_id === 0 ? 'option' : 'post'; foreach ($values as $index => $key) { $values[$key] = papi_get_property_meta_value($post_id, sprintf('%s_%s', $slug, $key), $type); unset($values[$index]); } } $link = (object) $values; if (isset($link->{$slug}) && is_numeric($link->{$slug})) { unset($link->{$slug}); } return $this->prepare_link_array($link); }
/** * Load value from database. * * @param mixed $value * @param string $slug * @param int $post_id * * @return array */ public function load_value($value, $slug, $post_id) { if (is_array($value) || is_object($value)) { $values = $value; } else { $values = $this->link_fields; foreach ($values as $index => $key) { $values[$key] = papi_get_property_meta_value($post_id, sprintf('%s_%s', $slug, $key), $this->get_meta_type()); unset($values[$index]); } } return (object) $this->prepare_link_array($values, $slug); }
/** * Get sort option value. * * @param int $post_id * * @return string */ public function get_sort_option($post_id) { $slug = $this->html_id('sort_option'); $slug = str_replace('][', '_', $slug); $slug = str_replace('[', '_', $slug); $slug = str_replace(']', '', $slug); return papi_get_property_meta_value($post_id, $slug, $this->get_meta_type()); }
/** * Get value from property. * * @param string $slug * * @return mixed */ public function get_value($slug) { $slug = papi_remove_papi($slug); $value = papi_get_property_meta_value($this->id, $slug, $this->type); return $this->convert($slug, $value); }
/** * Load property value from the property. * * @param string $slug * * @return mixed */ public function load_value($slug) { $slug = unpapify($slug); $property = $this->property($slug); // If no property type is found, just return null. if (!papi_is_property($property)) { return; } // Get raw property meta value. $value = papi_get_property_meta_value($this->id, $slug, $this->get_type()); // Prepare load value, when you have `overwrite => true` // this value will not exist in the database and that's // why we need to prepare (change) the value. $value = $this->prepare_load_value($property, $value); // Bail if value is empty and option value is empty. if (papi_is_empty($value)) { if (!papi_is_empty($property->get_option('value'))) { return $property->get_option('value'); } return; } // A property need to know about the store. $this->property($slug)->set_store($this); // Run load value method right after the value has been loaded from the database. $value = $property->load_value($value, $slug, $this->id); $value = papi_filter_load_value($property->type, $value, $slug, $this->id, papi_get_meta_type()); // Remove empty values from arrays. if (is_array($value)) { $value = array_filter($value); } return $value; }