' . esc_html__( 'No form data available.', 'airo-wp' ) . '
'; + return; + } + + echo '| ' . esc_html__( 'Field Name', 'airo-wp' ) . ' | '; + echo '' . esc_html__( 'Value', 'airo-wp' ) . ' | '; + echo '' . esc_html__( 'Type', 'airo-wp' ) . ' | '; + echo '
|---|---|---|
| ' . esc_html( $field_name ) . ' | '; + echo '' . $value . ' | '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '' . esc_html( $type ) . ' | ';
+ echo '
' . esc_html( $form_id ) . '';
+ echo '' . esc_html( $ip_address ) . '';
+ echo '' . esc_html( $user_agent ) . '';
+ echo '' . esc_html( $form_id ) . '' : '—';
+ break;
+
+ case 'email_status':
+ $email_sent = get_post_meta( $post_id, '_dsg_email_sent', true );
+ if ( '' === $email_sent ) {
+ echo '—';
+ } elseif ( 'yes' === $email_sent ) {
+ echo '✓ ' . esc_html__( 'Sent', 'airo-wp' ) . '';
+ } else {
+ echo '✗ ' . esc_html__( 'Failed', 'airo-wp' ) . '';
+ }
+ break;
+
+ case 'ip_address':
+ $ip_address = get_post_meta( $post_id, '_dsg_submission_ip', true );
+ echo $ip_address ? '' . esc_html( $ip_address ) . '' : '—';
+ break;
+ }
+ }
+
+ /**
+ * Enqueue admin styles for the submission meta box.
+ *
+ * @param string $hook Current admin page hook suffix.
+ */
+ public function enqueue_submission_styles( string $hook ) : void {
+ if ( 'post.php' !== $hook && 'post-new.php' !== $hook ) {
+ return;
+ }
+ wp_register_style( 'airowp-submissions', false, array(), AIRO_WP_VERSION ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
+ wp_enqueue_style( 'airowp-submissions' );
+ wp_add_inline_style( 'airowp-submissions', '.airo-wp-submission-status{margin-bottom:1em;padding:10px;border-left:3px solid}.airo-wp-submission-status--success{background:#d4edda;border-color:#28a745}.airo-wp-submission-status--success .airo-wp-submission-status__label{color:#155724}.airo-wp-submission-status--error{background:#f8d7da;border-color:#dc3545}.airo-wp-submission-status--error .airo-wp-submission-status__label{color:#721c24}' );
+ }
+}
diff --git a/includes/Blocks/Common/Modal/ModalHooks.php b/includes/Blocks/Common/Modal/ModalHooks.php
new file mode 100644
index 0000000..95e2e60
--- /dev/null
+++ b/includes/Blocks/Common/Modal/ModalHooks.php
@@ -0,0 +1,327 @@
+sanitize_attributes( $attributes );
+
+ /**
+ * Filter modal CSS classes.
+ *
+ * @param array $classes Array of CSS classes.
+ * @param array $attributes Modal block attributes.
+ * @param array $block Complete block data.
+ * @return array Modified classes.
+ */
+ $classes = apply_filters(
+ 'airowp_modal_classes',
+ array( 'airo-wp-modal' ),
+ $attributes,
+ $block
+ );
+
+ // Sanitize classes after filtering.
+ $classes = array_map( 'sanitize_html_class', array_filter( $classes ) );
+
+ /**
+ * Filter modal data attributes.
+ *
+ * These attributes are read by the JavaScript modal controller.
+ *
+ * @param array $data_attrs Associative array of data attributes.
+ * @param array $attributes Modal block attributes.
+ * @param array $block Complete block data.
+ * @return array Modified data attributes.
+ */
+ $data_attrs = apply_filters(
+ 'airowp_modal_data_attributes',
+ $this->get_default_data_attributes( $attributes ),
+ $attributes,
+ $block
+ );
+
+ // Sanitize data attributes after filtering.
+ $data_attrs = $this->sanitize_data_attributes( $data_attrs );
+
+ /**
+ * Action fired before modal block renders.
+ *
+ * @param array $attributes Modal block attributes.
+ * @param array $block Complete block data.
+ */
+ do_action( 'airowp_modal_before_render', $attributes, $block );
+
+ /**
+ * Filter complete modal block content.
+ *
+ * This is the final filter before output. Use this for major structural changes.
+ *
+ * @param string $block_content Current block HTML.
+ * @param array $attributes Modal block attributes.
+ * @param array $block Complete block data.
+ * @param array $classes Filtered CSS classes.
+ * @param array $data_attrs Filtered data attributes.
+ * @return string Modified block content.
+ */
+ $block_content = apply_filters(
+ 'airowp_modal_content',
+ $block_content,
+ $attributes,
+ $block,
+ $classes,
+ $data_attrs
+ );
+
+ /**
+ * Action fired after modal block renders.
+ *
+ * @param string $block_content Rendered block HTML.
+ * @param array $attributes Modal block attributes.
+ * @param array $block Complete block data.
+ */
+ do_action( 'airowp_modal_after_render', $block_content, $attributes, $block );
+
+ return $block_content;
+ }
+
+ /**
+ * Get default data attributes from modal attributes.
+ *
+ * @param array $attributes Modal block attributes.
+ * @return array Data attributes array.
+ */
+ private function get_default_data_attributes( $attributes ) {
+ $data_attrs = array();
+
+ // Map modal attributes to data attributes.
+ $attr_map = array(
+ 'modalId' => 'modal-id',
+ 'animationType' => 'animation-type',
+ 'animationDuration' => 'animation-duration',
+ 'closeOnBackdrop' => 'close-on-backdrop',
+ 'closeOnEsc' => 'close-on-esc',
+ 'disableBodyScroll' => 'disable-body-scroll',
+ 'allowHashTrigger' => 'allow-hash-trigger',
+ 'updateUrlOnOpen' => 'update-url-on-open',
+ 'autoTriggerType' => 'auto-trigger-type',
+ 'autoTriggerDelay' => 'auto-trigger-delay',
+ 'autoTriggerFrequency' => 'auto-trigger-frequency',
+ 'cookieDuration' => 'cookie-duration',
+ 'exitIntentSensitivity' => 'exit-intent-sensitivity',
+ 'exitIntentMinTime' => 'exit-intent-min-time',
+ 'exitIntentExcludeMobile' => 'exit-intent-exclude-mobile',
+ 'scrollDepth' => 'scroll-depth',
+ 'scrollDirection' => 'scroll-direction',
+ 'timeOnPage' => 'time-on-page',
+ 'galleryGroupId' => 'gallery-group-id',
+ 'galleryIndex' => 'gallery-index',
+ 'showGalleryNavigation' => 'show-gallery-navigation',
+ 'navigationStyle' => 'navigation-style',
+ 'navigationPosition' => 'navigation-position',
+ );
+
+ foreach ( $attr_map as $attr_key => $data_key ) {
+ if ( isset( $attributes[ $attr_key ] ) ) {
+ $value = $attributes[ $attr_key ];
+
+ // Convert booleans to strings.
+ if ( is_bool( $value ) ) {
+ $value = $value ? 'true' : 'false';
+ }
+
+ $data_attrs[ $data_key ] = $value;
+ }
+ }
+
+ return $data_attrs;
+ }
+
+ /**
+ * Sanitize modal attributes.
+ *
+ * @param array $attributes Attributes to sanitize.
+ * @return array Sanitized attributes.
+ */
+ private function sanitize_attributes( $attributes ) {
+ $sanitized = array();
+
+ // Define expected attribute types and validation.
+ $validators = array(
+ 'modalId' => 'sanitize_key',
+ 'width' => 'sanitize_text_field',
+ 'maxWidth' => 'sanitize_text_field',
+ 'height' => 'sanitize_text_field',
+ 'maxHeight' => 'sanitize_text_field',
+ 'animationType' => array( $this, 'validate_enum' ),
+ 'animationDuration' => 'absint',
+ 'overlayOpacity' => 'absint',
+ 'overlayColor' => 'sanitize_hex_color',
+ 'overlayBlur' => 'absint',
+ 'closeOnBackdrop' => 'rest_sanitize_boolean',
+ 'closeOnEsc' => 'rest_sanitize_boolean',
+ 'showCloseButton' => 'rest_sanitize_boolean',
+ 'closeButtonPosition' => array( $this, 'validate_enum' ),
+ 'closeButtonSize' => 'absint',
+ 'closeButtonIconColor' => 'sanitize_text_field',
+ 'closeButtonBgColor' => 'sanitize_text_field',
+ 'disableBodyScroll' => 'rest_sanitize_boolean',
+ 'allowHashTrigger' => 'rest_sanitize_boolean',
+ 'updateUrlOnOpen' => 'rest_sanitize_boolean',
+ 'autoTriggerType' => array( $this, 'validate_enum' ),
+ 'autoTriggerDelay' => 'absint',
+ 'autoTriggerFrequency' => array( $this, 'validate_enum' ),
+ 'cookieDuration' => 'absint',
+ 'exitIntentSensitivity' => array( $this, 'validate_enum' ),
+ 'exitIntentMinTime' => 'absint',
+ 'exitIntentExcludeMobile' => 'rest_sanitize_boolean',
+ 'scrollDepth' => 'absint',
+ 'scrollDirection' => array( $this, 'validate_enum' ),
+ 'timeOnPage' => 'absint',
+ 'galleryGroupId' => 'sanitize_key',
+ 'galleryIndex' => 'absint',
+ 'showGalleryNavigation' => 'rest_sanitize_boolean',
+ 'navigationStyle' => array( $this, 'validate_enum' ),
+ 'navigationPosition' => array( $this, 'validate_enum' ),
+ );
+
+ foreach ( $attributes as $key => $value ) {
+ if ( isset( $validators[ $key ] ) ) {
+ $sanitized[ $key ] = call_user_func( $validators[ $key ], $value, $key );
+ } else {
+ // If no validator defined for attribute, sanitize as text.
+ $sanitized[ $key ] = sanitize_text_field( $value );
+ }
+ }
+
+ return $sanitized;
+ }
+
+ /**
+ * Validate enum values.
+ *
+ * @param mixed $value Value to validate.
+ * @param string $key Attribute key.
+ * @return mixed Validated value or default.
+ */
+ private function validate_enum( $value, $key ) {
+ // Define valid enum values for each attribute.
+ $enums = array(
+ 'animationType' => array( 'fade', 'slide-up', 'slide-down', 'zoom', 'none' ),
+ 'closeButtonPosition' => array( 'inside-top-right', 'inside-top-left', 'top-right', 'top-left' ),
+ 'autoTriggerType' => array( 'none', 'pageLoad', 'exitIntent', 'scroll', 'time' ),
+ 'autoTriggerFrequency' => array( 'always', 'session', 'once' ),
+ 'exitIntentSensitivity' => array( 'low', 'medium', 'high' ),
+ 'scrollDirection' => array( 'down', 'both' ),
+ 'navigationStyle' => array( 'arrows', 'chevrons', 'text' ),
+ 'navigationPosition' => array( 'sides', 'bottom', 'top' ),
+ );
+
+ if ( isset( $enums[ $key ] ) && in_array( $value, $enums[ $key ], true ) ) {
+ return $value;
+ }
+
+ // Return first valid value as default if invalid value provided.
+ return isset( $enums[ $key ] ) ? $enums[ $key ][0] : sanitize_text_field( $value );
+ }
+
+ /**
+ * Sanitize data attributes.
+ *
+ * @param array $data_attrs Data attributes to sanitize.
+ * @return array Sanitized data attributes.
+ */
+ private function sanitize_data_attributes( $data_attrs ) {
+ $sanitized = array();
+
+ foreach ( $data_attrs as $key => $value ) {
+ // Sanitize key.
+ $clean_key = sanitize_key( $key );
+
+ // Sanitize value - escape for HTML attribute context.
+ if ( is_numeric( $value ) ) {
+ $clean_value = (string) $value;
+ } elseif ( is_string( $value ) ) {
+ $clean_value = esc_attr( $value );
+ } else {
+ // Convert other types to string and escape.
+ $clean_value = esc_attr( (string) $value );
+ }
+
+ $sanitized[ $clean_key ] = $clean_value;
+ }
+
+ return $sanitized;
+ }
+
+ /**
+ * Add custom scripts to footer for modal integrations.
+ *
+ * Developers can use this action to inject custom JavaScript for modal events.
+ */
+ public function modal_footer_scripts() {
+ /**
+ * Action fired in footer for custom modal scripts.
+ *
+ * Use this to add custom JavaScript that interacts with the modal API.
+ *
+ * Example:
+ * ```php
+ * add_action('airowp_modal_footer_scripts', function() {
+ * ?>
+ *
+ * \WP_REST_Server::CREATABLE,
+ 'callback' => array( $this, 'handle_render' ),
+ 'permission_callback' => array( $this, 'check_permission' ),
+ 'args' => array(
+ 'queryId' => array(
+ 'type' => 'string',
+ 'required' => true,
+ 'sanitize_callback' => 'sanitize_key',
+ ),
+
+ // NOTE: `attributes` and `params` are nested objects; WP only enforces the
+ // top-level type. The shared render helper (airowp_query_render) is
+ // responsible for per-field sanitization of every value before it reaches
+ // WP_Query args or HTML output. Do NOT assume these arrive sanitized.
+ 'attributes' => array(
+ 'type' => 'object',
+ 'required' => true,
+ ),
+ 'page' => array(
+ 'type' => 'integer',
+ 'default' => 1,
+ 'sanitize_callback' => 'absint',
+ ),
+ 'innerBlocks' => array(
+ 'type' => 'string',
+ 'default' => '',
+ ),
+ 'params' => array(
+ 'type' => 'object',
+ 'default' => array(),
+ ),
+ 'currentUrl' => array(
+ 'type' => 'string',
+ 'default' => '',
+ 'sanitize_callback' => 'esc_url_raw',
+ ),
+ ),
+ )
+ );
+
+ register_rest_route(
+ self::REST_NAMESPACE,
+ '/query/filter-register',
+ array(
+ 'methods' => \WP_REST_Server::CREATABLE,
+ 'callback' => array( $this, 'handle_filter_register' ),
+ 'permission_callback' => array( $this, 'check_manage_options_permission' ),
+ 'args' => array(
+ 'filter_key' => array(
+ 'type' => 'string',
+ 'required' => true,
+ 'sanitize_callback' => 'sanitize_key',
+ ),
+ 'config' => array(
+ 'type' => 'object',
+ 'required' => true,
+ ),
+ ),
+ )
+ );
+
+ // Admin-only routes (manage_options).
+
+ register_rest_route(
+ self::REST_NAMESPACE,
+ '/query/filter-status',
+ array(
+ 'methods' => \WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'handle_filter_status' ),
+ 'permission_callback' => array( $this, 'check_manage_options_permission' ),
+ )
+ );
+
+ register_rest_route(
+ self::REST_NAMESPACE,
+ '/query/filter-rebuild',
+ array(
+ 'methods' => \WP_REST_Server::CREATABLE,
+ 'callback' => array( $this, 'handle_filter_rebuild' ),
+ 'permission_callback' => array( $this, 'check_manage_options_permission' ),
+ )
+ );
+
+ register_rest_route(
+ self::REST_NAMESPACE,
+ '/query/preview',
+ array(
+ 'methods' => \WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'handle_preview' ),
+ 'permission_callback' => array( $this, 'check_edit_posts_permission' ),
+ 'args' => array(
+ 'attributes' => array(
+ 'type' => 'object',
+ 'required' => true,
+ ),
+ ),
+ )
+ );
+
+ register_rest_route(
+ self::REST_NAMESPACE,
+ '/query/filters',
+ array(
+ array(
+ 'methods' => \WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'handle_filters_list' ),
+ 'permission_callback' => array( $this, 'check_manage_options_permission' ),
+ ),
+ array(
+ 'methods' => \WP_REST_Server::DELETABLE,
+ 'callback' => array( $this, 'handle_filter_unregister' ),
+ 'permission_callback' => array( $this, 'check_manage_options_permission' ),
+ 'args' => array(
+ 'filter_key' => array(
+ 'type' => 'string',
+ 'required' => true,
+ 'sanitize_callback' => 'sanitize_key',
+ ),
+ ),
+ ),
+ )
+ );
+ }
+
+ /**
+ * Checks that the request carries a valid nonce and the user has manage_options.
+ *
+ * Used by every admin-only filter route: /filter-register, /filter-status,
+ * /filter-rebuild, /filters (list), /filters/{key} (delete). Editor-level
+ * users go through check_edit_posts_permission instead (used only by the
+ * /query/preview route).
+ *
+ * @param \WP_REST_Request $request The REST request.
+ * @return true|\WP_Error
+ */
+ public function check_manage_options_permission( \WP_REST_Request $request ) {
+ if ( ! is_user_logged_in() ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'You must be logged in.', 'airo-wp' ),
+ array( 'status' => 401 )
+ );
+ }
+
+ $nonce = $request->get_header( 'X-WP-Nonce' );
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'Invalid nonce.', 'airo-wp' ),
+ array( 'status' => 401 )
+ );
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'Insufficient permissions.', 'airo-wp' ),
+ array( 'status' => 403 )
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Handles the preview REST request.
+ *
+ * For `source === 'posts'` this returns a WP_Error (client uses useEntityRecords).
+ * For `source === 'users'` runs WP_User_Query limited to perPage results.
+ * For `source === 'terms'` runs get_terms() limited to perPage results.
+ *
+ * @param \WP_REST_Request $request The REST request.
+ * @return \WP_REST_Response|\WP_Error
+ */
+ public function handle_preview( \WP_REST_Request $request ) {
+ $attributes = (array) $request->get_param( 'attributes' );
+ $source = isset( $attributes['source'] ) ? sanitize_key( $attributes['source'] ) : 'posts';
+ $per_page = isset( $attributes['perPage'] ) ? max( 1, min( 100, (int) $attributes['perPage'] ) ) : 6;
+
+ if ( 'posts' === $source ) {
+ return new \WP_Error(
+ 'not_needed',
+ __( 'Use useEntityRecords for posts source preview.', 'airo-wp' ),
+ array( 'status' => 400 )
+ );
+ }
+
+ if ( 'users' === $source ) {
+ $user_query = new \WP_User_Query(
+ array(
+ 'number' => $per_page,
+ 'orderby' => 'registered',
+ 'order' => 'DESC',
+ 'fields' => array( 'ID', 'display_name' ),
+ )
+ );
+ $items = array();
+ foreach ( $user_query->get_results() as $user ) {
+ $items[] = array(
+ 'id' => (int) $user->ID,
+ 'name' => (string) $user->display_name,
+ 'type' => 'user',
+ );
+ }
+ return rest_ensure_response( $items );
+ }
+
+ if ( 'terms' === $source ) {
+ $taxonomy = isset( $attributes['taxonomy'] )
+ ? sanitize_key( $attributes['taxonomy'] )
+ : 'category';
+ $terms = get_terms(
+ array(
+ 'taxonomy' => $taxonomy,
+ 'number' => $per_page,
+ 'hide_empty' => false,
+ 'fields' => 'id=>name',
+ )
+ );
+
+ if ( is_wp_error( $terms ) || ! is_array( $terms ) ) {
+ return rest_ensure_response( array() );
+ }
+
+ $items = array();
+ foreach ( $terms as $term_id => $term_name ) {
+ $items[] = array(
+ 'id' => (int) $term_id,
+ 'name' => (string) $term_name,
+ 'type' => 'term',
+ );
+ }
+ return rest_ensure_response( $items );
+ }
+
+ return rest_ensure_response( array() );
+ }
+
+ /**
+ * Returns the current filter index status.
+ *
+ * @return \WP_REST_Response
+ */
+ public function handle_filter_status() {
+ return rest_ensure_response( FilterIndexRebuilder::status() );
+ }
+
+ /**
+ * Runs a full filter index rebuild synchronously and returns the result.
+ *
+ * Note: on large sites this may approach PHP's max_execution_time.
+ * For v2.2 the synchronous model is acceptable; the dashboard polls
+ * /filter-status every 2 s so even a timeout is handled gracefully.
+ *
+ * @return \WP_REST_Response
+ */
+ public function handle_filter_rebuild() {
+ return rest_ensure_response( FilterIndexRebuilder::rebuild_all() );
+ }
+
+ /**
+ * Returns all registered filters.
+ *
+ * @return \WP_REST_Response
+ */
+ public function handle_filters_list() {
+ return rest_ensure_response( FilterRegistry::all() );
+ }
+
+ /**
+ * Unregisters a filter by key.
+ *
+ * @param \WP_REST_Request $request The REST request.
+ * @return \WP_REST_Response|\WP_Error
+ */
+ public function handle_filter_unregister( \WP_REST_Request $request ) {
+ $key = $request->get_param( 'filter_key' );
+
+ if ( empty( $key ) ) {
+ return new \WP_Error(
+ 'airowp_filter_unregister_invalid',
+ __( 'filter_key is required.', 'airo-wp' ),
+ array( 'status' => 400 )
+ );
+ }
+
+ if ( null === FilterRegistry::get( $key ) ) {
+ return new \WP_Error(
+ 'airowp_filter_not_found',
+ __( 'Filter not found.', 'airo-wp' ),
+ array( 'status' => 404 )
+ );
+ }
+
+ FilterRegistry::unregister( $key );
+
+ return rest_ensure_response(
+ array(
+ 'unregistered' => true,
+ 'filter_key' => $key,
+ )
+ );
+ }
+
+ /**
+ * Checks that the request carries a valid nonce and the user can edit posts.
+ *
+ * Used by the /query/preview route — any editor-level user may use the live
+ * preview endpoint; only admins may mutate the filter registry (see
+ * check_manage_options_permission).
+ *
+ * @param \WP_REST_Request $request The REST request.
+ * @return true|\WP_Error
+ */
+ public function check_edit_posts_permission( \WP_REST_Request $request ) {
+ if ( ! is_user_logged_in() ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'You must be logged in.', 'airo-wp' ),
+ array( 'status' => 401 )
+ );
+ }
+
+ $nonce = $request->get_header( 'X-WP-Nonce' );
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'Invalid nonce.', 'airo-wp' ),
+ array( 'status' => 401 )
+ );
+ }
+
+ if ( ! current_user_can( 'edit_posts' ) ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'Insufficient permissions.', 'airo-wp' ),
+ array( 'status' => 403 )
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Handles the filter-register REST request.
+ *
+ * Stores the filter configuration in FilterRegistry so the PHP filter index
+ * knows how to resolve values for this filter key.
+ *
+ * @param \WP_REST_Request $request The REST request.
+ * @return \WP_REST_Response|\WP_Error
+ */
+ public function handle_filter_register( \WP_REST_Request $request ) {
+ $key = $request->get_param( 'filter_key' );
+ $config = (array) $request->get_param( 'config' );
+
+ if ( empty( $key ) || empty( $config['type'] ) || empty( $config['source'] ) ) {
+ return new \WP_Error(
+ 'airowp_filter_register_invalid',
+ __( 'filter_key, type, and source are required.', 'airo-wp' ),
+ array( 'status' => 400 )
+ );
+ }
+
+ $type = (string) $config['type'];
+ if ( ! in_array( $type, array( 'taxonomy', 'meta' ), true ) ) {
+ return new \WP_Error(
+ 'airowp_filter_invalid_type',
+ __( 'config.type must be "taxonomy" or "meta".', 'airo-wp' ),
+ array( 'status' => 400 )
+ );
+ }
+
+ FilterRegistry::register( $key, $config );
+
+ return rest_ensure_response(
+ array(
+ 'registered' => true,
+ 'filter_key' => sanitize_key( $key ),
+ 'config' => FilterRegistry::get( $key ),
+ )
+ );
+ }
+
+ /**
+ * Checks that the request is authenticated and carries a valid nonce.
+ *
+ * @param \WP_REST_Request $request The REST request.
+ * @return true|\WP_Error
+ */
+ public function check_permission( \WP_REST_Request $request ) {
+ if ( ! is_user_logged_in() ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'You must be logged in.', 'airo-wp' ),
+ array( 'status' => 401 )
+ );
+ }
+
+ $nonce = $request->get_header( 'X-WP-Nonce' );
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'Invalid nonce.', 'airo-wp' ),
+ array( 'status' => 401 )
+ );
+ }
+
+ if ( ! current_user_can( 'read' ) ) {
+ return new \WP_Error(
+ 'rest_forbidden',
+ __( 'Insufficient permissions.', 'airo-wp' ),
+ array( 'status' => 403 )
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Handles the render REST request and returns HTML + pagination metadata.
+ *
+ * @param \WP_REST_Request $request The REST request.
+ * @return \WP_REST_Response
+ */
+ public function handle_render( \WP_REST_Request $request ) {
+ $query_id = $request->get_param( 'queryId' );
+ $attributes = (array) $request->get_param( 'attributes' );
+ $page = max( 1, (int) $request->get_param( 'page' ) );
+ $inner_html = (string) $request->get_param( 'innerBlocks' );
+ $params = (array) $request->get_param( 'params' );
+ $current_url = (string) $request->get_param( 'currentUrl' );
+
+ // Sibling filter blocks (search / sort / checkbox / select / active /
+ // reset) read filter state from $_GET and the current page URL
+ // (`add_query_arg(array())`) so the no-JS fallback can build chip/
+ // reset links that navigate back to the page. On the REST refresh
+ // path, $_GET is empty and REQUEST_URI points at the REST endpoint,
+ // so we overlay both for the duration of the render and restore
+ // afterwards to avoid leaking state into later request-scoped code.
+ $original_get = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ // Snapshot REQUEST_URI raw — sanitize_text_field() mangles URL encoding
+ // (eats `+`, collapses whitespace) and this value is only ever restored
+ // to the superglobal, never echoed or used in HTML.
+ $original_uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- restore-only, see comment above.
+ $allowed_keys = apply_filters( 'airowp_query_url_params', array( 'q', 'sort' ) );
+ foreach ( $params as $key => $value ) {
+ $key = (string) $key;
+ if ( in_array( $key, $allowed_keys, true ) || 0 === strpos( $key, 'filter_' ) ) {
+ // REST-supplied values are sanitized downstream before use in
+ // WP_Query / SQL / HTML, but nested block renders may pass
+ // through filter hooks or third-party code that reads $_GET
+ // directly — sanitize at the overlay boundary too.
+ if ( is_array( $value ) ) {
+ $_GET[ $key ] = array_map( 'sanitize_text_field', wp_unslash( (array) $value ) );
+ } else {
+ $_GET[ $key ] = sanitize_text_field( wp_unslash( (string) $value ) );
+ }
+ }
+ }
+ if ( '' !== $current_url ) {
+ $parsed = wp_parse_url( $current_url );
+ if ( is_array( $parsed ) && isset( $parsed['path'] ) ) {
+ $_SERVER['REQUEST_URI'] = $parsed['path']
+ . ( isset( $parsed['query'] ) ? '?' . $parsed['query'] : '' );
+ }
+ }
+
+ try {
+ $result = self::render(
+ $attributes,
+ array(
+ 'query_id' => $query_id,
+ 'page' => $page,
+ 'inner_html' => $inner_html,
+ 'params' => $params,
+ )
+ );
+ } finally {
+ $_GET = $original_get; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $_SERVER['REQUEST_URI'] = $original_uri;
+ }
+
+ return rest_ensure_response( $result );
+ }
+
+ /**
+ * Shared render entrypoint used by both REST and first-paint render.php.
+ *
+ * Delegates to airowp_query_render_region() so the REST response
+ * contains the full region (list + sibling blocks wrapped in
+ * .airo-wp-query-region) — identical to the first-paint output. The JS
+ * refresh handler swaps the outer region's innerHTML in one operation,
+ * updating pagination + no-results + chips together with the list.
+ *
+ * @param array $attributes Block attributes.
+ * @param array $context Keys: query_id, page, inner_html (full serialized
+ * innerBlocks including siblings), params.
+ * @return array { html: string, totalPages: int, totalItems: int }
+ */
+ public static function render( array $attributes, array $context ) {
+ $helpers = AIRO_WP_PLUGIN_DIR . 'build/blocks/query/render-helpers.php';
+ if ( file_exists( $helpers ) ) {
+ require_once $helpers; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable -- build artifact; path resolved from plugin directory
+ if ( function_exists( 'airowp_query_render_region' ) ) {
+ return airowp_query_render_region( $attributes, $context );
+ }
+ // Fallback to bare render (no region wrapper) for environments where
+ // the build artefact predates the region helper (e.g. older build cache).
+ if ( function_exists( 'airowp_query_render' ) ) {
+ return airowp_query_render( $attributes, $context );
+ }
+ }
+ return array(
+ 'html' => '',
+ 'totalPages' => 0,
+ 'totalItems' => 0,
+ );
+ }
+}
diff --git a/includes/Blocks/Common/Query/FilterIndex.php b/includes/Blocks/Common/Query/FilterIndex.php
new file mode 100644
index 0000000..d8c315b
--- /dev/null
+++ b/includes/Blocks/Common/Query/FilterIndex.php
@@ -0,0 +1,517 @@
+prefix}airowp_query_filter_index custom table.
+ *
+ * @package airo-wp
+ * @since 2.2.0
+ */
+
+declare(strict_types=1);
+
+namespace GoDaddy\WordPress\Plugins\AiroWp\Blocks\Common\Query;
+
+defined( 'ABSPATH' ) || exit;
+/**
+ * Manages the airowp_query_filter_index database table.
+ */
+class FilterIndex {
+
+ /**
+ * Current schema version.
+ *
+ * Increment when columns or indexes change and add migration logic in
+ * install() before updating the stored option.
+ *
+ * v2 (2026-04-19): adds `post_type` column so count_for_options can scope
+ * per-CPT. Upgrade TRUNCATEs the table — see install().
+ */
+ const SCHEMA_VERSION = '2';
+
+ /**
+ * Option key that stores the installed schema version.
+ */
+ const OPTION_SCHEMA = 'airowp_query_filter_index_schema';
+
+ /**
+ * Option key used to record background index status (e.g. "indexing", "ready").
+ * Reserved for future reindex tasks (Task A2+).
+ */
+ const OPTION_STATUS = 'airowp_query_filter_index_status';
+
+ /**
+ * Object-cache group for count_for_options() results.
+ *
+ * Cache entries carry the current epoch in their key so a bump invalidates
+ * every outstanding entry without needing to enumerate keys (which many
+ * object-cache backends do not support).
+ */
+ const CACHE_GROUP = 'airowp_query_filter_index';
+
+ /**
+ * Cache-epoch key. Read via wp_cache_get / bumped via wp_cache_incr so a
+ * persistent object cache (Redis/Memcached) invalidates count results
+ * atomically without hitting the options table on each write.
+ */
+ const CACHE_EPOCH_KEY = 'counts_epoch';
+
+ /**
+ * TTL (seconds) for cached count results. Counts stay correct until the
+ * next write (via the epoch), but we still TTL-cap in case the epoch
+ * counter is lost (non-persistent cache restart) — bounded staleness.
+ */
+ const CACHE_TTL = 300;
+
+ /**
+ * Per-request cache of the table existence check.
+ *
+ * Null = not yet checked; true/false = checked result.
+ *
+ * @var bool|null
+ */
+ private static $table_exists = null;
+
+ /**
+ * Returns the fully-qualified table name.
+ *
+ * @return string
+ */
+ public static function table_name(): string {
+ global $wpdb;
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
+ return $wpdb->prefix . 'airowp_query_filter_index';
+ }
+
+ /**
+ * Returns true when the filter index table actually exists in the database.
+ *
+ * Result is cached for the lifetime of the request to avoid repeated
+ * SHOW TABLES queries. Call reset_table_cache() in tests between cases.
+ *
+ * @return bool
+ */
+ public static function table_exists(): bool {
+ if ( null !== self::$table_exists ) {
+ return self::$table_exists;
+ }
+ global $wpdb;
+ $table_name = self::table_name();
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
+ self::$table_exists = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table_name ) ) ) === $table_name );
+ return self::$table_exists;
+ }
+
+ /**
+ * Resets the per-request table existence cache (for tests).
+ *
+ * @return void
+ */
+ public static function reset_table_cache(): void {
+ self::$table_exists = null;
+ }
+
+ /**
+ * Reindexes a single object's filter values.
+ *
+ * Deletes all prior rows for this (object_type, object_id) and rewrites them
+ * based on the current FilterRegistry entries. Idempotent by design.
+ *
+ * @param string $object_type One of 'post' (A2), 'user' (v2.4+), 'term' (v2.4+).
+ * @param int $object_id The object's primary key.
+ */
+ public static function reindex_object( string $object_type, int $object_id ): void {
+ global $wpdb;
+ if ( $object_id <= 0 || ! self::table_exists() ) {
+ return;
+ }
+
+ // v2.2 indexes only published posts. If the post is not published,
+ // remove any existing rows and bail. This covers the case where
+ // taxonomy/meta hooks fire for a draft that was previously published.
+ $post_type = '';
+ if ( 'post' === $object_type ) {
+ $post = get_post( $object_id );
+ if ( ! $post || 'publish' !== $post->post_status ) {
+ self::remove_object( 'post', $object_id );
+ return;
+ }
+ $post_type = (string) $post->post_type;
+ }
+
+ $table = self::table_name();
+
+ // Idempotency: wipe existing rows for this object before reinsert.
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
+ $wpdb->delete(
+ $table,
+ array(
+ 'object_id' => $object_id,
+ 'object_type' => $object_type,
+ ),
+ array( '%d', '%s' )
+ );
+
+ $filters = FilterRegistry::all();
+ if ( empty( $filters ) ) {
+ return;
+ }
+
+ $rows = array();
+ foreach ( $filters as $filter_key => $config ) {
+ $values = self::resolve_filter_values( $object_type, $object_id, $config );
+ foreach ( $values as $value ) {
+ $rows[] = array(
+ 'object_id' => $object_id,
+ 'object_type' => $object_type,
+ 'post_type' => $post_type,
+ 'filter_key' => $filter_key,
+ 'filter_value' => (string) $value,
+ );
+ }
+ }
+
+ if ( empty( $rows ) ) {
+ return;
+ }
+
+ // Bulk insert — one query regardless of filter count.
+ $placeholders = array();
+ $params = array();
+ foreach ( $rows as $row ) {
+ $placeholders[] = '(%d, %s, %s, %s, %s)';
+ $params[] = $row['object_id'];
+ $params[] = $row['object_type'];
+ $params[] = $row['post_type'];
+ $params[] = $row['filter_key'];
+ $params[] = $row['filter_value'];
+ }
+
+ $sql = "INSERT INTO {$table} (object_id, object_type, post_type, filter_key, filter_value) VALUES "
+ . implode( ', ', $placeholders );
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
+ $wpdb->query( $wpdb->prepare( $sql, $params ) );
+
+ self::bump_counts_cache();
+ }
+
+ /**
+ * Resolves filter values for a given object. Posts-only in v2.2.
+ *
+ * @param string $object_type One of 'post', 'user', 'term'.
+ * @param int $object_id Object primary key.
+ * @param array $config Filter config from FilterRegistry: { type, source, label }.
+ * @return array Flat array of string values to index.
+ */
+ private static function resolve_filter_values( string $object_type, int $object_id, array $config ): array {
+ if ( 'post' !== $object_type ) {
+ return array(); // v2.4 will add user/term support.
+ }
+
+ $type = $config['type'] ?? '';
+ $source = $config['source'] ?? '';
+ if ( '' === $source ) {
+ return array();
+ }
+
+ if ( 'taxonomy' === $type ) {
+ $term_ids = wp_get_post_terms( $object_id, $source, array( 'fields' => 'ids' ) );
+ if ( is_wp_error( $term_ids ) || empty( $term_ids ) ) {
+ return array();
+ }
+ return array_map( 'strval', $term_ids );
+ }
+
+ if ( 'meta' === $type ) {
+ $meta = get_post_meta( $object_id, $source, false );
+ if ( ! is_array( $meta ) || empty( $meta ) ) {
+ return array();
+ }
+ // Filter out empty strings, non-scalars, and values exceeding the VARCHAR(190) column width.
+ $clean = array();
+ foreach ( $meta as $value ) {
+ if ( ! is_scalar( $value ) ) {
+ continue;
+ }
+ $value = (string) $value;
+ if ( '' === $value ) {
+ continue;
+ }
+ if ( mb_strlen( $value ) > 190 ) {
+ continue; // Longer than the VARCHAR(190) index column; skip to avoid truncation.
+ }
+ $clean[] = $value;
+ }
+ return $clean;
+ }
+
+ return array();
+ }
+
+ /**
+ * Deletes all index rows for a given object.
+ *
+ * Scoped by both object_id and object_type to avoid cross-type collisions
+ * (e.g. a post and a user that happen to share the same numeric ID).
+ *
+ * @param string $object_type The object type (e.g. 'post').
+ * @param int $object_id The object's primary key.
+ * @return void
+ */
+ public static function remove_object( string $object_type, int $object_id ): void {
+ if ( ! self::table_exists() ) {
+ return;
+ }
+ global $wpdb;
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
+ $wpdb->delete(
+ self::table_name(),
+ array(
+ 'object_id' => $object_id,
+ 'object_type' => $object_type,
+ ),
+ array( '%d', '%s' )
+ );
+ self::bump_counts_cache();
+ }
+
+ /**
+ * Returns the count of distinct objects matching each option value for a
+ * filter key, intersected with the current active-filter state.
+ *
+ * Within-group semantics: selections inside the same filter group are OR
+ * (showing "how many objects would match if you added this value").
+ * Across-group semantics: each other active-filter group is AND.
+ * The self-filter is excluded from the intersection so users can still see
+ * counts for all options of the group they are currently filtering on.
+ *
+ * @param string $filter_key The filter key to count options for (e.g. 'category').
+ * @param array $option_values Option values to count. Values are (string)-cast.
+ * @param array $active_filters Active filter state: [ filter_key => [ value, ... ] ].
+ * @param string $post_type Optional. When non-empty, counts are restricted
+ * to rows with a matching post_type — and so are
+ * the intersection subqueries for active filters,
+ * so a CPT-scoped query never leaks counts from
+ * other post types that share the same taxonomy.
+ * @return array [ value => count ] zero-filled for options absent from the result set.
+ */
+ public static function count_for_options( string $filter_key, array $option_values, array $active_filters, string $post_type = '' ): array {
+ if ( empty( $option_values ) || ! self::table_exists() ) {
+ return array();
+ }
+
+ global $wpdb;
+ $table = self::table_name();
+ $key = sanitize_key( $filter_key );
+ if ( '' === $key ) {
+ return array();
+ }
+
+ // Normalise option values to strings and build a keyed default (0-filled).
+ $string_values = array_values( array_unique( array_map( 'strval', $option_values ) ) );
+ $counts = array_fill_keys( $string_values, 0 );
+
+ // Exclude self-filter from intersection — OR semantics within a group.
+ unset( $active_filters[ $key ] );
+
+ // Cache lookup. Key is (epoch, filter_key, option_values, active_filters, post_type).
+ // The epoch is bumped on every index write, so cached entries remain valid
+ // until the next reindex/remove/rebuild. Skipped in tests where the
+ // per-request table_exists cache can race with the drop-table teardown.
+ $cache_key = self::build_counts_cache_key( $key, $string_values, $active_filters, $post_type );
+ $cached = wp_cache_get( $cache_key, self::CACHE_GROUP );
+ if ( is_array( $cached ) ) {
+ return $cached;
+ }
+
+ // Optional post_type scope — applied to the outer query AND each
+ // intersection subquery so cross-filter counts stay within the CPT.
+ $post_type_sql = '';
+ $subquery_pt_sql = '';
+ $post_type_params = array();
+ if ( '' !== $post_type ) {
+ $post_type_sql = ' AND post_type = %s';
+ $subquery_pt_sql = ' AND post_type = %s';
+ $post_type_params[] = $post_type;
+ }
+
+ // Build intersection subqueries, one per active-filter group.
+ $intersect_sql = '';
+ $intersect_params = array();
+
+ foreach ( $active_filters as $f_key => $f_values ) {
+ $sanitized_f_key = sanitize_key( (string) $f_key );
+ if ( '' === $sanitized_f_key || empty( $f_values ) ) {
+ continue;
+ }
+ $f_strings = array_values( array_unique( array_map( 'strval', (array) $f_values ) ) );
+ if ( empty( $f_strings ) ) {
+ continue;
+ }
+ $f_placeholders = implode( ',', array_fill( 0, count( $f_strings ), '%s' ) );
+ $intersect_sql .= " AND object_id IN (
+ SELECT object_id FROM {$table}
+ WHERE filter_key = %s AND filter_value IN ({$f_placeholders}){$subquery_pt_sql}
+ )";
+ $intersect_params[] = $sanitized_f_key;
+ foreach ( $f_strings as $v ) {
+ $intersect_params[] = $v;
+ }
+ if ( '' !== $post_type ) {
+ $intersect_params[] = $post_type;
+ }
+ }
+
+ $value_placeholders = implode( ',', array_fill( 0, count( $string_values ), '%s' ) );
+ $sql = "SELECT filter_value, COUNT(DISTINCT object_id) AS cnt
+ FROM {$table}
+ WHERE filter_key = %s AND filter_value IN ({$value_placeholders}){$post_type_sql}
+ {$intersect_sql}
+ GROUP BY filter_value";
+
+ $params = array_merge( array( $key ), $string_values, $post_type_params, $intersect_params );
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
+ $rows = $wpdb->get_results( $wpdb->prepare( $sql, $params ) );
+
+ if ( is_array( $rows ) ) {
+ foreach ( $rows as $row ) {
+ if ( array_key_exists( $row->filter_value, $counts ) ) {
+ $counts[ $row->filter_value ] = (int) $row->cnt;
+ }
+ }
+ }
+
+ wp_cache_set( $cache_key, $counts, self::CACHE_GROUP, self::CACHE_TTL ); // phpcs:ignore WordPressVIPMinimum.Performance.LowExpiryCacheTime.CacheTimeUndetermined -- CACHE_TTL = 300 seconds (VIP minimum)
+
+ return $counts;
+ }
+
+ /**
+ * Builds a cache key for count_for_options() that scopes the cached value to
+ * the current cache epoch + the full argument shape. Any index write bumps
+ * the epoch, so stale entries become unreachable without explicit deletion.
+ *
+ * @param string $filter_key Sanitized filter key.
+ * @param array $string_values Sorted, unique option values.
+ * @param array $active_filters Active filter state (minus self-filter).
+ * @param string $post_type Post-type scope or empty string for all.
+ * @return string
+ */
+ private static function build_counts_cache_key( string $filter_key, array $string_values, array $active_filters, string $post_type = '' ): string {
+ $epoch = self::get_counts_epoch();
+ // Sort values and active filters for stable key regardless of input order.
+ sort( $string_values );
+ ksort( $active_filters );
+ foreach ( $active_filters as $k => $vs ) {
+ if ( is_array( $vs ) ) {
+ $vs = array_values( array_unique( array_map( 'strval', $vs ) ) );
+ sort( $vs );
+ $active_filters[ $k ] = $vs;
+ }
+ }
+ return 'cfo:' . $epoch . ':' . md5(
+ $filter_key . '|' . wp_json_encode( $string_values ) . '|' . wp_json_encode( $active_filters ) . '|pt=' . $post_type
+ );
+ }
+
+ /**
+ * Returns the current counts cache epoch — an incrementing integer used as
+ * part of the cache key so bumping the epoch invalidates every outstanding
+ * cached result without key enumeration.
+ *
+ * @return int
+ */
+ private static function get_counts_epoch(): int {
+ $epoch = wp_cache_get( self::CACHE_EPOCH_KEY, self::CACHE_GROUP );
+ if ( false === $epoch ) {
+ $epoch = 1;
+ wp_cache_set( self::CACHE_EPOCH_KEY, $epoch, self::CACHE_GROUP );
+ }
+ return (int) $epoch;
+ }
+
+ /**
+ * Bumps the counts cache epoch, invalidating all previously-cached
+ * count_for_options() results. Called from reindex_object / remove_object
+ * and by the rebuilder on completion. Object-cache-only (no DB write) so
+ * bumping inside tight loops is safe; with a persistent cache backend the
+ * bump is atomic via wp_cache_incr.
+ *
+ * @return void
+ */
+ public static function bump_counts_cache(): void {
+ $incremented = wp_cache_incr( self::CACHE_EPOCH_KEY, 1, self::CACHE_GROUP );
+ if ( false === $incremented ) {
+ // Non-persistent caches (or no cache yet) — seed then bump.
+ $current = (int) wp_cache_get( self::CACHE_EPOCH_KEY, self::CACHE_GROUP );
+ wp_cache_set( self::CACHE_EPOCH_KEY, $current + 1, self::CACHE_GROUP );
+ }
+ }
+
+ /**
+ * Returns true if the given filter key is registered in FilterRegistry.
+ *
+ * @param string $filter_key The filter key to check (e.g. 'category').
+ * @return bool
+ */
+ public static function is_available( string $filter_key ): bool {
+ return null !== FilterRegistry::get( $filter_key );
+ }
+
+ /**
+ * Creates or upgrades the filter index table via dbDelta.
+ *
+ * Safe to call multiple times — dbDelta is idempotent.
+ *
+ * @return void
+ */
+ public static function install(): void {
+ global $wpdb;
+
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
+
+ $table = self::table_name();
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
+ $charset = $wpdb->get_charset_collate();
+ $stored_schema = (string) get_option( self::OPTION_SCHEMA, '0' );
+ $needs_truncate = self::table_exists() && version_compare( $stored_schema, '2', '<' );
+
+ // Note: PRIMARY KEY requires two spaces before the column name — dbDelta quirk.
+ // post_type is VARCHAR(40) to match WP's wp_posts.post_type column width.
+ // Empty string for non-post object_types (users/terms in v2.4+).
+ $sql = "CREATE TABLE {$table} (
+ id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
+ object_id BIGINT UNSIGNED NOT NULL,
+ object_type VARCHAR(20) NOT NULL,
+ post_type VARCHAR(40) NOT NULL DEFAULT '',
+ filter_key VARCHAR(190) NOT NULL,
+ filter_value VARCHAR(190) NOT NULL,
+ indexed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (id),
+ KEY filter_key_value (filter_key, filter_value),
+ KEY filter_scope (post_type, filter_key, filter_value),
+ KEY object_lookup (object_type, object_id)
+) {$charset};";
+
+ dbDelta( $sql );
+
+ // On a v1 → v2 upgrade, pre-existing rows have post_type='' (dbDelta's
+ // DEFAULT fills new columns). A per-CPT count query would miss them,
+ // so TRUNCATE and rely on the admin dashboard / WP-CLI rebuild to
+ // reindex with correct post_type values. v2.2 has not shipped yet so
+ // no production data is lost.
+ if ( $needs_truncate ) {
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
+ $wpdb->query( $wpdb->prepare( 'TRUNCATE TABLE %i', $table ) );
+ self::bump_counts_cache();
+ }
+
+ // Reset the per-request cache so subsequent calls see the new table.
+ self::$table_exists = null;
+
+ update_option( self::OPTION_SCHEMA, self::SCHEMA_VERSION, false );
+ }
+}
diff --git a/includes/Blocks/Common/Query/FilterIndexCLI.php b/includes/Blocks/Common/Query/FilterIndexCLI.php
new file mode 100644
index 0000000..ed3e60b
--- /dev/null
+++ b/includes/Blocks/Common/Query/FilterIndexCLI.php
@@ -0,0 +1,168 @@
+]
+ * : Posts to process per batch. Default 200, min 50.
+ *
+ * ## EXAMPLES
+ *
+ * wp dsgo query index rebuild
+ * wp dsgo query index rebuild --batch-size=500
+ *
+ * @param array $args Positional arguments (unused).
+ * @param array $assoc_args Named arguments (batch-size).
+ */
+ public function rebuild( $args, $assoc_args ): void {
+ $batch = (int) \WP_CLI\Utils\get_flag_value( $assoc_args, 'batch-size', 200 );
+ $result = FilterIndexRebuilder::rebuild_all( array( 'batch_size' => $batch ) );
+
+ if ( 'error' === ( $result['status'] ?? '' ) ) {
+ \WP_CLI::error( sprintf( 'Rebuild failed (status: %s).', $result['status'] ) );
+ }
+
+ \WP_CLI::success(
+ sprintf(
+ 'Indexed %d objects (%d rows).',
+ (int) $result['processed'],
+ (int) $result['total_rows']
+ )
+ );
+ }
+
+ /**
+ * Rebuild a single filter.
+ *
+ * ## OPTIONS
+ *
+ * Contact Us
+ + + +Whether you are searching for your dream home or considering selling your property, our team is ready to provide the exceptional service you deserve.
+ + + ++1 (310) 555-0100
+inquiries@luxuryestates.com
+9876 Wilshire Blvd, Beverly Hills, CA 90210
+Take the first step toward resolving your legal matter. Contact us today to schedule a confidential consultation with one of our experienced attorneys.
+ + + +123 Legal Plaza, Suite 500, Business City, ST 12345
+(555) 123-4567
+contact@professionalfirm.com
+Monday - Friday: 8:30 AM - 6:00 PM
+We would love to hear from you. Send us a message and we will respond as soon as possible.
+Our Office
+ + + +123 Business Street
New York, NY 10001
United States
Phone: +1 (555) 123-4567
Email: hello@example.com
Get In Touch
+ + + +Have a question or want to work together? We would love to hear from you.
+123 Business Avenue, New York, NY 10001
++1 (555) 123-4567
+hello@company.com
+Mon - Fri: 9:00 AM - 6:00 PM
+Have a question or want to work together? We are here to help you bring your ideas to life.
+ + + + + + + + +We are a team of passionate designers and developers dedicated to creating exceptional digital products. Our mission is to help businesses transform their ideas into reality.
+ + + + + + + +Empowering businesses with innovative solutions.
+Leading the digital transformation revolution.
+Integrity, innovation, and client success.
+50+ experts across design and development.
+About Me
+ + + +With over 10 years of experience in product design, I have helped companies ranging from early-stage startups to Fortune 500 companies create meaningful digital experiences.
+ + + +I believe great design is invisible - it should feel intuitive and delightful without getting in the way. My approach combines user research, strategic thinking, and pixel-perfect execution to deliver results that matter.
+ + + +When not designing, you will find me mentoring aspiring designers, speaking at conferences, or exploring hiking trails with my camera.
+A comprehensive approach to achieving your goals
+STEP 01
+ + + +We start by understanding your business goals and creating a comprehensive roadmap for success. Our team analyzes market trends and competitive landscapes.
+ + + + +STEP 02
+ + + +Our expert team brings your vision to life with cutting-edge design and robust development practices that ensure scalability and performance.
+ + + + +STEP 03
+ + + +We ensure a smooth launch and provide ongoing support to help you grow. Our data-driven approach helps optimize performance continuously.
+ + + + +Trusted by Leading Brands
+ + + +VOGUE
+ + + +NIKE
+ + + +SPOTIFY
+ + + +AIRBNB
+Current Campaign
+ + + +We are building 10 new schools in rural communities. Every donation brings us closer to making education accessible to 5,000 more children.
+Previously worked with
+ + + +Spotify
+ + + +Airbnb
+ + + +Stripe
+ + + +Notion
+Personal Training
+ + + +Get personalized attention and a customized workout plan designed specifically for your goals, fitness level, and schedule.
+ + + +Custom workout plans
+Nutrition guidance
+Progress tracking
+Flexible scheduling
+TRUSTED BY INNOVATIVE TEAMS WORLDWIDE
+ + + +STRIPE
+ + + +NOTION
+ + + +FIGMA
+ + + +VERCEL
+ + + +LINEAR
+Featured Courses
+ + + +★★★★★ 4.9
+Dr. Angela Yu • 65 hours
+ + + +$89.99
+ + + +$199.99
+★★★★★ 4.8
+Jose Portilla • 45 hours
+ + + +$94.99
+ + + +$179.99
+★★★★★ 4.9
+Sarah Chen • 38 hours
+ + + +$79.99
+ + + +$149.99
+Event Schedule
+ + + +Opening Keynote: The Future of Tech
+ + + +James Chen • Main Stage
+9:00 AM
+AI & Machine Learning Workshop
+ + + +Panel Discussion • Workshop Room A
+11:00 AM
+Networking Lunch
+ + + +Exhibition Hall
+12:30 PM
+Welcome Reception & Demo Showcase
+ + + +Startup Demos • Rooftop Terrace
+6:00 PM
+Cloud Architecture at Scale
+ + + +Sarah Miller • Main Stage
+9:00 AM
+Startup Pitch Competition
+ + + +10 Startups • Innovation Stage
+2:00 PM
+VIP Dinner & Awards Ceremony
+ + + +Grand Ballroom
+7:00 PM
+Cybersecurity in the AI Era
+ + + +Emily Zhang • Main Stage
+9:00 AM
+Closing Keynote: Building Tomorrow
+ + + +All Speakers • Main Stage
+4:00 PM
+See the impact we have made together
+Success Stories
+ + + +About Us
+ + + +For over two decades, we have been the trusted advisors for clients seeking extraordinary properties. Our deep expertise in luxury markets, combined with unparalleled discretion and personalized service, sets us apart.
+ + + +We understand that finding the perfect home is about more than square footage and amenities. It is about discovering a residence that reflects your lifestyle, aspirations, and vision for the future.
+ + + +Visit Us
+ + + +Address
+ + + +456 Culinary Lane
Downtown District, City 12345
Hours
+ + + +Tue - Thu: 5:00 PM - 10:00 PM
Fri - Sat: 5:00 PM - 11:00 PM
Sun: 4:00 PM - 9:00 PM
Monday: Closed
Reservations
+ + + +(555) 987-6543
+Trusted by Industry Leaders
+ + + +Chef Favorites
+ + + +Our most beloved creations, made with the freshest seasonal ingredients.
+$34
+Wild-caught salmon with lemon herb crust, served with seasonal vegetables and saffron risotto.
+$48
+Aged tenderloin with red wine reduction, truffle mashed potatoes, and grilled asparagus.
+$42
+Maine lobster tail atop creamy Arborio rice with saffron, white wine, and fresh herbs.
+Our Mission
+ + + +We believe everyone deserves access to clean water, education, healthcare, and economic opportunity. Through sustainable programs and community partnerships, we work to break the cycle of poverty.
+ + + +Our approach focuses on long-term solutions that empower communities to thrive independently. We invest in local leaders, provide training and resources, and measure our impact to ensure every dollar makes a difference.
+ + + + +Selected projects we are proud of
+Fashion & Retail
Complete redesign of a fashion e-commerce platform with improved UX.
Health & Wellness
A comprehensive fitness tracking app with social features and gamification.
Visual Design
Complete brand identity including logo, guidelines, and marketing materials.
Get started in just four simple steps
+01
+Sign up for free in under a minute. No credit card required to get started.
+02
+Customize your workspace with our intuitive setup wizard and preferences.
+03
+Easily import your existing data from spreadsheets or other platforms.
+04
+You are all set! Start using the platform and watch your business grow.
+Featured Products
+ + + +Footwear
+ + + +$149
+ + + +$99
+Accessories
+ + + +$249
+Bags
+ + + +$189
+Eyewear
+ + + +$129
+Product Showcase
+ + + +We have honed our skills over years of experience to deliver exceptional results in every project we undertake.
+ + + + +The best way to predict the future is to create it. Innovation distinguishes between a leader and a follower.
+ + + +Steve Jobs
+ + + +Co-founder, Apple Inc.
+Drag to explore the cards or use navigation arrows
+Our team combines creativity with technical expertise to deliver exceptional results that drive real business growth.
+ + + + + + + + +About Us
+ + + +For over a decade, we have been helping businesses transform their digital presence. Our team of experts combines creativity with technical excellence to deliver solutions that drive real results.
+ + + +We believe in building lasting partnerships with our clients, understanding their unique challenges, and crafting tailored solutions that exceed expectations.
+ + + +Our Sponsors
+ + + +TECHCORP
+ + + +CLOUDIFY
+ + + +DATAFLOW
+ + + +NEXUSAI
+ + + +SCALABLE
+Trusted by thousands of businesses worldwide
+Discover how we can help you achieve your goals
+ + + +We create stunning websites that work perfectly on all devices. Our design process focuses on user experience and conversion optimization.
+ + + + +Our development team builds scalable, secure, and high-performance web applications using the latest technologies and best practices.
+ + + + +Drive growth with our comprehensive digital marketing strategies. We help you reach your target audience and convert them into loyal customers.
+ + + + +We are always here to help. Our dedicated support team ensures your website runs smoothly and any issues are resolved quickly.
+ + + + +Why Choose Us
+ + + +We understand the challenges of modern product development. That is why we built a platform that gets out of your way and lets you focus on what matters.
+ + + +Key milestones that shaped who we are today
+ + + +Started in a small garage with just two founders and a vision to transform the industry.
+Raised $10M in Series A funding to accelerate product development and expand our team.
+Opened offices in London, Tokyo, and Sydney, reaching customers in over 100 countries.
+Trusted by 10,000+ companies worldwide
+ + + +Acme Corp
+ + + +TechFlow
+ + + +Innovate Inc
+ + + +DataStream
+ + + +CloudBase
+We combine deep expertise with personalized service to deliver exceptional outcomes for every client.
+ + + +Proven Track Record
+ + + +Over 30 years of successful outcomes for clients across industries.
+Personalized Attention
+ + + +Direct access to senior partners who personally handle your matters.
+Transparent Communication
+ + + +Clear updates and honest advice throughout your engagement.
+Results-Driven Approach
+ + + +Focused strategies designed to achieve your specific objectives.
+Welcome to our comprehensive guide. This article will walk you through everything you need to know to get started and make the most of our platform. Whether you are a beginner or an experienced user, you will find valuable insights here.
+ + + +We have designed this guide to be easy to follow, with clear explanations and practical examples that you can apply immediately to your projects.
+ + + +The first step is to understand the fundamentals. Our platform is built on modern web standards and follows best practices for performance, accessibility, and user experience.
+ + + +To begin, you will need to familiarize yourself with the basic concepts and terminology. This foundation will help you navigate the more advanced features with confidence.
+ + + +Our platform offers a rich set of features designed to streamline your workflow and enhance your productivity. Here are some of the highlights:
+ + + +To get the most out of our platform, we recommend following these best practices that have been refined through years of user feedback and research.
+ + + +First, start with a clear plan and objectives. Understanding what you want to achieve will help you make better decisions throughout your project.
+ + + +Second, take advantage of templates and patterns. These pre-built components can save you time and ensure consistency across your work.
+ + + +We hope this guide has given you a solid understanding of how to use our platform effectively. Remember, the best way to learn is by doing, so do not be afraid to experiment and explore.
+ + + +If you have any questions or need further assistance, our support team is always here to help. Happy building!
+We combine cutting-edge technology with user-centered design to create experiences that delight and convert.
+We have honed our skills over years of experience to deliver exceptional results in every project we undertake.
+ + + + +See the impact we have made together
+Join thousands of companies already using our platform to grow faster.
+No credit card required • 14-day free trial • Cancel anytime
+Get 50% off your first year. This exclusive deal ends soon.
+Start a Project
+ + + +Let us discuss your project and explore how we can help you achieve your goals.
+ + + + +hello@creativestudio.com
++1 (555) 123-4567
+123 Design Street, Creative City
+Don\'t miss out on our biggest sale of the year. Offer ends soon!
+ + + +No credit card required. Cancel anytime.
+Your donation today will transform lives for generations to come. Together, we can build a world where everyone has the opportunity to thrive.
+ + + +Join our community of learners and unlock your potential. Get unlimited access to all courses with our subscription plans.
+ + + +Do not miss the most anticipated tech event of 2026. Limited seats available - secure yours today!
+ + + +Join thousands of teams already using our platform to work smarter.
+ + + +No credit card required. 14-day free trial.
+Join thousands of satisfied customers who have transformed their business with our solutions.
+ + + +Subscribe to our newsletter for exclusive deals, new arrivals, and style inspiration delivered straight to your inbox.
+ + + +No spam, unsubscribe anytime. By subscribing you agree to our Privacy Policy.
+Get the latest updates, tips, and exclusive offers delivered straight to your inbox.
+ + + + +Join 10,000+ subscribers
+Reserve your table today and let us create a memorable dining experience for you and your guests.
+ + + +Join thousands of teams already using our platform to ship better products faster. Start your free trial today.
+ + + +Join thousands of creators who have transformed their ideas into stunning websites. Start building today with our powerful tools.
+ + + +No credit card required • Free forever plan available
+Join today and get your first week free. No commitment, no risk. Just results.
+ + + +Get Involved
+ + + +There are many ways to support our mission beyond financial donations. Your time, skills, and voice can make a tremendous impact.
+ + + + +Get in Touch
+ + + +Have a project in mind? I would love to hear about it. Drop me a message and let us create something amazing together.
+ + + +FAQ
+ + + +Can\'t find what you\'re looking for? Feel free to contact our support team for personalized assistance.
+ + + + +FAQ
+ + + +Can\'t find what you\'re looking for? Feel free to contact our support team for personalized assistance.
+ + + + +Find answers to common questions about our services
+We offer a comprehensive range of digital services including web design, development, digital marketing, SEO optimization, and ongoing maintenance and support for your website.
+Project timelines vary based on complexity. A simple website typically takes 2-4 weeks, while more complex projects with custom functionality may take 6-12 weeks or longer.
+Yes! We work with clients worldwide through video calls, email, and project management tools. Distance is never an obstacle to delivering exceptional results.
+We typically require 50% deposit upfront with the remaining balance due upon project completion. For larger projects, we can arrange milestone-based payments.
+We offer a satisfaction guarantee. If you are not happy with our work, we will revise it until you are satisfied. Refunds are available within the first week if no substantial work has begun.
+We accept all major credit cards, PayPal, bank transfers, and can accommodate other payment methods upon request for international clients.
+Yes, we offer various maintenance and support packages to keep your website secure, updated, and running smoothly after launch.
+Absolutely! We build on WordPress with user-friendly interfaces. We also provide training so you can confidently manage your content and make updates.
+With our support packages, we monitor your site and address issues quickly. We also maintain regular backups so your data is always protected.
+We implement industry-standard security measures including SSL certificates, regular updates, secure hosting, firewalls, and malware scanning to protect your site.
+Yes, we take confidentiality seriously. All client data is protected under our privacy policy, and we can sign NDAs for sensitive projects upon request.
+Yes, we ensure all websites we build are GDPR compliant with proper cookie notices, privacy policies, and data handling procedures in place.
+Everything you need to know about our platform.
+FAQ
+ + + +Find answers to common questions about our products, shipping, and return policies.
+ + + + +Find answers organized by topic
+Explore the powerful capabilities that make our platform the choice of professionals worldwide.
+ + + + +Features
+ + + +Powerful features to help you build better products faster.
+Optimized for speed with lazy loading and efficient code that keeps your site running smoothly.
+Built with security best practices to keep your data safe and your site protected.
+Tailor every aspect to match your brand with extensive customization options.
+Track your performance with built-in analytics and detailed reporting dashboards.
+Work together seamlessly with team features, permissions, and real-time collaboration.
+Get help when you need it with our dedicated support team available around the clock.
+Free shipping on all orders over $50. Fast delivery within 3-5 business days.
+30-day hassle-free returns. Not satisfied? Get a full refund, no questions asked.
+Your payment information is protected with industry-leading encryption.
+Our Classes
+ + + +From high-intensity workouts to mindful yoga, we offer classes for every fitness level and goal.
+High-intensity interval training to maximize calorie burn and boost metabolism.
+ + + +45 min • All Levels
+Build muscle and increase strength with our expert-led weight training sessions.
+ + + +60 min • Intermediate
+Improve flexibility, balance, and mental clarity with mindful movement practices.
+ + + +60 min • All Levels
+High-energy indoor cycling with motivating music and inspiring instructors.
+ + + +45 min • All Levels
+Features
+ + + +Powerful tools designed to help your team move faster and build better products.
+Hover to learn more
+ +Track every metric that matters with live dashboards. Get instant insights into user behavior, conversion rates, and performance metrics.
+ + +Learn more →
+ +Hover to learn more
+ +Work together seamlessly with real-time editing, comments, and shared workspaces. Keep everyone aligned and moving fast.
+ + +Learn more →
+ +Hover to learn more
+ +Automate repetitive tasks and workflows. Set up triggers, actions, and rules that work while you sleep.
+ + +Learn more →
+ +Our Services
+ + + +Hover to learn more
+ +Our expert agents guide you through every step of finding and acquiring your perfect property. From initial search to closing, we negotiate on your behalf to secure the best terms.
+ + +Learn more →
+ +Hover to learn more
+ +Receive accurate, data-driven valuations backed by our deep knowledge of luxury markets. We analyze comparable sales, market trends, and unique property features.
+ + +Learn more →
+ +Hover to learn more
+ +Access exclusive listings worldwide through our international network. From New York penthouses to Mediterranean villas, we connect you with extraordinary properties globally.
+ + +Learn more →
+ +Our Focus Areas
+ + + +Building schools and providing scholarships to give children the education they deserve.
+Installing wells and water systems to provide safe drinking water to communities.
+Funding medical clinics and providing essential healthcare services to underserved areas.
+Microloans and vocational training to help families build sustainable livelihoods.
+Powerful features to help you succeed
+Optimized for speed with sub-second load times and efficient resource usage across all devices.
+Enterprise-grade security with encryption, regular audits, and compliance with industry standards.
+Tailor every aspect to match your brand with extensive customization options and flexible settings.
+Stay current with automatic updates that bring new features and security patches seamlessly.
+Round-the-clock expert support to help you whenever you need assistance with any issues.
+Comprehensive analytics dashboard to track performance and make data-driven decisions.
+Powerful features to help you build better websites, faster.
+Optimized for performance with lazy loading, minimal CSS, and efficient JavaScript.
Every block adapts beautifully to any screen size, from mobile to desktop.
Built with WCAG guidelines in mind, ensuring your site is usable by everyone.
Adjust colors, spacing, typography, and more using the familiar WordPress interface.
Works seamlessly with any WordPress theme that supports the block editor.
Constantly improved with new features, bug fixes, and WordPress compatibility.
Popular Categories
+ + + +Choose from a wide range of categories to find the perfect course for your career goals.
+120+ Courses
+85+ Courses
+95+ Courses
+200+ Courses
+What We Do
+ + + +From strategy to execution, we help ambitious brands stand out in a crowded marketplace.
+01
+ + + +We craft compelling brand identities that resonate with your audience and differentiate you from competitors.
+02
+ + + +Beautiful, functional websites that convert visitors into customers and showcase your brand at its best.
+03
+ + + +Data-driven campaigns that reach your target audience and deliver measurable business results.
+What I Offer
+ + + +End-to-end product design from concept to launch, including user research, wireframing, and high-fidelity prototypes.
+Intuitive interfaces and seamless experiences that delight users and achieve business goals.
+Visual identity systems including logos, color palettes, typography, and brand guidelines.
+Comprehensive expertise across key areas to serve your needs.
+Corporate formation, contracts, mergers and acquisitions, and business dispute resolution.
+ + + + +Commercial and residential transactions, zoning, development, and property disputes.
+ + + + +Civil litigation, dispute resolution, arbitration, and aggressive courtroom representation.
+ + + + +Workplace compliance, discrimination claims, employment contracts, and HR consulting.
+ + + + +Wills, trusts, estate administration, and wealth transfer strategies.
+ + + + +Tax planning, IRS representation, and strategic tax minimization for individuals and businesses.
+ + + + +Powerful features designed to help you work smarter, not harder.
+Optimized performance that keeps your team moving fast without slowdowns.
+Bank-level encryption and compliance certifications to protect your data.
+Real-time collaboration tools that keep your entire team in sync.
+Actionable insights and custom dashboards to track what matters.
+Automate repetitive tasks and focus on what really matters.
+Lightning-fast delivery from data centers around the world.
+Choose the right plan for your needs
+The Experience
+ + + +A showcase of our recent projects and creative work
+Our Work
+ + + +Explore our portfolio of innovative digital solutions.
+Digital Marketing
+Web Application
+Online Store
+iOS & Android
+Enterprise Software
+Business Solution
+Selected Work
+ + + +Branding / Web Design
+Digital Marketing / Strategy
+Social Media / Content
+UX Design / Development
+Featured Listings
+ + + +Portfolio
+ + + +Product Design / Mobile App
+UX Design / Web App
+UI Design / E-commerce
+Branding / Visual Identity
+info@yourbusiness.com · (555) 123-4567
+ + + + +Everything you need to create stunning websites that convert visitors into customers.
Launch faster with beautiful, conversion-focused designs that adapt to any brand and speak to your audience.
We combine strategy, design, and technology to create digital experiences that drive real results for your business.
Award-Winning Creative Studio
+ + + +A full-service creative agency specializing in brand strategy, web design, and digital marketing that drives real results.
+ + + +We partner with founders and teams to unlock potential, streamline operations, and accelerate sustainable business growth.
+ +Create stunning websites with powerful blocks designed for modern WordPress.
+ + + + +Thoughtfully designed pieces that transform everyday moments into extraordinary experiences
Discover our curated collection of premium essentials designed for the modern lifestyle. Quality craftsmanship meets contemporary design.
+ + + +Join over 100,000 learners worldwide and transform your career with our comprehensive online courses taught by industry professionals.
+ + + +500+ Courses
+Expert Instructors
+Certificates
+The premier conference for innovators, entrepreneurs, and tech leaders shaping the future of technology.
+ + + +Join us for the biggest product launch of 2025. Reserve your spot today.
+Transform Your Body, Transform Your Life
+ + + +State-of-the-art equipment, expert trainers, and a supportive community to help you achieve your fitness goals.
+ + + +Exceptional Properties
+ + + +Curating the world\'s most prestigious properties for discerning buyers who demand excellence.
+ + + +The all-in-one platform that helps teams collaborate, analyze, and deliver exceptional software experiences.
+ + + +Making a Difference Since 2010
+ + + +Join our mission to provide hope, resources, and opportunities to communities in need around the world.
+ + + +We help businesses grow with innovative solutions and cutting-edge technology.
+ + + +Hi, I am Sarah
+ + + +I help startups and established brands create beautiful, user-centered digital experiences that drive growth and delight users.
+ + + +Connect:
+ + + +Trusted Advisors Since 1995
+ + + +We provide strategic counsel to businesses and individuals, helping you navigate complex challenges with confidence and achieve your goals.
+ + + +Our Story
+ + + +Founded by Chef Maria Santos, our restaurant celebrates the rich culinary traditions of the Mediterranean with a modern twist.
+ + + +Every dish tells a story, crafted with locally-sourced ingredients and time-honored techniques passed down through generations. We believe that great food brings people together, creating moments that last a lifetime.
+ + + +15+
+ + + +Years of Excellence
+50k+
+ + + +Happy Guests
+4.9
+ + + +Star Rating
+The all-in-one platform that helps teams collaborate, automate workflows, and deliver results faster than ever before.
+ + + +No credit card required. 14-day free trial.
+Elevate your website with stunning visuals, smooth animations, and powerful customization options that adapt to any design vision.
+ + + +Watch how our platform transforms the way you build websites
+ + + + + + + + + + + +No credit card required • Free 14-day trial
+Award-Winning Creative Studio
+ + + +A full-service creative agency specializing in brand strategy, web design, and digital marketing that drives real results.
+ + + +Trusted by Leading Brands
+ + + +VOGUE
+ + + +NIKE
+ + + +SPOTIFY
+ + + +AIRBNB
+What We Do
+ + + +From strategy to execution, we help ambitious brands stand out in a crowded marketplace.
+01
+ + + +We craft compelling brand identities that resonate with your audience and differentiate you from competitors.
+02
+ + + +Beautiful, functional websites that convert visitors into customers and showcase your brand at its best.
+03
+ + + +Data-driven campaigns that reach your target audience and deliver measurable business results.
+Selected Work
+ + + +Branding / Web Design
+Digital Marketing / Strategy
+Social Media / Content
+UX Design / Development
+The Team
+ + + +Creative Director
+Lead Designer
+Strategy Director
+Marketing Lead
+Testimonials
+ + + +Start a Project
+ + + +Let us discuss your project and explore how we can help you achieve your goals.
+ + + + +hello@creativestudio.com
++1 (555) 123-4567
+123 Design Street, Creative City
+Discover our curated collection of premium essentials designed for the modern lifestyle. Quality craftsmanship meets contemporary design.
+ + + +Featured Products
+ + + +Footwear
+ + + +$149
+ + + +$99
+Accessories
+ + + +$249
+Bags
+ + + +$189
+Eyewear
+ + + +$129
+Free shipping on all orders over $50. Fast delivery within 3-5 business days.
+30-day hassle-free returns. Not satisfied? Get a full refund, no questions asked.
+Your payment information is protected with industry-leading encryption.
+Customer Love
+ + + +FAQ
+ + + +Find answers to common questions about our products, shipping, and return policies.
+ + + + +Subscribe to our newsletter for exclusive deals, new arrivals, and style inspiration delivered straight to your inbox.
+ + + +No spam, unsubscribe anytime. By subscribing you agree to our Privacy Policy.
+Join over 100,000 learners worldwide and transform your career with our comprehensive online courses taught by industry professionals.
+ + + +500+ Courses
+Expert Instructors
+Certificates
+Popular Categories
+ + + +Choose from a wide range of categories to find the perfect course for your career goals.
+120+ Courses
+85+ Courses
+95+ Courses
+200+ Courses
+Featured Courses
+ + + +★★★★★ 4.9
+Dr. Angela Yu • 65 hours
+ + + +$89.99
+ + + +$199.99
+★★★★★ 4.8
+Jose Portilla • 45 hours
+ + + +$94.99
+ + + +$179.99
+★★★★★ 4.9
+Sarah Chen • 38 hours
+ + + +$79.99
+ + + +$149.99
+Expert Instructors
+ + + +Web Development
+Data Science
+UI/UX Design
+Marketing
+Student Success
+ + + +Join our community of learners and unlock your potential. Get unlimited access to all courses with our subscription plans.
+ + + +The premier conference for innovators, entrepreneurs, and tech leaders shaping the future of technology.
+ + + +Featured Speakers
+ + + +Hear from visionaries who are transforming industries and shaping the future of technology.
+CEO, TechVenture Labs
+ + + +AI & Machine Learning
+VP Engineering, CloudScale
+ + + +Cloud Architecture
+Founder, DataDriven
+ + + +Data Science
+CTO, SecureNet
+ + + +Cybersecurity
+Event Schedule
+ + + +Opening Keynote: The Future of Tech
+ + + +James Chen • Main Stage
+9:00 AM
+AI & Machine Learning Workshop
+ + + +Panel Discussion • Workshop Room A
+11:00 AM
+Networking Lunch
+ + + +Exhibition Hall
+12:30 PM
+Welcome Reception & Demo Showcase
+ + + +Startup Demos • Rooftop Terrace
+6:00 PM
+Cloud Architecture at Scale
+ + + +Sarah Miller • Main Stage
+9:00 AM
+Startup Pitch Competition
+ + + +10 Startups • Innovation Stage
+2:00 PM
+VIP Dinner & Awards Ceremony
+ + + +Grand Ballroom
+7:00 PM
+Cybersecurity in the AI Era
+ + + +Emily Zhang • Main Stage
+9:00 AM
+Closing Keynote: Building Tomorrow
+ + + +All Speakers • Main Stage
+4:00 PM
+Tickets
+ + + +Early bird pricing available for a limited time. Choose the pass that fits your needs.
+$
+ + + +499
+Early Bird Price
+ + + +3-day conference access
+ + + +All keynotes & sessions
+ + + +Networking events
+ + + +Conference materials
+$
+ + + +899
+Early Bird Price
+ + + +Everything in General
+ + + +VIP lounge access
+ + + +Speaker meet & greet
+ + + +VIP dinner & awards
+ + + +Priority seating
+$
+ + + +3,999
+5 Team Members
+ + + +5 VIP passes
+ + + +Dedicated account manager
+ + + +Private meeting room
+ + + +Logo on event materials
+Our Sponsors
+ + + +TECHCORP
+ + + +CLOUDIFY
+ + + +DATAFLOW
+ + + +NEXUSAI
+ + + +SCALABLE
+Do not miss the most anticipated tech event of 2026. Limited seats available - secure yours today!
+ + + +Transform Your Body, Transform Your Life
+ + + +State-of-the-art equipment, expert trainers, and a supportive community to help you achieve your fitness goals.
+ + + +Our Classes
+ + + +From high-intensity workouts to mindful yoga, we offer classes for every fitness level and goal.
+High-intensity interval training to maximize calorie burn and boost metabolism.
+ + + +45 min • All Levels
+Build muscle and increase strength with our expert-led weight training sessions.
+ + + +60 min • Intermediate
+Improve flexibility, balance, and mental clarity with mindful movement practices.
+ + + +60 min • All Levels
+High-energy indoor cycling with motivating music and inspiring instructors.
+ + + +45 min • All Levels
+Personal Training
+ + + +Get personalized attention and a customized workout plan designed specifically for your goals, fitness level, and schedule.
+ + + +Custom workout plans
+Nutrition guidance
+Progress tracking
+Flexible scheduling
+Membership Plans
+ + + +Perfect for getting started
+ + + +$
+ + + +29
+ + + +/month
+Gym access (6am-10pm)
+ + + +Basic equipment
+ + + +Locker room access
+ + + +Free WiFi
+Everything you need to succeed
+ + + +$
+ + + +59
+ + + +/month
+24/7 gym access
+ + + +All equipment & classes
+ + + +1 PT session/month
+ + + +Sauna & spa access
+ + + +Guest passes (2/month)
+The ultimate fitness experience
+ + + +$
+ + + +99
+ + + +/month
+Everything in Premium
+ + + +4 PT sessions/month
+ + + +Nutrition coaching
+ + + +Recovery treatments
+ + + +Priority booking
+Expert Trainers
+ + + +Head Trainer
+Yoga & Pilates
+Strength Coach
+Cycling & HIIT
+Join today and get your first week free. No commitment, no risk. Just results.
+ + + +Exceptional Properties
+ + + +Curating the world\'s most prestigious properties for discerning buyers who demand excellence.
+ + + +About Us
+ + + +For over two decades, we have been the trusted advisors for clients seeking extraordinary properties. Our deep expertise in luxury markets, combined with unparalleled discretion and personalized service, sets us apart.
+ + + +We understand that finding the perfect home is about more than square footage and amenities. It is about discovering a residence that reflects your lifestyle, aspirations, and vision for the future.
+ + + +Featured Listings
+ + + +Our Services
+ + + +Hover to learn more
+ +Our expert agents guide you through every step of finding and acquiring your perfect property. From initial search to closing, we negotiate on your behalf to secure the best terms.
+ + +Learn more →
+ +Hover to learn more
+ +Receive accurate, data-driven valuations backed by our deep knowledge of luxury markets. We analyze comparable sales, market trends, and unique property features.
+ + +Learn more →
+ +Hover to learn more
+ +Access exclusive listings worldwide through our international network. From New York penthouses to Mediterranean villas, we connect you with extraordinary properties globally.
+ + +Learn more →
+ +Testimonials
+ + + +Contact Us
+ + + +Whether you are searching for your dream home or considering selling your property, our team is ready to provide the exceptional service you deserve.
+ + + ++1 (310) 555-0100
+inquiries@luxuryestates.com
+9876 Wilshire Blvd, Beverly Hills, CA 90210
+The all-in-one platform that helps teams collaborate, analyze, and deliver exceptional software experiences.
+ + + +TRUSTED BY INNOVATIVE TEAMS WORLDWIDE
+ + + +STRIPE
+ + + +NOTION
+ + + +FIGMA
+ + + +VERCEL
+ + + +LINEAR
+Features
+ + + +Powerful tools designed to help your team move faster and build better products.
+Hover to learn more
+ +Track every metric that matters with live dashboards. Get instant insights into user behavior, conversion rates, and performance metrics.
+ + +Learn more →
+ +Hover to learn more
+ +Work together seamlessly with real-time editing, comments, and shared workspaces. Keep everyone aligned and moving fast.
+ + +Learn more →
+ +Hover to learn more
+ +Automate repetitive tasks and workflows. Set up triggers, actions, and rules that work while you sleep.
+ + +Learn more →
+ +Why Choose Us
+ + + +We understand the challenges of modern product development. That is why we built a platform that gets out of your way and lets you focus on what matters.
+ + + +Product Showcase
+ + + +Pricing
+ + + +$
+ + + +0
+ + + +/month
+Up to 3 team members
+ + + +Basic analytics
+ + + +1GB storage
+ + + +Community support
+$
+ + + +29
+ + + +/month
+Unlimited team members
+ + + +Advanced analytics
+ + + +100GB storage
+ + + +Priority support
+ + + +API access
+Custom
+Everything in Pro
+ + + +Custom integrations
+ + + +Unlimited storage
+ + + +Dedicated support
+ + + +SLA guarantee
+Join thousands of teams already using our platform to ship better products faster. Start your free trial today.
+ + + +Making a Difference Since 2010
+ + + +Join our mission to provide hope, resources, and opportunities to communities in need around the world.
+ + + +Our Mission
+ + + +We believe everyone deserves access to clean water, education, healthcare, and economic opportunity. Through sustainable programs and community partnerships, we work to break the cycle of poverty.
+ + + +Our approach focuses on long-term solutions that empower communities to thrive independently. We invest in local leaders, provide training and resources, and measure our impact to ensure every dollar makes a difference.
+ + + + +Our Focus Areas
+ + + +Building schools and providing scholarships to give children the education they deserve.
+Installing wells and water systems to provide safe drinking water to communities.
+Funding medical clinics and providing essential healthcare services to underserved areas.
+Microloans and vocational training to help families build sustainable livelihoods.
+Current Campaign
+ + + +We are building 10 new schools in rural communities. Every donation brings us closer to making education accessible to 5,000 more children.
+Success Stories
+ + + +Get Involved
+ + + +There are many ways to support our mission beyond financial donations. Your time, skills, and voice can make a tremendous impact.
+ + + + +Your donation today will transform lives for generations to come. Together, we can build a world where everyone has the opportunity to thrive.
+ + + +Hi, I am Sarah
+ + + +I help startups and established brands create beautiful, user-centered digital experiences that drive growth and delight users.
+ + + +Connect:
+ + + +Previously worked with
+ + + +Spotify
+ + + +Airbnb
+ + + +Stripe
+ + + +Notion
+About Me
+ + + +With over 10 years of experience in product design, I have helped companies ranging from early-stage startups to Fortune 500 companies create meaningful digital experiences.
+ + + +I believe great design is invisible - it should feel intuitive and delightful without getting in the way. My approach combines user research, strategic thinking, and pixel-perfect execution to deliver results that matter.
+ + + +When not designing, you will find me mentoring aspiring designers, speaking at conferences, or exploring hiking trails with my camera.
+What I Offer
+ + + +End-to-end product design from concept to launch, including user research, wireframing, and high-fidelity prototypes.
+Intuitive interfaces and seamless experiences that delight users and achieve business goals.
+Visual identity systems including logos, color palettes, typography, and brand guidelines.
+Portfolio
+ + + +Product Design / Mobile App
+UX Design / Web App
+UI Design / E-commerce
+Branding / Visual Identity
+Kind Words
+ + + +"Sarah has an incredible ability to understand complex problems and translate them into elegant, user-friendly solutions. She transformed our product completely."
+ + + +Jason Miller
+ + + +CEO, TechVenture
+"Working with Sarah was a dream. She is not just a designer but a true partner who cares deeply about the success of your product. Highly recommended!"
+ + + +Lisa Chen
+ + + +Product Lead, InnovateCo
+Get in Touch
+ + + +Have a project in mind? I would love to hear about it. Drop me a message and let us create something amazing together.
+ + + +Trusted Advisors Since 1995
+ + + +We provide strategic counsel to businesses and individuals, helping you navigate complex challenges with confidence and achieve your goals.
+ + + +Comprehensive expertise across key areas to serve your needs.
+Corporate formation, contracts, mergers and acquisitions, and business dispute resolution.
+ + + + +Commercial and residential transactions, zoning, development, and property disputes.
+ + + + +Civil litigation, dispute resolution, arbitration, and aggressive courtroom representation.
+ + + + +Workplace compliance, discrimination claims, employment contracts, and HR consulting.
+ + + + +Wills, trusts, estate administration, and wealth transfer strategies.
+ + + + +Tax planning, IRS representation, and strategic tax minimization for individuals and businesses.
+ + + + +We combine deep expertise with personalized service to deliver exceptional outcomes for every client.
+ + + +Proven Track Record
+ + + +Over 30 years of successful outcomes for clients across industries.
+Personalized Attention
+ + + +Direct access to senior partners who personally handle your matters.
+Transparent Communication
+ + + +Clear updates and honest advice throughout your engagement.
+Results-Driven Approach
+ + + +Focused strategies designed to achieve your specific objectives.
+Experienced professionals dedicated to your success.
+Managing Partner
+ + + +Harvard Law, 25+ years in corporate law and complex litigation.
+Senior Partner, Real Estate
+ + + +Yale Law, specializing in commercial real estate and development.
+Senior Partner, Tax Advisory
+ + + +Stanford Law, CPA with expertise in tax strategy and IRS matters.
+"They handled our company merger with exceptional skill and attention to detail. Their guidance was invaluable throughout the entire process."
+ + + +Thomas Anderson
+ + + +CEO, Anderson Industries
+"Professional, responsive, and truly invested in our success. They have been our trusted advisors for over a decade now."
+ + + +Patricia Reynolds
+ + + +Managing Director, Reynolds Group
+Take the first step toward resolving your legal matter. Contact us today to schedule a confidential consultation with one of our experienced attorneys.
+ + + +123 Legal Plaza, Suite 500, Business City, ST 12345
+(555) 123-4567
+contact@professionalfirm.com
+Monday - Friday: 8:30 AM - 6:00 PM
+Est. 2010 - Farm to Table Dining
+ + + +Experience the finest seasonal ingredients crafted with passion and served with warmth in the heart of downtown.
+ + + +Our Story
+ + + +Founded by Chef Maria Santos, our restaurant celebrates the rich culinary traditions of the Mediterranean with a modern twist.
+ + + +Every dish tells a story, crafted with locally-sourced ingredients and time-honored techniques passed down through generations. We believe that great food brings people together, creating moments that last a lifetime.
+ + + +15+
+ + + +Years of Excellence
+50k+
+ + + +Happy Guests
+4.9
+ + + +Star Rating
+Chef Favorites
+ + + +Our most beloved creations, made with the freshest seasonal ingredients.
+$34
+Wild-caught salmon with lemon herb crust, served with seasonal vegetables and saffron risotto.
+$48
+Aged tenderloin with red wine reduction, truffle mashed potatoes, and grilled asparagus.
+$42
+Maine lobster tail atop creamy Arborio rice with saffron, white wine, and fresh herbs.
+The Experience
+ + + +Reviews
+ + + +★★★★★
+ + + +"An unforgettable dining experience! The lobster risotto was pure perfection. Will definitely be back."
+ + + +- Michael R., via Google
+★★★★★
+ + + +"We celebrated our anniversary here and it was magical. The service was impeccable and the food was outstanding."
+ + + +- Sarah T., via Yelp
+★★★★★
+ + + +"Best restaurant in the city, hands down. The chef truly understands how to bring out the best in each ingredient."
+ + + +- James L., via TripAdvisor
+Visit Us
+ + + +Address
+ + + +456 Culinary Lane
Downtown District, City 12345
Hours
+ + + +Tue - Thu: 5:00 PM - 10:00 PM
Fri - Sat: 5:00 PM - 11:00 PM
Sun: 4:00 PM - 9:00 PM
Monday: Closed
Reservations
+ + + +(555) 987-6543
+Reserve your table today and let us create a memorable dining experience for you and your guests.
+ + + +The all-in-one platform that helps teams collaborate, automate workflows, and deliver results faster than ever before.
+ + + +No credit card required. 14-day free trial.
+Trusted by 10,000+ companies worldwide
+ + + +Acme Corp
+ + + +TechFlow
+ + + +Innovate Inc
+ + + +DataStream
+ + + +CloudBase
+Powerful features designed to help you work smarter, not harder.
+Optimized performance that keeps your team moving fast without slowdowns.
+Bank-level encryption and compliance certifications to protect your data.
+Real-time collaboration tools that keep your entire team in sync.
+Actionable insights and custom dashboards to track what matters.
+Automate repetitive tasks and focus on what really matters.
+Lightning-fast delivery from data centers around the world.
+See the impact we have made together
+Join thousands of satisfied customers who have transformed their workflow.
+★★★★★
+ + + +"This platform completely transformed how our team collaborates. We have seen a 40% increase in productivity since switching."
+ + + +Sarah Chen
+ + + +VP of Operations, TechCorp
+★★★★★
+ + + +"The automation features alone have saved us countless hours every week. Best investment we have made this year."
+ + + +Marcus Johnson
+ + + +CEO, StartupFlow
+★★★★★
+ + + +"Outstanding customer support and a product that just works. Our team adopted it instantly with zero learning curve."
+ + + +Emily Rodriguez
+ + + +Director, Digital Agency
+Choose the plan that fits your needs. Upgrade or downgrade anytime.
+Perfect for individuals and small teams getting started.
+ + + +$19/month
+ + + +For growing teams that need more power and flexibility.
+ + + +$49/month
+ + + +For large organizations with advanced needs and custom requirements.
+ + + +$149/month
+ + + +Everything you need to know about our platform.
+Join thousands of teams already using our platform to work smarter.
+ + + +No credit card required. 14-day free trial.
+Click the button below to trigger the modal:
+ + + + +Choose the plan that fits your needs. Upgrade or downgrade anytime.
+$9/month
Perfect for individuals and small projects getting started.
$29/month
For growing teams that need more power and flexibility.
$99/month
For large organizations with advanced needs and support.
$19/mo
+ + + + +$49/mo
+ + + + +$15/mo
+ + + +Save $48/year
+ + + + +$39/mo
+ + + +Save $120/year
+ + + + +Tickets
+ + + +Early bird pricing available for a limited time. Choose the pass that fits your needs.
+$
+ + + +499
+Early Bird Price
+ + + +3-day conference access
+ + + +All keynotes & sessions
+ + + +Networking events
+ + + +Conference materials
+$
+ + + +899
+Early Bird Price
+ + + +Everything in General
+ + + +VIP lounge access
+ + + +Speaker meet & greet
+ + + +VIP dinner & awards
+ + + +Priority seating
+$
+ + + +3,999
+5 Team Members
+ + + +5 VIP passes
+ + + +Dedicated account manager
+ + + +Private meeting room
+ + + +Logo on event materials
+Membership Plans
+ + + +Perfect for getting started
+ + + +$
+ + + +29
+ + + +/month
+Gym access (6am-10pm)
+ + + +Basic equipment
+ + + +Locker room access
+ + + +Free WiFi
+Everything you need to succeed
+ + + +$
+ + + +59
+ + + +/month
+24/7 gym access
+ + + +All equipment & classes
+ + + +1 PT session/month
+ + + +Sauna & spa access
+ + + +Guest passes (2/month)
+The ultimate fitness experience
+ + + +$
+ + + +99
+ + + +/month
+Everything in Premium
+ + + +4 PT sessions/month
+ + + +Nutrition coaching
+ + + +Recovery treatments
+ + + +Priority booking
+Pricing
+ + + +$
+ + + +0
+ + + +/month
+Up to 3 team members
+ + + +Basic analytics
+ + + +1GB storage
+ + + +Community support
+$
+ + + +29
+ + + +/month
+Unlimited team members
+ + + +Advanced analytics
+ + + +100GB storage
+ + + +Priority support
+ + + +API access
+Custom
+Everything in Pro
+ + + +Custom integrations
+ + + +Unlimited storage
+ + + +Dedicated support
+ + + +SLA guarantee
+Choose the plan that fits your needs. Upgrade or downgrade anytime.
+Perfect for individuals and small teams getting started.
+ + + +$19/month
+ + + +For growing teams that need more power and flexibility.
+ + + +$49/month
+ + + +For large organizations with advanced needs and custom requirements.
+ + + +$149/month
+ + + +Pricing
+ + + +Save 20% with annual billing. All plans include a 14-day free trial.
+$19
+ + + +/month
+Perfect for individuals and small projects.
+ + + +$49
+ + + +/month
+For growing teams that need more power.
+ + + +$99
+ + + +/month
+For large organizations with custom needs.
+ + + +$15
+ + + +/month
+ + +Billed annually at $180/year
+ + + +$39
+ + + +/month
+ + +Billed annually at $468/year
+ + + +$79
+ + + +/month
+ + +Billed annually at $948/year
+ + + +What We Offer
+ + + +Comprehensive solutions tailored to help your business grow and succeed in the digital landscape.
+Custom websites and web applications built with modern technologies for optimal performance.
+ + + + +Beautiful, intuitive interfaces designed with user experience at the forefront.
+ + + + +Data-driven strategies to increase your online presence and drive conversions.
+ + + + +The Team
+ + + +Creative Director
+Lead Designer
+Strategy Director
+Marketing Lead
+Hover over our team members to learn more
+Product Manager
+ +Chris brings 10 years of product experience from leading tech companies. When not building products, you can find him hiking or playing guitar.
+ + + + +Lead Developer
+ +Maria is a React and WordPress expert who loves building accessible interfaces. She contributes to open source and mentors junior developers.
+ + + + +UX Designer
+ +James creates intuitive user experiences backed by research. He is passionate about accessibility and inclusive design practices.
+ + + + +The talented people behind our success
+CEO & Founder
+ + + + +CTO
+ + + + +Lead Designer
+ + + + +Marketing Lead
+ + + + +The talented people behind our success
+CEO & Founder
Visionary leader with 15+ years in tech startups.
CTO
Full-stack architect passionate about performance.
Design Lead
Award-winning designer focused on user experience.
Marketing Director
Growth strategist driving brand awareness.
Click on a team member to learn more about them
+Expert Instructors
+ + + +Web Development
+Data Science
+UI/UX Design
+Marketing
+Experienced professionals dedicated to your success.
+Managing Partner
+ + + +Harvard Law, 25+ years in corporate law and complex litigation.
+Senior Partner, Real Estate
+ + + +Yale Law, specializing in commercial real estate and development.
+Senior Partner, Tax Advisory
+ + + +Stanford Law, CPA with expertise in tax strategy and IRS matters.
+Featured Speakers
+ + + +Hear from visionaries who are transforming industries and shaping the future of technology.
+CEO, TechVenture Labs
+ + + +AI & Machine Learning
+VP Engineering, CloudScale
+ + + +Cloud Architecture
+Founder, DataDriven
+ + + +Data Science
+CTO, SecureNet
+ + + +Cybersecurity
+Expert Trainers
+ + + +Head Trainer
+Yoga & Pilates
+Strength Coach
+Cycling & HIIT
+Testimonials
+ + + +Real feedback from real customers who have transformed their business.
+"Working with this team was a game-changer. They delivered beyond our expectations and helped us achieve a 200% increase in conversions."
+ + + +Sarah Johnson
+ + + +CEO, TechStart Inc.
+"The attention to detail and commitment to excellence is unmatched. They truly understand our business needs and deliver solutions that work."
+ + + +Michael Chen
+ + + +Founder, GrowthLab
+"From concept to launch, the experience was seamless. Their team is responsive, creative, and delivers on time, every time."
+ + + +David Martinez
+ + + +CTO, InnovateCo
+Testimonials
+ + + +Kind Words
+ + + +"Sarah has an incredible ability to understand complex problems and translate them into elegant, user-friendly solutions. She transformed our product completely."
+ + + +Jason Miller
+ + + +CEO, TechVenture
+"Working with Sarah was a dream. She is not just a designer but a true partner who cares deeply about the success of your product. Highly recommended!"
+ + + +Lisa Chen
+ + + +Product Lead, InnovateCo
+Join thousands of satisfied customers who have transformed their workflow.
+★★★★★
+ + + +"This platform completely transformed how our team collaborates. We have seen a 40% increase in productivity since switching."
+ + + +Sarah Chen
+ + + +VP of Operations, TechCorp
+★★★★★
+ + + +"The automation features alone have saved us countless hours every week. Best investment we have made this year."
+ + + +Marcus Johnson
+ + + +CEO, StartupFlow
+★★★★★
+ + + +"Outstanding customer support and a product that just works. Our team adopted it instantly with zero learning curve."
+ + + +Emily Rodriguez
+ + + +Director, Digital Agency
+James Wilson
+ + + +CTO, StartupHub
+"The performance gains we have seen since switching to airo-wp are remarkable. Our Core Web Vitals scores improved significantly."
+ + + +★★★★★
+Lisa Thompson
+ + + +Marketing Director, BrandCo
+"The patterns saved us weeks of design work. We launched our new site in record time with professional-looking sections."
+ + + +★★★★★
+David Park
+ + + +Agency Owner, WebCraft
+"Our team loves how easy it is to customize. The blocks work perfectly with our existing theme and match our brand guidelines."
+ + + +★★★★★
+Amanda Foster
+ + + +Designer, CreativeStudio
+"Finally, a block library that understands design! The attention to spacing, typography, and visual hierarchy is exceptional."
+ + + +★★★★★
+Reviews
+ + + +★★★★★
+ + + +"An unforgettable dining experience! The lobster risotto was pure perfection. Will definitely be back."
+ + + +- Michael R., via Google
+★★★★★
+ + + +"We celebrated our anniversary here and it was magical. The service was impeccable and the food was outstanding."
+ + + +- Sarah T., via Yelp
+★★★★★
+ + + +"Best restaurant in the city, hands down. The chef truly understands how to bring out the best in each ingredient."
+ + + +- James L., via TripAdvisor
+Testimonials
+ + + +"They handled our company merger with exceptional skill and attention to detail. Their guidance was invaluable throughout the entire process."
+ + + +Thomas Anderson
+ + + +CEO, Anderson Industries
+"Professional, responsive, and truly invested in our success. They have been our trusted advisors for over a decade now."
+ + + +Patricia Reynolds
+ + + +Managing Director, Reynolds Group
+Real reviews from real customers
+"This product has completely transformed how we work. The interface is intuitive and the features are exactly what we needed. Highly recommended!"
+ + + +Amanda Peters
+ + + +Marketing Director
+"The customer support is outstanding. Every time I had a question, they responded quickly and resolved my issues efficiently. Great experience overall."
+ + + +David Kim
+ + + +Software Engineer
+"We have seen a 40% increase in productivity since implementing this solution. The ROI has been incredible and the team loves using it daily."
+ + + +Sarah Mitchell
+ + + +Operations Manager
+Join thousands of satisfied users building amazing websites
+Customer Love
+ + + +Student Success
+ + + +Working with this team transformed our business. Their innovative approach and dedication to excellence helped us achieve results we never thought possible.
+ + + +Robert Chen
+ + + +CEO, TechStart Inc.
++ {__( + 'Colors applied to all accordion items when open.', + 'airo-wp' + )} +
+ ++ {hoverBackgroundColor || hoverTextColor + ? __( + 'Custom hover colors set. Clear to use open state colors.', + 'airo-wp' + ) + : __( + 'Hover colors mirror open state by default. Set custom colors to override.', + 'airo-wp' + )} +
++ {__('Heading Level', 'airo-wp')} +
+Nested
' + + '