/** * Get Papi cache key. * * @param string $key * @param mixed $suffix * * @return string */ function papi_cache_key($key, $suffix) { if (!is_string($key)) { return ''; } $key = papify($key); $suffix = papi_convert_to_string($suffix); $suffix = papi_html_name($suffix); $suffix = unpapify($suffix); return sprintf('%s_%s', $key, $suffix); }
/** * Get Papi cache key. * * @param string $key * @param mixed $suffix * @param string $type * * @return string */ function papi_cache_key($key, $suffix, $type = 'post') { if (!is_string($key)) { return ''; } $type = empty($type) ? 'post' : $type; $type = $type === 'page' ? 'post' : $type; $key = unpapify($key); $key = papify($type . '_' . $key); $suffix = papi_convert_to_string($suffix); $suffix = papi_html_name($suffix); $suffix = unpapify($suffix); return sprintf('%s_%s', $key, $suffix); }
/** * Get html name for property with or without sub property and row number. * * @param array|object $sub_property * @param int $row * * @return string */ public function html_name($sub_property = null, $row = null) { $base_slug = $this->slug; if (is_null($sub_property)) { return $base_slug; } if (is_numeric($row)) { $base_slug = sprintf('%s[%d]', $base_slug, intval($row)); } if (!papi_is_property($sub_property)) { if (is_array($sub_property) || is_object($sub_property)) { $sub_property = self::factory($sub_property); } else { return $base_slug; } } return sprintf('%s[%s]', $base_slug, unpapify($sub_property->get_slug())); }
/** * Render repeater row. */ protected function render_repeater_row() { $layouts = $this->get_settings_layouts(); $values = $this->get_value(); // Fetch all slugs in all layouts. $slugs = []; foreach ($layouts as $index => $layout) { foreach ($layout['items'] as $item) { $slugs[] = unpapify($item->slug); } } // Remove values that don't exists in the slugs array. foreach ($values as $index => $row) { $keys = array_keys($row); foreach (array_keys($row) as $slug) { if (in_array($slug, $keys, true) || papi_is_property_type_key($slug) || $this->is_layout_key($slug)) { continue; } unset($values[$index][$slug]); } } $values = array_filter($values); $closed_rows = $this->get_setting('closed_rows', true); foreach ($values as $index => $row) { ?> <tr <?php echo $closed_rows ? 'class="closed"' : ''; ?> > <td class="handle"> <span class="toggle"></span> <span class="count"><?php echo esc_html($this->counter + 1); ?> </span> </td> <?php foreach ($layouts as $layout) { // Don't render layouts that don't have a valid value in the database. if (!isset($row[$this->layout_key]) || $layout['slug'] !== $this->get_layout_value($row[$this->layout_key])) { continue; } // Render all properties in the layout $this->render_properties($layout['items'], $row); } $this->counter++; ?> <td class="last"> <span> <a title="<?php esc_html_e('Remove', 'papi'); ?> " href="#" class="repeater-remove-item">x</a> </span> </td> </tr> <?php } }
/** * Get rule slug. * * @param Papi_Core_Conditional_Rule $rule * @param Papi_Core_Property $property * * @return string */ protected function get_rule_slug($rule, $property) { $arr_reg = '/\\[\\d+\\](\\[\\w+\\])$/'; $slug = $property->get_slug(); $page_type = papi_get_entry_type_by_meta_id(); if ($page_type instanceof Papi_Page_Type === false) { return $rule->slug; } if (preg_match($arr_reg, $slug, $out)) { $slug = str_replace($out[1], '[' . unpapify($rule->slug) . ']', $slug); $property = $page_type->get_property($slug); if (papi_is_property($property)) { return $slug; } } return $rule->slug; }
/** * Update property values on the post with the given post id * or update property values on the option page. * * @param array $meta * * @return bool */ function papi_update_property_meta_value(array $meta = []) { $meta = array_merge(['id' => 0, 'slug' => '', 'type' => 'post', 'value' => ''], $meta); $meta = (object) $meta; $meta->type = papi_get_meta_type($meta->type); $save_value = true; // Set the right update value function for the type. $update_value_fn = $meta->type === 'option' ? 'update_option' : 'update_metadata'; /** * Change update function. * * @param string $update_value_fn */ $update_value_fn = apply_filters('papi/core/update_value_fn', $update_value_fn); // Check so the function is callable before using it. if (!is_callable($update_value_fn)) { return; } // Check for string keys in the array if any. foreach (papi_to_array($meta->value) as $key => $value) { if (is_string($key)) { $save_value = false; break; } } // If main value shouldn't be saved it should be array. if (!$save_value && is_array($meta->value)) { $meta->value = [$meta->value]; } // Delete saved value if empty. if (papi_is_empty($meta->value)) { return papi_delete_property_meta_value($meta->id, $meta->slug, $meta->type); } $result = true; foreach (papi_to_array($meta->value) as $key => $value) { // Delete saved value if value is empty. if (papi_is_empty($value) || $value === '[]' || $value === '{}') { return papi_delete_property_meta_value($meta->id, $meta->slug, $meta->type); } // Delete main value cache. papi_cache_delete($meta->slug, $meta->id, $meta->type); // If not a array we can save the value. if (!is_array($value)) { if ($save_value) { $value = $meta->value; } if (papi_get_meta_type($meta->type) === 'option') { $out = call_user_func_array($update_value_fn, [unpapify($meta->slug), $value]); $result = $out ? $result : $out; } else { $out = call_user_func_array($update_value_fn, [$meta->type, $meta->id, unpapify($meta->slug), $value]); $result = $out ? $result : $out; } continue; } // Delete all child value caches. papi_update_property_meta_value_cache_delete($meta, $value); // Update metadata or option value for all child values. foreach ($value as $child_key => $child_value) { if (papi_is_empty($child_value)) { papi_delete_property_meta_value($meta->id, $child_key, $meta->type); } else { if (papi_get_meta_type($meta->type) === 'option') { call_user_func_array($update_value_fn, [unpapify($child_key), $child_value]); } else { call_user_func_array($update_value_fn, [$meta->type, $meta->id, unpapify($child_key), $child_value]); } } } } return $result; }
/** * Load child properties. * * @param array $results * @param Papi_Core_Property $property * * @return array */ protected function load_child_properties(array $results, $property = null) { foreach ($results as $index => $row) { foreach ($row as $slug => $value) { if (is_array($value) && isset($value[$slug])) { $child_property = $this->get_store()->get_property($this->get_slug(true), $slug); if (papi_is_property($child_property) && !empty($child_property->get_child_properties())) { $value = papi_from_property_array_slugs($value, unpapify($slug)); $results[$index][$slug] = $this->load_child_properties($value, $child_property); } } $type_key = papi_get_property_type_key_f($slug); if ($property->match_slug($slug)) { $results[$index][$type_key] = $property; } else { $results[$index][$type_key] = $property->get_child_property($slug); } } } return $results; }
/** * Update property values on the post with the given post id * or update property values on the option page. * * @param array $meta * * @return bool */ function papi_update_property_meta_value(array $meta = []) { $meta = array_merge(['post_id' => 0, 'slug' => '', 'type' => Papi_Post_Page::TYPE, 'value' => ''], $meta); $meta = (object) $meta; $option = $meta->type === 'option' || papi_is_option_page(); $save_value = true; foreach (papi_to_array($meta->value) as $key => $value) { if (is_string($key)) { $save_value = false; break; } } if (!$save_value && is_array($meta->value)) { $meta->value = [$meta->value]; } if (papi_is_empty($meta->value)) { return papi_delete_property_meta_value($meta->post_id, $meta->slug, $meta->type); } $result = true; foreach (papi_to_array($meta->value) as $key => $value) { papi_cache_delete($meta->slug, $meta->post_id); if (!is_array($value)) { if ($save_value) { $value = $meta->value; } if ($option) { $out = update_option(unpapify($meta->slug), $value); $result = $out ? $result : $out; } else { $out = update_post_meta($meta->post_id, unpapify($meta->slug), $value); $result = $out ? $result : $out; } continue; } foreach ($value as $child_key => $child_value) { if (papi_is_empty($child_value)) { papi_delete_property_meta_value($meta->post_id, $child_key, $meta->type); } else { if ($option) { update_option(unpapify($child_key), $child_value); } else { update_post_meta($meta->post_id, unpapify($child_key), $child_value); } } } } return $result; }
/** * 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); }
/** * 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; }
/** * Change value after it's loaded from the database * and populate every property in the repeater with the right property type. * * @param int $value * @param string $repeater_slug * @param int $post_id * * @return array */ public function load_value($value, $repeater_slug, $post_id) { if (is_array($value)) { return $value; } list($results, $trash) = $this->get_results($value, $repeater_slug, $post_id); // Will not need this array. unset($trash); $page = $this->get_page(); $types = []; $results = papi_from_property_array_slugs($results, unpapify($repeater_slug)); if (empty($page) || empty($results)) { return $this->default_value; } foreach ($results[0] as $slug => $value) { if ($property = $page->get_property($repeater_slug, $slug)) { $types[$slug] = $property; } } foreach ($results as $index => $row) { foreach ($row as $slug => $value) { if (!isset($types[$slug])) { continue; } $type_key = papi_get_property_type_key_f($slug); $results[$index][$type_key] = $types[$slug]; } } return $results; }
/** * Get property option or default value. * * @param string $slug * @param string $option * @param mixed $default * * @return bool */ public function get_property_option($slug, $option, $default = null) { $slug = unpapify($slug); $property = $this->property($slug); // If no property type is found, return default // value since we don't have a property. if (!papi_is_property($property)) { return $default; } $value = $property->get_option($option); if (papi_is_empty($value)) { return $default; } return $value; }
/** * 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'], 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); if ($item['type']->overwrite) { $slug = unpapify($key); $this->overwrite[$slug] = $data[$key]; } } } return $data; }