/**
  * 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;
 }
    /**
     * 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 
        }
    }
 /**
  * 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;
 }
Esempio n. 4
0
/**
 * Convert array of arrays to array of slugs.
 * The given slug will match a key with the number of properties.
 *
 * @param  array  $value
 * @param  string $slug
 *
 * @return array
 */
function papi_to_property_array_slugs(array $value, $slug)
{
    $results = [];
    $counter = [];
    foreach ($value as $index => $arr) {
        if (!is_array($arr)) {
            continue;
        }
        $counter[] = $arr;
        foreach ($arr as $key => $val) {
            if (!is_string($key) || empty($key)) {
                continue;
            }
            if ($key[0] !== '_') {
                $key = '_' . $key;
            }
            $item_slug = $slug . '_' . $index . $key;
            if (papi_is_property_type_key($item_slug)) {
                $item_slug = papi_f($item_slug);
            }
            $results[$item_slug] = $val;
        }
    }
    $results[$slug] = count($counter);
    return $results;
}
 /**
  * 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;
 }