indexOffering($entity->id()); } public function indexOffering(int $offering_id): void { if ($offering_id <= 0 || get_post_type($offering_id) !== Offering::PT) return; $fields = $this->fields(); $values = get_post_meta($offering_id, \DayTidy\Modules\Offering\Core\Module::OFFERING_FIELDS_META, true); if (!is_array($values)) $values = []; $this->deleteIndex($offering_id); foreach ($fields as $field_id => $field) { if (!array_key_exists($field_id, $values)) continue; $type = (string) ($field['type'] ?? ''); $value = $values[$field_id]; if ($type === Number::TYPE) { if (is_numeric($value)) add_post_meta($offering_id, self::key((string) $field_id, true), (string) $value, false); continue; } if ($type === Agreement::TYPE) { add_post_meta($offering_id, self::key((string) $field_id), $value ? '1' : '0', false); continue; } if ($type === Checkboxes::TYPE && is_array($value)) { foreach ($value as $item) { $item = sanitize_text_field((string) $item); if ($item !== '') add_post_meta($offering_id, self::key((string) $field_id), $item, false); } continue; } if (is_array($value)) $value = implode(' ', array_map('sanitize_text_field', $value)); $value = sanitize_text_field((string) $value); if ($value !== '') add_post_meta($offering_id, self::key((string) $field_id), $value, false); } } public function maybeScheduleBackfill(): void { $version = $this->fieldsVersion(); if (get_option(self::VERSION_OPTION, '') === $version) return; if (wp_next_scheduled(self::CRON_HOOK)) return; update_option(self::OFFSET_OPTION, 0, false); wp_schedule_single_event(time() + 5, self::CRON_HOOK); } public function backfillBatch(): void { $offset = absint(get_option(self::OFFSET_OPTION, 0)); $ids = get_posts([ 'post_type' => Offering::PT, 'post_status' => 'any', 'fields' => 'ids', 'posts_per_page' => self::BATCH_SIZE, 'offset' => $offset, 'orderby' => 'ID', 'order' => 'ASC', ]); foreach ($ids as $id) { $this->indexOffering((int) $id); } if (count($ids) === self::BATCH_SIZE) { update_option(self::OFFSET_OPTION, $offset + self::BATCH_SIZE, false); wp_schedule_single_event(time() + 5, self::CRON_HOOK); return; } update_option(self::VERSION_OPTION, $this->fieldsVersion(), false); delete_option(self::OFFSET_OPTION); } private function deleteIndex(int $offering_id): void { $db = new Db(); $db->query($db->prepare( "DELETE FROM {$db->table('postmeta')} WHERE post_id = %d AND meta_key LIKE %s", $offering_id, $db->escLike(self::KEY_PREFIX) . '%' )); } /** * @return mixed[] */ private function fields(): array { $config = DayTidyConfig::module('offering/core'); $fields = isset($config['fields']) && is_array($config['fields']) ? $config['fields'] : []; return CustomFields::normalize($fields); } private function fieldsVersion(): string { return md5((string) wp_json_encode($this->fields())); } }