| | |
| | | <?php |
| | | namespace JVBase\meta; |
| | | |
| | | use DateTime; |
| | | use Exception; |
| | | use JVBase\utility\Features; |
| | | use WP_Post; |
| | | |
| | | if (!defined('ABSPATH')) { |
| | | exit; // Exit if accessed directly |
| | |
| | | protected string|null $object_type; |
| | | protected int $max_file_size = 5242880; |
| | | protected ?string $content = null; |
| | | protected bool $isTimeline = false; |
| | | |
| | | protected ?string $baseKey = null; |
| | | protected \wpdb $wpdb; |
| | |
| | | switch ($type) { |
| | | case 'post': |
| | | $this->data = get_post((string)$ID); |
| | | $this->content = jvbNoBase($this->data->post_type); |
| | | $this->isTimeline = Features::forContent($this->content)->has('is_timeline'); |
| | | break; |
| | | case 'term': |
| | | $this->data = get_term($ID); |
| | | $this->content = jvbNoBase($this->data->taxonomy); |
| | | break; |
| | | case 'user': |
| | | case 'integrations': |
| | | $this->data = get_user($ID); |
| | | $this->content = jvbUserRole($ID); |
| | | break; |
| | | case 'options': |
| | | $this->baseKey = $ID; |
| | |
| | | break; |
| | | } |
| | | } |
| | | $this->content = $content; |
| | | |
| | | $this->type_manager = new MetaTypeManager(); |
| | | $this->validator = new MetaValidator(); |
| | |
| | | * |
| | | * @return bool |
| | | */ |
| | | public function updateValue(string $name, mixed $value): bool |
| | | public function updateValue(string $name, mixed $value, bool $updatePost = true): bool |
| | | { |
| | | try { |
| | | // Get field definition |
| | |
| | | $field_config['name'] = $name; |
| | | // Validate value |
| | | if (!$this->validator->validate($value, $field_config)) { |
| | | error_log('Validation unsuccessful'); |
| | | throw new Exception("Validation failed for {$name}"); |
| | | } |
| | | |
| | |
| | | if ($old !== $sanitized) { |
| | | switch ($this->object_type) { |
| | | case 'post': |
| | | $ID = wp_update_post([ |
| | | |
| | | $ID = jvb_update_post([ |
| | | 'ID' => $this->object_id, |
| | | $name => $sanitized |
| | | ]); |
| | |
| | | if ($name === 'display_name') { |
| | | $link = get_user_meta($this->object_id, BASE.'link', true); |
| | | if ($link !== '') { |
| | | wp_update_post([ |
| | | jvb_update_post([ |
| | | 'ID' => $link, |
| | | 'post_title' => $sanitized |
| | | ]); |
| | |
| | | |
| | | |
| | | if ($field_config['type'] == 'taxonomy' && (!array_key_exists('taxonomy_type', $field_config))) { |
| | | $set = wp_set_post_terms($this->object_id, $sanitized, jvbCheckBase($field_config['taxonomy']), false); |
| | | if (empty(trim($sanitized))) { |
| | | // Clear all terms when value is empty |
| | | wp_set_object_terms($this->object_id, [], jvbCheckBase($field_config['taxonomy']), false); |
| | | } else { |
| | | $term_ids = array_map('intval', array_filter(explode(',', $sanitized))); |
| | | wp_set_object_terms($this->object_id, $term_ids, jvbCheckBase($field_config['taxonomy']), false); |
| | | } |
| | | } |
| | | if ($field_config['type'] === 'location' && empty($sanitized)) { |
| | | $this->addMeta('has_map', false); |
| | |
| | | throw new Exception("Failed to update meta value for {$name}"); |
| | | } |
| | | |
| | | if ($updatePost && $this->object_type === 'post') { |
| | | //Flush the cache for this post. |
| | | jvb_update_post([ |
| | | 'ID' => $this->object_id, |
| | | ]); |
| | | } |
| | | return true; |
| | | |
| | | } catch (Exception $e) { |
| | |
| | | return []; |
| | | } |
| | | |
| | | return jvbGetFields($type, $this->object_type); |
| | | $this->fields = jvbGetFields($type, $this->object_type); |
| | | return $this->fields; |
| | | } |
| | | |
| | | protected function getObjectType(): string|false |
| | |
| | | return false; |
| | | } |
| | | |
| | | public function setAll(array $fields):bool |
| | | public function setAll(array $fields, bool $updatePost = true):bool |
| | | { |
| | | if (empty($fields) || !$this->object_type) { |
| | | return false; |
| | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // Determine table based on object type |
| | | $check = array_key_exists($this->object_type, $this->wpDefaults) ? $this->wpDefaults[$this->object_type] : []; |
| | | switch ($this->object_type) { |
| | |
| | | $temp = []; |
| | | foreach ($setFields as $f) { |
| | | $temp[$f] = $fields[$f]; |
| | | unset($fields[array_search($f, $fields)]); |
| | | unset($fields[$f]); |
| | | } |
| | | $setFields = $temp; |
| | | |
| | |
| | | // Sanitize value |
| | | $sanitized = $this->sanitizer->sanitize($value, $field_config); |
| | | if ($this->checkOverrides($field, $sanitized, $field_config)) { |
| | | return true; |
| | | continue; |
| | | } |
| | | |
| | | if ($field_config['type'] === 'taxonomy' && !array_key_exists('taxonomy_type', $field_config)){ |
| | | $term_ids = array_map('intval', explode(',', trim($sanitized))); |
| | | $set = wp_set_post_terms($this->object_id, $term_ids, jvbCheckBase($field_config['taxonomy']), false); |
| | | |
| | | if ($field_config['type'] == 'taxonomy' && (!array_key_exists('taxonomy_type', $field_config))) { |
| | | if (empty(trim($sanitized))) { |
| | | // Clear all terms when value is empty |
| | | wp_set_object_terms($this->object_id, [], jvbCheckBase($field_config['taxonomy']), false); |
| | | } else { |
| | | $term_ids = array_map('intval', array_filter(explode(',', $sanitized))); |
| | | wp_set_object_terms($this->object_id, $term_ids, jvbCheckBase($field_config['taxonomy']), false); |
| | | } |
| | | } |
| | | |
| | | if ($field_config['type'] === 'location' && empty($sanitized)) { |
| | |
| | | } |
| | | |
| | | if (!empty($setFields)) { |
| | | foreach ($setFields as $field => $value) { |
| | | $field_config = $this->getFieldConfig($field); |
| | | if ($field_config) { |
| | | $setFields[$field] = $this->sanitizer->sanitize($value, $field_config); |
| | | } |
| | | |
| | | if ($field === 'post_date') { |
| | | $datetime = strtotime($setFields[$field]); |
| | | if ($datetime !== false) { |
| | | $setFields[$field] = date('Y-m-d H:i:s', $datetime); |
| | | } else { |
| | | $setFields[$field] = date('Y-m-d H:i:s', time()); |
| | | } |
| | | |
| | | $setFields['post_date_gmt'] = get_gmt_from_date($setFields[$field]); |
| | | $setFields['edit_date'] = true; |
| | | } |
| | | } |
| | | |
| | | switch ($this->object_type) { |
| | | case 'post': |
| | | if (array_key_exists('post_thumbnail', $setFields)) { |
| | |
| | | } |
| | | |
| | | if (!empty($setFields)) { |
| | | $result = wp_update_post(array_merge(['ID' => $this->object_id], $setFields), true); |
| | | $result = jvb_update_post(array_merge(['ID' => $this->object_id], $setFields)); |
| | | } |
| | | break; |
| | | case 'user': |
| | |
| | | wp_update_term($this->object_id, $this->data->taxonomy, $setFields); |
| | | break; |
| | | } |
| | | } elseif ($this->object_type === 'post' && !empty($this->object_id)) { |
| | | } elseif ($updatePost && $this->object_type === 'post' && !empty($this->object_id)) { |
| | | //Update the 'post modified' date with meta updates, for filtering |
| | | wp_update_post(['ID' => $this->object_id]); |
| | | jvb_update_post(['ID' => $this->object_id]); |
| | | } |
| | | |
| | | } catch (Exception $e) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private function getOrCreateTerm(string $termName, string $taxonomy):?int |
| | | { |
| | | $taxonomy = jvbCheckBase($taxonomy); |
| | | $term = get_term_by('name', $termName, $taxonomy); |
| | | |
| | | if (!$term) { |
| | | $result = wp_insert_term($termName, $taxonomy); |
| | | if (is_wp_error($result)) { |
| | | return null; |
| | | } |
| | | $termID = $result['term_id']; |
| | | } else { |
| | | $termID = $term->term_id; |
| | | } |
| | | |
| | | if ($termID) { |
| | | return $termID; |
| | | } |
| | | return null; |
| | | } |
| | | } |