AlkantarClanX12
Your IP : 216.73.217.24
<?php
/**
* @package ACF
* @author WP Engine
*
* © 2026 Advanced Custom Fields (ACF®). All rights reserved.
* "ACF" is a trademark of WP Engine.
* Licensed under the GNU General Public License v2 or later.
* https://www.gnu.org/licenses/gpl-2.0.html
*/
namespace ACF\AI\GEO;
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* ACF GEO Extension
*
* Extends ACF admin interface to add AI-related settings and functionality.
*/
class GEO {
/**
* Constructs the GEO class.
*
* @since 6.8.0
*
* @return void
*/
public function __construct() {
$this->init();
}
/**
* Initialize the GEO extension,
*
* @since 6.8.0
*
* @return void
*/
public function init() {
// Add hooks for ACF admin interface extensions for post types.
add_filter( 'acf/post_type/additional_settings_tabs', array( $this, 'add_schema_tab' ) );
add_action( 'acf/post_type/render_settings_tab/schema', array( $this, 'render_post_type_schema_tab' ) );
// Initialize GEO submodules.
// Field Settings.
new FieldSettings();
// JSON-LD Outputs.
new Outputs\Posts();
// Note: Blocks output is initialized separately in PRO (see acf-pro.php).
}
/**
* Adds the "Schema" settings tab for post types.
*
* @since 6.8.0
*
* @param array $tabs An array of the existing tabs.
* @return array
*/
public function add_schema_tab( $tabs ) {
$tabs['schema'] = __( 'Schema', 'acf' );
return $tabs;
}
/**
* Render "Schema" tab content for post types
*
* @since 6.8.0
*
* @param array $acf_post_type The ACF post type data.
*/
public function render_post_type_schema_tab( $acf_post_type ) {
?>
<span class="acf-experimental-badge acf-field"><?php esc_html_e( 'Experimental', 'acf' ); ?></span>
<?php
// Add post-type-specific field: auto JSON-LD.
acf_render_field_wrap(
array(
'type' => 'true_false',
'name' => 'auto_jsonld',
'key' => 'auto_jsonld',
'prefix' => 'acf_post_type',
'value' => $acf_post_type['auto_jsonld'] ?? 0,
'label' => __( 'Automatically add JSON-LD data for fields on this post type', 'acf' ),
'instructions' => __( 'When enabled, ACF field data will be automatically included as JSON-LD structured data in the page head for better SEO and semantic markup.', 'acf' ),
'ui' => true,
'default' => 0,
)
);
// Add post-type-specific field: schema type.
acf_render_field_wrap(
array(
'type' => 'select',
'name' => 'schema_type',
'key' => 'schema_type',
'prefix' => 'acf_post_type',
'value' => $acf_post_type['schema_type'] ?? '',
'label' => __( 'Schema.org Type', 'acf' ),
'instructions' => __( 'The Schema.org @type for JSON-LD output. By default, the type is automatically detected based on the schema properties assigned to your fields. You can assign additional types here. Select multiple types if needed (e.g., Recipe + Article).', 'acf' ),
'choices' => $this->get_schema_types(),
'default' => '',
'allow_null' => 1,
'multiple' => 1,
'ui' => 1,
),
'div',
'field'
);
}
/**
* Get available Schema.org types for selection
*
* @since 6.8.0
*
* @return array A hierarchical array of Schema.org types grouped by category.
*/
public function get_schema_types() {
$types = array();
// Get all types from schema hierarchy.
$all_types = array_keys( SchemaData::get_type_hierarchy() );
// Add 'Thing' which is the root and doesn't have a parent.
$all_types[] = 'Thing';
sort( $all_types );
// Get priority types from Schema class.
$priority_types_list = Schema::get_priority_types();
$common_types_cat = __( 'Common Types', 'acf' );
$all_types_cat = __( 'All Types', 'acf' );
// Add priority types under "Common Types" group.
$types[ $common_types_cat ] = array();
foreach ( $priority_types_list as $type ) {
if ( in_array( $type, $all_types, true ) ) {
$types[ $common_types_cat ][ $type ] = $type;
}
}
// Add remaining types under "All Types".
$remaining_types = array_diff( $all_types, $priority_types_list );
if ( ! empty( $remaining_types ) ) {
$types[ $all_types_cat ] = array();
foreach ( $remaining_types as $type ) {
$types[ $all_types_cat ][ $type ] = $type;
}
}
/**
* Filter the available Schema.org types
*
* Allows developers to add custom Schema.org types or modify existing ones.
*
* @param array $types The Schema.org type mappings grouped by category.
*/
return apply_filters( 'acf/schema/schema_types', $types );
}
/**
* Process ACF fields and map them to Schema.org structure
*
* Takes an array of field objects and processes them based on their schema_property setting.
* Fields with a schema_property are mapped to core Schema.org properties. Properties that
* expect objects (like 'author' or 'publisher') automatically get proper "@type" added.
* Fields without a schema_property are skipped.
*
* @since 6.8.0
*
* @param array $field_objects Array of ACF field objects with values.
* @return array Processed data with core properties, with 'field_types' key containing types from qualified properties.
*/
public static function process_fields( $field_objects ) {
$data = array();
$field_types = array();
foreach ( $field_objects as $field_name => $field_object ) {
// Skip empty values.
if ( null === $field_object['value'] || '' === $field_object['value'] ) {
continue;
}
// Check if this field has a schema property mapping.
$schema_property = $field_object['schema_property'] ?? '';
if ( ! empty( $schema_property ) ) {
// Parse qualified property (e.g., "Offer.price" -> type: "Offer", property: "price").
$parsed = Schema::parse_qualified_property( $schema_property );
$property_name = $parsed['property'];
// Collect field types from qualified properties.
if ( $parsed['type'] ) {
$field_types[] = $parsed['type'];
}
$formatted_value = self::format_field_value_for_jsonld( $field_object['value'], $field_object );
// Field has a schema property - map to core property using just the property name.
$data[ $property_name ] = $formatted_value;
}
}
// Add @type to nested objects based on schema.org ranges.
$data = self::add_types_to_nested_objects( $data );
// Include field types from qualified properties.
if ( ! empty( $field_types ) ) {
$data['field_types'] = array_values( array_unique( $field_types ) );
}
return $data;
}
/**
* Determine the final "@type" value for JSON-LD output
*
* Merges provided types (from post type/block settings) with field types
* (from qualified properties like "Recipe.prepTime"). Falls back to the
* default type if neither source provides any types.
*
* @since 6.8.0
*
* @param string|array|null $provided_types Types explicitly set in settings (can be string, array, or null).
* @param array $field_types Types extracted from qualified properties.
* @param string $default_type Fallback type if no types provided.
* @return string|array Final @type value (string for single type, array for multiple).
*/
public static function determine_schema_type( $provided_types, $field_types, $default_type = 'Thing' ) {
$types = array();
// Add provided types from post type/block settings.
if ( ! empty( $provided_types ) ) {
$types = is_array( $provided_types ) ? $provided_types : array( $provided_types );
}
// Merge in field types from qualified properties.
if ( ! empty( $field_types ) && is_array( $field_types ) ) {
$types = array_merge( $types, $field_types );
}
$types = array_values( array_unique( $types ) );
if ( empty( $types ) ) {
return $default_type;
}
return count( $types ) === 1 ? $types[0] : $types;
}
/**
* Add "@type" to nested objects based on schema.org property ranges
*
* Examines each property in the data and if it expects an object type
* (like Person, Organization, etc.), automatically adds the appropriate @type.
*
* For example, if 'author' contains { 'name': 'John' }, it becomes:
* { '@type': 'Person', 'name': 'John' }
*
* @since 6.8.0
*
* @param array $data The data array to process.
* @return array The data with @type added to nested objects.
*/
private static function add_types_to_nested_objects( $data ) {
foreach ( $data as $property => $value ) {
// Skip if value is not an array (can't be a nested object).
if ( ! is_array( $value ) ) {
continue;
}
// Skip if already has @type.
if ( isset( $value['@type'] ) ) {
continue;
}
// Check if this is a sequential array (list) vs associative array (object).
// Sequential arrays are for properties that accept multiple values.
// We only add @type to associative arrays (objects).
$is_list = array_keys( $value ) === range( 0, count( $value ) - 1 );
if ( $is_list ) {
// This is a list/array, not a single object. Skip adding @type.
continue;
}
// Check if this property expects an object type.
if ( Schema::property_expects_object( $property ) ) {
// Get the preferred object type for this property.
$object_type = Schema::get_preferred_object_type( $property );
if ( $object_type ) {
// Add @type at the beginning of the array.
$data[ $property ] = array_merge(
array( '@type' => $object_type ),
$value
);
}
}
}
return $data;
}
/**
* Render a JSON-LD script tag with the provided data
*
* Shared helper method for outputting JSON-LD structured data.
*
* @since 6.8.0
*
* @param array $jsonld_data The JSON-LD data array to output.
*/
public static function render_jsonld_script( $jsonld_data ) {
if ( empty( $jsonld_data ) ) {
return;
}
/**
* Action fired before rendering JSON-LD script tag
*
* Allows developers to output custom schemas or capture the data.
*
* @param array $jsonld_data The JSON-LD data array.
*/
do_action( 'acf/schema/render_script', $jsonld_data );
/**
* Filter to disable ACF's default JSON-LD output
*
* Return true to prevent ACF from outputting the JSON-LD script tag.
* Useful if you want to handle the output yourself via the action above.
*
* @param bool $disable Whether to disable default output. Default false.
* @param array $jsonld_data The JSON-LD data that would be output.
*/
$disable_output = apply_filters( 'acf/schema/disable_output', false, $jsonld_data );
if ( $disable_output ) {
return;
}
// Output the JSON-LD script tag.
echo "<script type=\"application/ld+json\">\n";
echo wp_json_encode( $jsonld_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_UNESCAPED_UNICODE );
echo "\n</script>\n";
}
/**
* Format ACF field value for JSON-LD output
*
* Shared helper method for formatting field values consistently.
* Checks for field-type-specific formatting methods in this order:
* 1. Pre-filter to allow complete bypass of formatting logic
* 2. format_value_for_jsonld() - custom method for JSON-LD formatting (if field type implements it)
* 3. Field-type-specific formatting, defaulting to format_value_for_rest() for most types
* 4. Post-filter on the final formatted value
*
* @since 6.8.0
*
* @param mixed $value The field value.
* @param array $field_object The ACF field object.
* @return mixed Formatted value.
*/
public static function format_field_value_for_jsonld( $value, $field_object ) {
$field_type_name = $field_object['type'] ?? '';
$field_name = $field_object['name'] ?? '';
/**
* Filter to bypass the default formatting logic entirely
*
* Return a non-null value to bypass all default formatting.
* This runs before any other formatting logic.
*
* @param mixed|null $pre_value Return non-null to bypass default formatting.
* @param mixed $value The raw field value.
* @param array $field_object The ACF field object.
* @param string $field_type_name The field type name.
*/
$pre_value = apply_filters( 'acf/schema/format_value/pre', null, $value, $field_object, $field_type_name );
$pre_value = apply_filters( "acf/schema/format_value/pre/type={$field_type_name}", $pre_value, $value, $field_object );
$pre_value = apply_filters( "acf/schema/format_value/pre/name={$field_name}", $pre_value, $value, $field_object );
if ( null !== $pre_value ) {
return $pre_value;
}
// Get the field type class instance.
$field_type = acf_get_field_type( $field_type_name );
// First priority: Check if field type has a custom format_value_for_jsonld method.
if ( $field_type && method_exists( $field_type, 'format_value_for_jsonld' ) ) {
$formatted_value = $field_type->format_value_for_jsonld( $value, null, $field_object );
} else {
// Second priority: Use format_value_for_rest or return as-is.
if ( $field_type && method_exists( $field_type, 'format_value_for_rest' ) ) {
$formatted_value = $field_type->format_value_for_rest( $value, null, $field_object );
} else {
// Final fallback: return value as-is.
// Arrays are valid JSON-LD (e.g., multi-select values).
$formatted_value = $value;
}
}
/**
* Filter the formatted value before returning
*
* Allows modification of the value after all default formatting has been applied.
*
* @param mixed $formatted_value The formatted value.
* @param mixed $value The raw field value.
* @param array $field_object The ACF field object.
* @param string $field_type_name The field type name.
*/
$formatted_value = apply_filters( 'acf/schema/format_value', $formatted_value, $value, $field_object, $field_type_name );
$formatted_value = apply_filters( "acf/schema/format_value/type={$field_type_name}", $formatted_value, $value, $field_object );
$formatted_value = apply_filters( "acf/schema/format_value/name={$field_name}", $formatted_value, $value, $field_object );
return $formatted_value;
}
}
Home - Capital GMC Buick Regina
Skip to content
{{ $t(category) }}
Error
{{vehicle.modelData.year}} {{vehicle.modelData.make}} {{vehicle.modelData.model}}
Starting from {{vehicle.modelData.startingPrice | moneyFormat(lang)}}
Welcome to Capital GMC BUICK – REGINA
Thank you for choosing Capital GMC Buick | Regina, your premier certified Buick and GMC dealership proudly serving drivers in Regina and the surrounding communities. Whether you’re searching for a brand-new Buick or GMC vehicle or a meticulously inspected pre-owned model, we have a diverse selection to match your needs and lifestyle.
Beyond our impressive inventory, we offer a seamless and stress-free financing experience through our well-connected finance centre, where our team of experts is dedicated to securing the best loan or lease options for you, quickly, transparently, and hassle-free.
But our commitment to you doesn’t stop at the sale. Our state-of-the-art service centre is staffed with skilled Buick and GMC technicians who use the latest equipment and genuine OEM parts to keep your vehicle running at its best. From routine maintenance to complex repairs, we’ve got you covered.
Experience top-tier customer service, quality vehicles, and expert care, all in one place. Visit Capital GMC Buick | Regina today or call us at 306-205-8072 with any questions. We’re here to help!
Ask a Question
Capital GMC Buick – Regina
Contact Us
Have a question or need assistance? Fill out the form and we will reach out to you as soon as possible.
Notice: JavaScript is required for this content.
CLOSE
Schedule a Visit
Let us know when you are coming and how we can assist you. We can ensure someone will be on hand to help you out at the desired date and time.
Notice: JavaScript is required for this content.
CLOSE
Find a Career
Have a look at our list of available positions and apply online today to join our team!
×
Opportunities to Grow
The auto industry is constantly changing and we want to continue to grow. We offer growth, leadership & mentorship programs to allow our staff to grow with us.
×
Competitive Salary
We have a significant earning potential with incentive-based pay in most roles. We also offer an employee referral bonus with paid bonuses.
×
Health & Dental
We offer a comprehensive benefits package including extended health, dental, and vision care. We also include paramedical, life insurance, paid sick leave, short & long-term disability coverages.
×
Vacation
We value our employees and want everyone to take their vacation time. We offer a minimum of 2 weeks vacation each year.
×
Training & Development
We have many opportunities for paid education and training in-house as well as training from the Manufacturer.
×
$10,000 Cash Giveaway – Terms & Conditions
All October long, stop by Capital GMC Buick Cadillac, to enter for your chance to win $10,000 cash. No purchase is required, but entries must be made in-store.
The contest is open to residents of Saskatchewan who are 18+. Dealership employees and their households are not eligible. Entries will be accepted from October 1 to October 31, 2025. A random draw will take place on November 1, 2025.
The prize is one $10,000 award, paid by cheque, and must be accepted as awarded. Winner will be contacted by phone or email and must respond within 7 days or another entry may be drawn. Odds of winning depend on the number of entries received.By entering, you agree that Capital Automotive Group may use your name and photo for winner announcements. The contest is governed by the laws of Saskatchewan.
Notice: JavaScript is required for this content.
CLOSE