/** * Get posts. * * @param stdClass $settings * * @return array */ protected function get_posts($settings) { // By default we add posts per page key with the value -1 (all). if (!isset($settings->query['posts_per_page'])) { $settings->query['posts_per_page'] = -1; } // Prepare arguments for WP_Query. $args = array_merge($settings->query, ['post_type' => papi_to_array($settings->post_type), 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false]); $query = new WP_Query($args); $posts = $query->get_posts(); // Keep only objects. $posts = papi_get_only_objects($posts); $results = []; // Set labels. foreach ($posts as $post) { $obj = get_post_type_object($post->post_type); if (empty($obj)) { continue; } if (!isset($results[$obj->labels->menu_name])) { $results[$obj->labels->menu_name] = []; } $results[$obj->labels->menu_name][] = $post; } return $results; }
/** * Filter TinyMCE buttons (Visual tab). * * @param array $buttons * * @return array */ public function mce_buttons(array $buttons = []) { if ($new = papi_to_array($this->get_setting(current_filter(), []))) { return $new; } return $buttons; }
/** * Register Papi directory. * * @param array|string $directory * * @return bool */ function register_papi_directory($directory) { // Bail if not a array or string. if (!is_array($directory) && !is_string($directory)) { return false; } // Bail if directory don't exists. if (is_string($directory) && (!file_exists($directory) || !is_dir($directory))) { return false; } // Add directory to directories filter. return add_filter('papi/settings/directories', function ($directories) use($directory) { $directories = is_string($directories) ? [$directories] : $directories; $directories = is_array($directories) ? $directories : []; // Create a array of directory. $directory = papi_to_array($directory); // Check if directory exists before adding it. foreach ($directory as $index => $dir) { if (!file_exists($dir) || !is_dir($dir)) { unset($directory[$index]); } } return array_merge($directories, $directory); }); }
/** * Get settings properties. * * @return array */ protected function get_settings_properties() { $settings = $this->get_settings(); if (is_null($settings)) { return []; } return array_filter(papi_to_array($settings->items), 'papi_is_property'); }
/** * Get all taxonomies Papi should work with. * * @return array */ function papi_get_taxonomies() { $taxonomies = []; $entry_types = papi_get_all_entry_types(['types' => 'taxonomy']); foreach ($entry_types as $entry_type) { $taxonomies = array_merge($taxonomies, papi_to_array($entry_type->taxonomy)); } return array_unique($taxonomies); }
/** * Get users as dropdown items. * * @return array */ public function get_items() { $capabilities = papi_to_array($this->get_setting('capabilities')); $users = get_users(); $items = []; foreach ($users as $user) { $allcaps = $user->allcaps; if (count(array_diff($capabilities, array_keys($allcaps))) === 0) { $items[$user->display_name] = $user->ID; } } return $items; }
/** * Render property html. */ public function html() { $settings = $this->get_settings(); $value = papi_cast_string_value($this->get_value()); // Override selected setting with // database value if not empty. if (!papi_is_empty($value)) { $settings->selected = $value; } $settings->selected = papi_to_array($settings->selected); foreach ($settings->items as $key => $value) { $key = is_numeric($key) ? $value : $key; papi_render_html_tag('label', ['class' => 'light', 'for' => $this->html_id($key), papi_html_tag('input', ['checked' => in_array($value, $settings->selected) ? 'checked' : null, 'id' => $this->html_id($key), 'name' => $this->html_name() . '[]', 'type' => 'checkbox', 'value' => $value]), papi_convert_to_string($key)]); papi_render_html_tag('br'); } }
/** * Render property html. */ public function html() { $settings = $this->get_settings(); $value = papi_cast_string_value($this->get_value()); // Override selected setting with // database value if not empty. if (!papi_is_empty($value)) { $settings->selected = $value; } $settings->selected = papi_to_array($settings->selected); echo '<div class="papi-property-checkbox">'; foreach ($settings->items as $key => $value) { $key = is_numeric($key) ? $value : $key; papi_render_html_tag('p', [papi_html_tag('label', ['class' => 'light', 'for' => esc_attr($this->html_id($key)), papi_html_tag('input', ['id' => esc_attr($this->html_id($key)), 'name' => esc_attr($this->html_name()) . '[]', 'type' => 'hidden']), papi_html_tag('input', ['checked' => in_array($value, $settings->selected, true), 'id' => esc_attr($this->html_id($key)), 'name' => esc_attr($this->html_name()) . '[]', 'type' => 'checkbox', 'value' => esc_attr($value)]), esc_html(papi_convert_to_string($key))])]); } echo '</div>'; }
/** * Get layouts. * * @return array */ protected function get_settings_layouts() { $settings = $this->get_settings(); return $this->prepare_properties(papi_to_array($settings->items)); }
/** * Setup post types array. */ protected function setup_post_types() { $this->post_type = papi_to_array($this->post_type); // Set a default value to post types array // if we don't have a array or a empty array. if (empty($this->post_type)) { $this->post_type = ['page']; } if (count($this->post_type) === 1 && $this->post_type[0] === 'any') { $this->post_type = get_post_types('', 'names'); $this->post_type = array_values($this->post_type); } }
/** * Get all post types Papi should work with. * * @return array */ function papi_get_post_types() { $page_types = papi_get_all_page_types(true); $post_types = []; foreach ($page_types as $page_type) { $post_types = array_merge($post_types, papi_to_array($page_type->post_type)); } if (empty($post_types)) { return ['page']; } return array_unique($post_types); }
/** * Remove post type support. Runs once, on page load. * * @param array $post_type_supports */ protected function remove($post_type_supports = []) { $this->post_type_supports = array_merge($this->post_type_supports, papi_to_array($post_type_supports)); }
/** * Populate post type. * * @param array|string $post_type * * @return string */ private function populate_post_type($post_type) { $post_id = papi_get_post_id(); if ($post_id !== 0) { return get_post_type($post_id); } // Get the post type that we currently are on if it exist in the array of post types. $post_type = array_filter(papi_to_array($post_type), function ($post_type) { // Support fake post types. if (strpos($post_type, '_papi') !== false) { return true; } return !empty($post_type) && strtolower($post_type) === strtolower(papi_get_or_post('post_type')); }); if (!empty($post_type)) { return $post_type[0]; } return 'page'; }
/** * Setup property options. * * @param mixed $options * * @return mixed */ private function setup_options($options = []) { // When a object is sent in, just return it. if (is_object($options)) { return $options; } // Only arrays can be handled. if (!is_array($options)) { $options = []; } // Merge default options with the given options array. $options = array_merge($this->default_options, $options); $options = (object) $options; // Capabilities should be a array. $options->capabilities = papi_to_array($options->capabilities); // Setup property slug. $options->slug = $this->setup_options_slug($options); // Setup property settings. $options->settings = $this->setup_options_settings($options); // Type should always be lowercase. $options->type = strtolower($options->type); // Escape all options except those that are send it as second argument. return papi_esc_html($options, ['before_html', 'html', 'after_html']); }
/** * Setup post types array. */ private function setup_post_types() { $this->post_type = papi_to_array($this->post_type); // Set a default value to post types array // if we don't have a array or a empty array. if (empty($this->post_type)) { $this->post_type = ['page']; } }
/** * Set driver alias. */ protected function set_driver_alias() { foreach (papi_to_array($this->alias) as $alias) { if (is_string($alias) && !$this->porter->exists('driver.' . $alias)) { $this->set_driver_name($alias); } } }
/** * Fire filter. * * @param array $options * * @throws Exception if `filter` is missing from options array. * @throws Exception if `value` is missing from options array. * * @return mixed */ public function fire_filter(array $options) { if (!isset($options['type'])) { $options['type'] = 'after'; } if (!isset($options['filter'])) { throw new Exception('Missing `filter` in options array.'); } if (!isset($options['value'])) { throw new Exception('Missing `value` in options array.'); } $arguments = [$this->driver->filter($options['type'], $options['filter'])]; $value = $options['value']; foreach (papi_to_array($value) as $val) { $arguments[] = $val; } return call_user_func_array('apply_filters', $arguments); }
/** * Sort array based on given key and numeric value. * * @param array $array * @param string $key * * @return array */ function papi_sort_order($array, $key = 'sort_order') { if (empty($array) || !is_array($array) && !is_object($array)) { return []; } if (is_object($array)) { $array = papi_to_array($array); } $sorter = []; foreach ($array as $k => $value) { $value = is_array($value) ? (object) $value : $value; if (is_object($value) && isset($value->{$key})) { $sorter[$k] = $value->{$key}; continue; } } $i = 0; $default_sort = papi_filter_settings_sort_order(); foreach ($sorter as $k => $v) { if ($default_sort === $v) { $sorter[$k] = $v - $i; $i++; } } asort($sorter, SORT_NUMERIC); $result = []; foreach ($sorter as $k => $v) { $value = $array[$k]; $value = is_array($value) ? (object) $value : $value; if (is_object($value) && isset($value->{$key})) { $result[$k] = $array[$k]; } } return array_values($result); }
/** * 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; }
/** * Parse term query arguments. * * @param array $args * * @return array */ protected function parse_term_args(array $args) { if (isset($args['taxonomy_type'])) { $args['entry_type'] = $args['taxonomy_type']; unset($args['taxonomy_type']); } $entry_type = papi_get_entry_type_by_id($args['entry_type']); if ($entry_type instanceof Papi_Taxonomy_Type) { $args['taxonomy'] = papi_to_array($entry_type->taxonomy); } else { $args['taxonomy'] = isset($args['taxonomy']) ? $args['taxonomy'] : ''; } return $args; }
/** * Get taxonomies. * * @return array */ protected function get_taxonomies() { return papi_to_array($this->get_setting('taxonomy')); }
/** * Sort array based on given key and numeric value. * * @param array $array * @param string $key * * @return array */ function papi_sort_order($array, $key = 'sort_order') { if (empty($array) || !is_array($array) && !is_object($array)) { return []; } if (is_object($array)) { $array = papi_to_array($array); } $sorter = []; foreach ($array as $k => $value) { if (is_object($value)) { if (isset($value->{$key})) { $sorter[$k] = $value->{$key}; } else { if (isset($value->options->{$key})) { $sorter[$k] = $value->options->{$key}; } } } else { if (is_array($value) && isset($value[$key])) { $sorter[$k] = $value[$key]; } } } $i = 0; $default_sort = papi_filter_settings_sort_order(); foreach ($sorter as $k => $v) { if ($default_sort === $v) { $sorter[$k] = $v - $i; $i++; } } asort($sorter, SORT_NUMERIC); $result = []; $rest = []; foreach ($sorter as $k => $v) { $value = $array[$k]; if (is_object($value) && (!isset($value->options) && !isset($value->options->{$key}) || !isset($value->{$key})) || is_array($value) && !isset($value[$key])) { $rest[] = $value; } else { $result[$k] = $array[$k]; } } $result = array_values($result); foreach ($rest as $key => $value) { $result[] = $value; } return $result; }
/** * Render property html. */ public function html() { $post_id = papi_get_post_id(); $settings = $this->get_settings(); // Create query array for every page type. $page_types = array_map(function ($page_type) { return ['key' => papi_get_page_type_key(), 'value' => $page_type, 'compare' => 'LIKE']; }, papi_to_array($settings->page_type)); // Add relation. $page_types['relation'] = 'OR'; // Prepare arguments for WP_Query. $args = ['post_type' => 'any', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'meta_query' => $page_types]; $query = new WP_Query($args); $posts = $query->get_posts(); $values = []; foreach (papi_to_array($settings->slug) as $slug) { foreach ($posts as $post) { $val = papi_get_field($post->ID, $slug); $val = array_filter(papi_to_array($val), function ($item) use($post_id) { return is_object($item) && $item->ID === $post_id; }); if (empty($val)) { continue; } $page_type = papi_get_entry_type_by_meta_id($post->ID); if (empty($page_type)) { continue; } // Create the array if (!isset($values[$post->post_type])) { $values[$post->post_type] = []; } if (!isset($values[$post->post_type][$page_type->name])) { $values[$post->post_type][$page_type->name] = []; } // Add the post if (!isset($values[$post->post_type][$page_type->name][$post->ID]) && !empty($val)) { $values[$post->post_type][$page_type->name][$post->ID] = $post; } } } ?> <ul class="papi-property-reference" data-papi-rule="<?php echo esc_attr($this->html_name()); ?> "> <?php if (empty($values)) { ?> <p> <?php esc_html_e('No references exists', 'papi'); ?> </p> <?php } ksort($values); foreach ($values as $title => $val) { $post_type = get_post_type_object($title); ?> <li> <h3><?php echo esc_html($post_type->labels->name); ?> </h3> <div class="handlediv" title="Click to toggle"><br></div> </li> <li> <div class="page-types"> <ul> <?php ksort($val); foreach ($val as $name => $posts) { ?> <li class="heading-border"> <h4><?php echo esc_html($name); ?> </h4> <div class="handlediv" title="Click to toggle"><br></div> </li> <li> <div class="box"> <?php $i = 0; foreach ($posts as $post) { ?> <a href="<?php echo esc_attr(get_edit_post_link($post->ID)); ?> "><?php echo esc_html($post->post_title); ?> </a> <?php $i++; } ?> <div class="clear"></div> </div> </li> <?php } ?> </ul> <div class="clear"></div> </div> </li> <?php } ?> </ul> <?php }
/** * Setup meta data. */ protected function setup_meta_data() { parent::setup_meta_data(); $this->taxonomy = papi_to_array($this->taxonomy); }
/** * 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 post types. * * @return array */ protected function get_post_types() { return papi_to_array($this->get_setting('post_type')); }
/** * Get dropdown items. * * @return array */ protected function get_items() { return papi_to_array($this->get_setting('items', [])); }
/** * 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; }
/** * 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 = (object) $meta; $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 (!isset($meta->post_id)) { $meta->post_id = 0; } if (!$save_value && is_array($meta->value)) { $meta->value = [$meta->value]; } if (papi_is_empty($meta->value)) { papi_cache_delete($meta->slug, $meta->post_id); if ($option) { return delete_option(papi_remove_papi($meta->slug)); } else { return delete_post_meta($meta->post_id, papi_remove_papi($meta->slug)); } } $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(papi_remove_papi($meta->slug), $value); $result = $out ? $result : $out; } else { $out = update_post_meta($meta->post_id, papi_remove_papi($meta->slug), $value); $result = $out ? $result : $out; } continue; } foreach ($value as $child_key => $child_value) { if (papi_is_empty($child_value)) { if ($option) { delete_option(papi_remove_papi($child_key)); } else { delete_post_meta($meta->post_id, papi_remove_papi($child_key)); } } else { if ($option) { update_option(papi_remove_papi($child_key), $child_value); } else { update_post_meta($meta->post_id, papi_remove_papi($child_key), $child_value); } } } } return $result; }
/** * Import value to the property. * * @param mixed $value * @param string $slug * @param int $post_id * * @return mixed */ public function import_value($value, $slug, $post_id) { if (!is_array($value) && !is_object($value) && !is_numeric($value)) { return; } $values = []; foreach (papi_to_array($value) as $val) { if ($val instanceof WP_Post) { $values[] = $val->ID; } if (is_object($val) && isset($val->id)) { $values[] = (int) $val->id; } if (is_numeric($val)) { $values[] = (int) $val; } } return $values; }