/** * Convert all arrays that has a valid property type. * * @param array $items * * @return array */ private function convert_items_array($items) { foreach ($items as $index => $item) { if (is_array($item) && !isset($item['type'])) { foreach ($item as $key => $value) { if (is_array($value)) { $items[$index][$key] = $this->convert_items_array($value); $items[$index][$key] = array_filter($items[$index][$key]); } } continue; } if (papi_is_property($item)) { $child_items = $item->get_setting('items'); if (is_array($child_items)) { $items[$index]->set_setting('items', $this->convert_items_array($child_items)); } continue; } if (is_array($item) && isset($item['type']) || is_object($item) && isset($item->type)) { $items[$index] = papi_get_property_type($item); if (is_null($items[$index])) { unset($items[$index]); continue; } if (is_object($items[$index])) { $child_items = $items[$index]->get_setting('items'); if (is_array($child_items)) { $items[$index]->set_setting('items', $this->convert_items_array($child_items)); } } } } return $items; }
/** * Get child property. * * @param string $slug * @param array $items * * @return Papi_Core_Property|null */ public function get_child_property($slug, array $items = []) { $items = empty($items) ? $this->get_child_properties() : $items; foreach ($items as $property) { if (is_array($property) && isset($property['items'])) { $property = $this->get_child_property($slug, $property['items']); } $property = papi_get_property_type($property); if (papi_is_property($property) && $property->match_slug($slug)) { return $property; } } }
/** * Prepare properties data for saving. * * @param array $data * @param int $post_id * * @return array */ protected function prepare_properties_data(array $data = [], $post_id = 0) { // Since we are storing witch property it is in the $data array // we need to remove that and set the property type to the property // and make a array of the property type and the value. foreach ($data as $key => $value) { $property_type_key = papi_get_property_type_key(); if (strpos($key, $property_type_key) === false) { continue; } $property_key = str_replace($property_type_key, '', $key); // Check if value exists. if (isset($data[$property_key])) { $data[$property_key] = ['type' => $value, 'value' => $data[$property_key]]; } unset($data[$key]); } foreach ($data as $key => $item) { $property = papi_get_property_type($item['type']); unset($data[$key]); if (papi_is_property($property)) { // Run `update_value` method on the property class. $data[$key] = $property->update_value($item['value'], papi_remove_papi($key), $post_id); // Apply `update_value` filter so this can be changed from the theme for specified property type. $data[$key] = papi_filter_update_value($item['type']->type, $data[$key], papi_remove_papi($key), $post_id); if ($item['type']->overwrite) { $slug = papi_remove_papi($key); $this->overwrite[$slug] = $data[$key]; } } } return $data; }
/** * Format the value of the property before it's returned * to WordPress admin or the site. * * @param mixed $values * @param string $repeater_slug * @param int $post_id * * @return array */ public function format_value($values, $repeater_slug, $post_id) { if (!is_array($values)) { return []; } foreach ($values as $index => $layout) { foreach ($layout as $slug => $value) { if (is_string($value) && preg_match($this->layout_value_regex, $value)) { if (isset($values[$index][$this->layout_key])) { unset($values[$index][$slug]); continue; } $values[$index][$this->layout_key] = $value; unset($values[$index][$slug]); continue; } if (papi_is_property_type_key($slug)) { continue; } $property_type_slug = papi_get_property_type_key_f($slug); if (!isset($values[$index][$property_type_slug])) { continue; } $property_type_value = $values[$index][$property_type_slug]; $property_type = papi_get_property_type($property_type_value); if (!is_object($property_type)) { continue; } // Get property child slug. $child_slug = $this->get_child_slug($repeater_slug, $slug); // Create cache key. $cache_key = sprintf('%s_%d_%s', $repeater_slug, $index, $slug); // Get raw value from cache if enabled. if ($this->cache) { $raw_value = papi_cache_get($cache_key, $post_id, $this->get_meta_type()); } else { $raw_value = false; } // Load the value. if ($raw_value === null || $raw_value === false) { $values[$index][$slug] = $property_type->load_value($value, $child_slug, $post_id); $values[$index][$slug] = papi_filter_load_value($property_type->type, $values[$index][$slug], $child_slug, $post_id, papi_get_meta_type()); if (!papi_is_empty($values[$index][$slug]) && $this->cache) { papi_cache_set($cache_key, $post_id, $values[$index][$slug], $this->get_meta_type()); } } else { $values[$index][$slug] = $raw_value; } if (strtolower($property_type->type) === 'repeater') { $property_type->cache = false; } // Format the value from the property class. $values[$index][$slug] = $property_type->format_value($values[$index][$slug], $child_slug, $post_id); if (!is_admin()) { $values[$index][$slug] = papi_filter_format_value($property_type->type, $values[$index][$slug], $child_slug, $post_id, papi_get_meta_type()); } $values[$index][$property_type_slug] = $property_type_value; } } if (!is_admin()) { foreach ($values as $index => $row) { foreach ($row as $slug => $value) { if (is_string($value) && preg_match($this->layout_value_regex, $value)) { unset($values[$index][$slug]); $values[$index]['_layout'] = preg_replace($this->layout_value_regex, '', $value); } if (papi_is_property_type_key($slug)) { unset($values[$index][$slug]); } if (papi_is_empty($value)) { unset($values[$index][$slug]); } } } } return $values; }
/** * 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; }
/** * Create a new property array or rendering a template property file. * * @param mixed $file_or_options * @param array $values * * @return Papi_Core_Property */ function papi_property($file_or_options, array $values = []) { if (papi_is_empty($file_or_options)) { return; } if (is_array($file_or_options)) { if ($property = Papi_Core_Property::factory($file_or_options)) { $file_or_options = $property->get_options(); } } if (is_string($file_or_options) && is_array($values)) { $file_or_options = papi_template($file_or_options, $values); if (is_object($file_or_options)) { $file_or_options = papi_property((array) $file_or_options->get_options()); } } if (is_object($file_or_options)) { return papi_get_property_type($file_or_options); } }
/** * Create a new property array or rendering a template property file. * * @param mixed $file_or_options * @param array $values * * @return null|Papi_Property */ function papi_property($file_or_options, $values = []) { if (papi_is_empty($file_or_options)) { return; } if (is_array($file_or_options)) { $file_or_options = papi_get_property_options($file_or_options); } if (is_string($file_or_options) && is_array($values)) { $file_or_options = papi_template($file_or_options, $values); } if (is_object($file_or_options)) { return papi_get_property_type($file_or_options); } }
/** * Format the value of the property before it's returned * to WordPress admin or the site. * * @param mixed $values * @param string $repeater_slug * @param int $post_id * * @return array */ public function format_value($values, $repeater_slug, $post_id) { if (!is_array($values)) { return []; } foreach ($values as $index => $layout) { foreach ($layout as $slug => $value) { if (is_string($value) && preg_match($this->layout_prefix_regex, $value)) { if (isset($values[$index][$this->layout_key])) { unset($values[$index][$slug]); continue; } $values[$index][$this->layout_key] = $value; unset($values[$index][$slug]); continue; } if (papi_is_property_type_key($slug)) { continue; } $property_type_slug = papi_get_property_type_key_f($slug); if (!isset($values[$index][$property_type_slug])) { continue; } $property_type_value = $values[$index][$property_type_slug]; $property_type = papi_get_property_type($property_type_value); if (!is_object($property_type)) { continue; } // Get property child slug. $child_slug = $this->get_child_slug($repeater_slug, $slug); // Load the value. $values[$index][$slug] = $property_type->load_value($value, $child_slug, $post_id); $values[$index][$slug] = papi_filter_load_value($property_type->type, $values[$index][$slug], $child_slug, $post_id); // Format the value from the property class. $values[$index][$slug] = $property_type->format_value($values[$index][$slug], $child_slug, $post_id); if (!is_admin()) { $values[$index][$slug] = papi_filter_format_value($property_type->type, $values[$index][$slug], $child_slug, $post_id); } $values[$index][$property_type_slug] = $property_type_value; } } if (!is_admin()) { foreach ($values as $index => $row) { foreach ($row as $slug => $value) { if (is_string($value) && preg_match($this->layout_prefix_regex, $value)) { $values[$index][$slug] = preg_replace($this->layout_prefix_regex, '', $value); } if (papi_is_property_type_key($slug)) { unset($values[$index][$slug]); } } } } return $values; }
/** * Get property from entry type. * * @param string $slug * @param string $child_slug * * @return Papi_Property */ public function get_property($slug, $child_slug = '') { $boxes = $this->get_boxes(); $parts = preg_split('/\\[\\d+\\]/', $slug); $parts = array_map(function ($part) { return preg_replace('/(\\[|\\])/', '', $part); }, $parts); if (count($parts) > 1) { $property = null; for ($i = 0, $l = count($parts); $i < $l; $i++) { $child = isset($parts[$i + 1]) ? $parts[$i + 1] : ''; $property = $this->get_property($parts[$i], $child); if (isset($parts[$i + 1])) { $i++; } } /** * Modify property. * * @param Papi_Core_Property $property */ return apply_filters('papi/get_property', $property); } foreach ($boxes as $box) { foreach ($box->properties as $property) { $property = papi_get_property_type($property); if (papi_is_property($property) && $property->match_slug($slug)) { if (empty($child_slug)) { /** * Modify property. * * @param Papi_Core_Property $property */ return apply_filters('papi/get_property', $property); } $property = $property->get_child_property($child_slug); if (papi_is_property($property)) { /** * Modify property. * * @param Papi_Core_Property $property */ return apply_filters('papi/get_property', $property); } } } } }
/** * Get property from page type. * * @param string $slug * @param string $child_slug * * @return null|Papi_Property */ public function get_property($slug, $child_slug = '') { $boxes = $this->get_boxes(); $parts = preg_split('/\\[\\d+\\]/', $slug); $parts = array_map(function ($part) { return preg_replace('/(\\[|\\])/', '', $part); }, $parts); if (count($parts) > 1) { $property = null; for ($i = 0, $l = count($parts); $i < $l; $i++) { $child = isset($parts[$i + 1]) ? $parts[$i + 1] : ''; $property = $this->get_property($parts[$i], $child); if (isset($parts[$i + 1])) { $i++; } } return $property; } if (empty($boxes)) { return; } foreach ($boxes as $box) { $properties = isset($box[1][0]->properties) ? $box[1][0]->properties : $box[1]; foreach ($properties as $property) { $property = papi_get_property_type($property); if (papi_is_property($property) && $property->match_slug($slug)) { if (empty($child_slug)) { return $property; } $result = $this->get_child_property($property->get_child_properties(), $child_slug); if (is_object($result)) { return papi_get_property_type($result); } } } } }
/** * Prepare properties data for saving. * * @param array $data * @param int $post_id * * @return array */ protected function prepare_properties_data(array $data = [], $post_id = 0) { // Since we are storing witch property it is in the `$data` array // we need to remove that and set the property type to the property // and make a array of the property type and the value. foreach ($data as $key => $value) { if (papi_is_property_type_key($key)) { continue; } $property_type_key = papify(papi_get_property_type_key($key)); // Check if value exists. if (!isset($data[$key]) && !isset($data[$property_type_key])) { continue; } // Pair property value with property type object. $data[$key] = ['type' => $data[$property_type_key], 'value' => $value]; // Remove property type object since it's not needed anymore. unset($data[$property_type_key]); } foreach ($data as $key => $item) { if (papi_is_property_type_key($key)) { continue; } $property = papi_get_property_type($item['type']); unset($data[$key]); if (papi_is_property($property)) { // Run `update_value` method on the property class. $data[$key] = $property->update_value($item['value'], unpapify($key), $post_id); // Apply `update_value` filter so this can be changed from // the theme for specified property type. $data[$key] = papi_filter_update_value($item['type']->type, $data[$key], unpapify($key), $post_id, papi_get_meta_type()); if ($item['type']->overwrite) { $slug = unpapify($key); $this->overwrite[$slug] = $data[$key]; unset($data[$key]); } } } return $data; }