/**
  * Decode property.
  *
  * @param string $key
  * @param string $value
  *
  * @return mixed
  */
 protected function decode_property($key, $value)
 {
     if (papi_is_property_type_key($key) && is_string($value)) {
         $value = base64_decode($value);
         $value = papi_maybe_json_decode($value);
     }
     return $value;
 }
 /**
  * Format the value of the property before it's returned
  * to WordPress admin or the site.
  *
  * @param  mixed  $value
  * @param  string $slug
  * @param  int    $post_id
  *
  * @return array
  */
 public function format_value($value, $slug, $post_id)
 {
     if (!$this->get_setting('allow_html') && $this->input_type === 'text') {
         $value = papi_maybe_json_decode(maybe_unserialize($value));
         if (!is_string($value)) {
             $value = '';
         }
         $value = wp_strip_all_tags($value);
     }
     return $value;
 }
Example #3
0
/**
 * Cast string value to right value type.
 *
 * @param  string $str
 *
 * @return mixed
 */
function papi_cast_string_value($str)
{
    if (!is_string($str)) {
        return $str;
    }
    if (is_numeric($str)) {
        return $str == (int) $str ? (int) $str : (double) $str;
    }
    if ($str === 'true' || $str === 'false') {
        return $str === 'true';
    }
    return papi_maybe_json_decode(maybe_unserialize($str));
}
 /**
  * Get value that should be saved.
  *
  * @param  array $options
  *
  * @throws InvalidArgumentException when option values not matching the expected value.
  *
  * @return mixed
  */
 public function get_value(array $options = [])
 {
     if (!isset($options['post_id']) || !is_int($options['post_id'])) {
         throw new InvalidArgumentException('Missing `post_id` option. Should be int.');
     }
     if (!isset($options['property']) || $options['property'] instanceof Papi_Core_Property === false) {
         throw new InvalidArgumentException('Missing `property` option. Should be instance of `Papi_Core_Property`.');
     }
     if (!isset($options['slug']) || empty($options['slug'])) {
         $options['slug'] = $options['property']->get_slug(true);
     }
     if (!isset($options['value'])) {
         throw new InvalidArgumentException('Missing `value` option.');
     }
     $value = $this->call_value($options['value']);
     $value = $this->update_value($options['property'], $value, $options['slug'], $options['post_id']);
     return papi_maybe_json_decode(maybe_unserialize($value));
 }
 /**
  * Change value after it's loaded from the database.
  *
  * @param  mixed  $value
  * @param  string $slug
  * @param  int    $post_id
  *
  * @return mixed
  */
 public function load_value($value, $slug, $post_id)
 {
     $value = maybe_unserialize($value);
     return papi_maybe_json_decode($value, $this->get_setting('multiple'));
 }
 /**
  * Change value after it's loaded from the database.
  *
  * @param  mixed  $value
  * @param  string $slug
  * @param  int    $post_id
  *
  * @return mixed
  */
 public function load_value($value, $slug, $post_id)
 {
     $value = maybe_unserialize($value);
     return papi_maybe_json_decode($value, $this->convert_type === 'array');
 }
 /**
  * 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];
 }
 /**
  * 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;
 }
 /**
  * Sort the values on update.
  *
  * @param  mixed  $values
  * @param  string $slug
  * @param  int    $post_id
  *
  * @return string
  */
 public function update_value($values, $slug, $post_id)
 {
     $values = $this->format_value($values, $slug, $post_id);
     $values = array_map(function ($item) {
         if ($item instanceof WP_Post) {
             $item = $this->convert_post_to_item($item);
         }
         if (isset($item->title)) {
             unset($item->title);
         }
         return $item;
     }, $values);
     return papi_maybe_json_decode($values);
 }
 /**
  * Change value after it's loaded from the database.
  *
  * @param  mixed  $values
  * @param  string $slug
  * @param  int    $post_id
  *
  * @return mixed
  */
 public function load_value($values, $slug, $post_id)
 {
     $values = (array) papi_maybe_json_decode(maybe_unserialize($values), true);
     return array_map('papi_maybe_convert_to_object', $values);
 }