This documentation is intended for WordPress developers who are comfortable with PHP. The examples provided here are intended to demonstrate features of the Property Plugin, and we hope they are useful to you. However, they are not packaged blocks of code that can simply be added to your theme or site. Please be warned that using example code without modification is likely to cause problems.

We also offer customization services that encompass everything in this document and more. Please contact us at support@victheme.com for a quotation if you are interested.

Entity System - Property Factory

What is the Property Entity Factory?

The Property Entity Factory is a wrapper for the VTCore_Property_Entity_Property PHP class that uses data from a property post to create a property entity object. The class will retrieve all relevant type entity, field entities, and attribute entities related to a property.

We recommend using the property factory object whenever you want to edit, delete, save, or display a single property post.

The factory object also provides a method to create a display object that outputs markup for the front end, metabox field, and search field displays. Use the VTCore_Property_Entity_Property::BuildFieldDisplayObject method to build a display object.

Why use the property factory?

All of the various classes and methods needed to work with property posts are grouped together within the factory class. Without it, you’ll have to access and invoke these classes and methods separately, adding significant complexity to your code.

Here’s an example of how to use the factory to render markup from inside the WordPress Loop:


            // Assuming that we are in the property post type loop
            global $post;

            $property = new VTCore_Property_Entity_Property($post->ID);

            $property
                ->loadMetaData()
                ->initializeType()
                ->initializeFields()
                ->initializeAttributes();

            if (isset($property) && is_a($property, 'VTCore_Property_Entity_Property')) {

                // Try to render all available fields, display mode
                $property->render('fields');

                // Try to render all available attributes, display mode
                $property->render('attributes');

                // Grab property_location field search object
                $object = $property->buildFieldDisplayObject('property_location', array(), 'search');
            }

        

And here’s an example of using the factory to change and save data for an arbitrary property:


            // Try to manually initiate the factory for post id 1
            $factory = new VTCore_Property_Entity_Property(array('id' => 1));

            // Initialize Fields, attributes and types
            $factory
                ->initializeType()
                ->initializeAttributes()
                ->initializeFields();

            // Load the stored _property_metadata for the current post
            $factory
                ->loadMetaData();

            // Alter the metadata value, 2 is a dummy tax term
            $factory
                ->mutate('meta.fields.property_status.status', 2);

            // Save the fields, attributes, type back to database
            $factory
                ->saveMetaFields()
                ->saveMetaAttributes()
                ->saveMetaType();

            // Save the post _property_metadata back to database
            $factory
                ->saveMetaData();

        

Entity System - Property Types

What are Property Type Entities?

VTCore_Property_Entity_Type is a PHP class for creating, updating, revising, and deleting property types. The purpose of this class is to act as the general gateway object for others to use.

What are Property Types?

Property Types are actually Taxonomies that are stored in a single wp_options table entry in an array. This array is keyed by property type taxonomy slugs. Each value is a taxonomy that stores the fields, attributes, and options related to that type.

Type Entity Hooks

The following hooks are available for the type entity system:

  • vtcore_property_type_init

    This hook is invoked as the last step when the type entity is constructed.

  • vtcore_property_type_after_entity_load

    This action is invoked after the type entity object finishes loading type entity data from the database into the object.

  • vtcore_property_type_before_entity_save

    This action is triggered before the type entity object attempts to update the stored entity entry in the database.

  • vtcore_property_type_after_entity_save

    This action is triggered after the type entity object attempts to save the type array into the database, regardless of whether the saving process is succeeds or fails.

  • vtcore_property_type_before_entity_delete

    This action is triggered before the entity data is removed from the database.

  • vtcore_property_type_after_entity_delete

    This action is triggered after the data is removed from the database.

Hook Example

Here’s an example of how to use these hooks:


            /**
             * Hooking into type entity init hook
             */
            add_action('vtcore_property_type_init', 'alter_my_type');

            function alter_my_type($object) {

                /**
                 * Use dotted notation and object getter
                 * Just a simple demonstration to change all the
                 * type form label
                 */
                $object->mutate('label', 'Newly altered label');

            }

        

Entity System - Property Fields

What are Field Entities?

VTCore_Property_Entity_Field is a PHP class that wraps all operations for creating, updating, and disabling property fields. We recommend using the field entity object whenever making changes to fields.

What are Property Fields?

Property Fields are custom data linked to a given property type. Fields are mapped by the property field system array which is alterable via hooks. If you are considering using a field, please check first if a Property Attribute will work for you–they are much simpler to use. Pricing data is an example where a field is appropriate, because of the need to handle different currencies and searching with minimum and maximum values.

Where does a property field stores its data?

Property field system data entry can be stored in taxonomy as taxonomy terms either hierarchical or not, custom post meta, or a serialized _property_data post meta. It all depends on how you register the field and what is defined in the field configuration array.

Field Entity Hooks

Field Entities provide the following hooks:

  • vtcore_property_field_init

    This hook is invoked as the last action when the field entity object constructed.

  • vtcore_property_field_after_entity_load

    This action is invoked after the field entity object loads the field system configuration array from field system configuration objects (VTCore_Property_Fields()).

  • vtcore_property_field_after_entity_save

    This action is triggered after the field entity object saves the field system configuration array to the WordPress options vtcore_property_fields database table.

  • vtcore_property_field_after_entity_delete

    This action is triggered after the field entity object removes the current field custom configuration from the database. Note that the only way to truly remove one of the fields that ships with the plugin completely from the field system is using hook action vtcore_property_field_register.

Hook Example

Here’s an example of using field entity hooks:


            /**
             * Hooking into type entity init hook
             */
            add_action('vtcore_property_field_init', 'alter_my_field');

            function alter_my_field($object) {

                /**
                 * Use dotted notation and object getter
                 * Just a simple demonstration to change all the
                 * type form label
                 */
                $object->mutate('label', 'Newly altered label');


                /**
                 * Changing visibility globally
                 * Turn off the icon visibility
                 */
                $object->mutate('visibility.icon', false);
            }

        

Entity System - Property Attributes

What are Attributes Entities?

VTCore_Property_Entity_Attribute is a PHP class for managing the Property Attributes linked to a property type. We recommend using this class only when you need to alter the attributes of a property programatically.

What are Property Attributes?

Property Attributes are a simpler form of Property Fields. They allow users to add custom data to a property type via the front end editor without the need to know PHP. Since they are designed to be easy to use, attributes have fewer features than fields.

Where is attribute data stored?

Attributes are stored in a taxonomy using terms, either by category or tags, depending on how the the attribute metabox form is set up.

Attribute Entity Hooks

Attribute Entities provide the following hooks:

  • vtcore_property_attribute_init

    This hook is invoked as the last action when the attribute entity is constructed.

  • vtcore_property_attribute_after_entity_load

    This action is invoked after the type entity object finishes loading attribute entity data into the object from the WordPress options table with row key vtcore_property_attributes.

  • vtcore_property_type_before_entity_save

    This action is triggered after the attribute entity object attempts to save to the database, regardless of whether the saving process succeeded or failed.

  • vtcore_property_attribute_after_entity_delete

    This action is triggered after the attribute’s data is removed from the database and also after the deleted attribute is removed from all property types and all WordPress posts.

Hook Example

Here’s an example of using attribute entity hooks:


            /**
             * Hooking into type entity init hook
             */
            add_action('vtcore_property_attribute_init', 'alter_my_attribute');

            function alter_my_type($object) {

                /**
                 * Use dotted notation and object getter
                 * Just a simple demonstration to change all the
                 * type form label
                 */
                $object->mutate('label', 'Newly altered label');

                /**
                 * Don't allow all attributes to be searched
                 */
                $object->mutate('search', false);

            }

        

Field System - Field Hooks

The Field System provides the following hooks :

  • vtcore_property_alter_fields

    This filter allows you to modify, remove, or add fields. It is fired when a VTCore_Property_Fields object is created.

  • vtcore_property_field_registered

    This action is triggered after a field object is created, and it is the last step in the class’s register method. A reference to the field object is passed into the function call.

  • vtcore_property_field_load

    This action is triggered after a field array is loaded from the database. A reference to the field object is passed into the function call.

  • vtcore_property_field_save

    This action is triggered after a field array is saved to the database. A reference to the field object is passed into the function call.

  • vtcore_property_field_delete

    This action is triggered after a field array is deleted from the database. A reference to the field object is passed into the function call.

Hook Example

Here’s an example of using the field system hooks:


            /**
             * Adding the new Field to Property Field system
             */
            add_filter('vtcore_property_alter_fields', 'register_my_field');

            function register_my_field($registry) {

                /**
                 * Modify the field registry via $registry
                 * This will disable the property status
                 */
                $registry['property_status']['enabled'] = false;

                return $registry;
            }


            /**
             * We use object instead of direct array via _register action
             * Remember that this action is called after everything else (eg. WPML integration)
             */
            add_action('vtcore_property_field_register', 'modify_field_object');

            function modify_field_object($fieldObject) {

                /**
                 * $fieldObject is the field object and it inherits the VTCore_Wordpress_Models_Config
                 * Thus it can use dotted notation for the array key drilling and has the getter and setter
                 * Method inherited as well.
                 */

                /**
                 * This will disable the property status
                 */
                $fieldObject->mutate('property_status.enabled', false);
            }

        

Field System - Configuration Array

The Field System Array is designed to store field related information to be used in various objects. For example, the translation key will be used when integrating field dynamic strings with The WordPress Multilingual Plugin for translation.

Here’s an example:


            /**
             * Example of valid property fields registration
             * array, you can inject this array via field related hooks
             */
            $registry['property_duration'] = array(
                    'field' => 'property_duration',
                    'name' => __('Duration', 'victheme_property'),
                    'label' => __('Availability', 'victheme_property'),
                    'enabled' => true,
                    'icons' => array(
                    'icon' => 'real8',
                    'family' => 'proicon',
                ),
                'settings' => array(
                    'separator' => array(
                        'mode' => 'data',
                        'type' => 'VTCore_Bootstrap_Form_BsText',
                        'context' => array(
                        'text' => __('Separator', 'victheme_property'),
                        'description' => __('Configure the text for the separator element', 'victheme_property'),
                        'value' => __('To', 'victheme_property'),
                    ),
                ),
                'format' => array(
                    'mode' => 'data',
                    'type' => 'VTCore_Bootstrap_Form_BsText',
                    'context' => array(
                            'text' => __('Date Format', 'victheme_property'),
                            'description' => __('Configure the text for the separator element', 'victheme_property'),
                            'value' => 'd/m/Y',
                        ),
                    ),
                ),
                'storage' => array(
                    'from' => array(
                        'type' => 'meta',
                        'mode' => 'timestamp',
                        'target' => '_property_duration_from',
                    ),
                    'end' => array(
                        'type' => 'meta',
                        'mode' => 'timestamp',
                        'target' => '_property_duration_end',
                    ),
                ),
                'translation' => array(
                    'search.label',
                    'search.settings.from.context.value',
                    'search.settings.separator.context.value',
                    'search.settings.end.context.value',
                    'settings.separator.context.value',
                    'metabox.settings.from.context.value',
                    'metabox.settings.end.context.value',
                ),
                'search' => array(
                    'label' => __('Availability', 'victheme_property'),
                    'settings' => array(
                        'from' => array(
                        'type' => 'VTCore_Bootstrap_Form_BsText',
                    'context' => array(
                        'text' => __('From Date Form Label', 'victheme_property'),
                        'description' => __('Configure the text for the from date search form label text', 'victheme_property'),
                        'value' => __('Availability Start Date', 'victheme_property'),
                    ),
                ),
                'separator' => array(
                    'type' => 'VTCore_Bootstrap_Form_BsText',
                    'context' => array(
                        'text' => __('Separator Date Form Label', 'victheme_property'),
                        'description' => __('Configure the text for the separator search form label text', 'victheme_property'),
                        'value' => __('to', 'victheme_property'),
                    ),
                ),
                'end' => array(
                    'type' => 'VTCore_Bootstrap_Form_BsText',
                        'context' => array(
                            'text' => __('End Date Form Label', 'victheme_property'),
                            'description' => __('Configure the text for the end date search form label text', 'victheme_property'),
                            'value' => __('Availability End Date', 'victheme_property'),
                            ),
                        ),
                    ),
                ),
                'metabox' => array(
                    'label' => __('Duration', 'victheme_property'),
                    'description' => __('Set the availability duration for this property.', 'victheme_property'),
                    'settings' => array(
                        'from' => array(
                            'type' => 'VTCore_Bootstrap_Form_BsText',
                            'context' => array(
                                'text' => __('From Form Label', 'victheme_property'),
                                'description' => __('Configure the text for the from form label text', 'victheme_property'),
                                'value' => __('From Date', 'victheme_property'),
                            ),
                        ),
                        'end' => array(
                            'type' => 'VTCore_Bootstrap_Form_BsText',
                            'context' => array(
                                'text' => __('End Form Label', 'victheme_property'),
                                'description' => __('Configure the text for the end form label text', 'victheme_property'),
                                'value' => __('End Date', 'victheme_property'),
                            ),
                        ),
                    ),
                ),
                'objects' => array(
                    'metabox' => 'VTCore_Property_Form_Metabox_Duration',
                    'search' => 'VTCore_Property_Form_Search_Duration',
                    'display'=> 'VTCore_Property_Element_Duration',
                ),
                'visibility' => array(
                    'from' => true,
                    'separator' => true,
                    'end' => true,
                    'label' => true,
                    'icon' => true,
                    'search' => true,
                ),
                'group' => 'property_info',
                'weight' => 1,
            );
        

Keys

A field array has the following keys for accessing or modifying data about the field:

  • field

    The unique, machine readable name of the field.

  • name

    The human readable name of the field. Is used as the search, metabox, and, front end field labels, if the other label keys haven’t been set.

  • enabled

    Set whether a field is currently active.

  • label

    The text for the front end field form label element. Also the default fallback value if a label for the metabox or search form hasn’t been defined.

  • icons

    The icon array context for VTCore_Wordpress_Element_WpIcon objects. By using the VTCore icon objects you can access all the icons defined via the VTCore Icon Factory and if any theme or plugin registers additional icon sets to the library, they will also available for the field to use.

  • settings

    A custom settings context that will be used when creating the field management form. This allows you to create a field that can be customized easily via the WordPress front end. Here’s an example from the Location field that comes bundled with the plugin:

    
    
                'settings' => array(
                    'property_country' => array(
                        'mode' => 'taxonomy',
                        'type' => 'property_country',
                        'label' => __('Country', 'victheme_property'),
                    ),
                )
    
            
  • storage

    Define the field data storage behavior. You can have multiple storage points in a single field. Valid storage types are taxonomy terms, metadata, and data (serialized data in a single _property_data post meta. For example:

    
    
                'storage' => array(
                    'country' => array(
                        'type' => 'taxonomy',
                        'target' => 'property_country',
                        'mode' => 'taxonomy_id',
                        'args' => array(
                            'name' => __('Country', 'victheme_property'),
                            'taxonomy' => 'property_country',
                            'hierarchical' => TRUE,
                            'show_in_nav_menus' => TRUE,
                            'slug' => 'property-country',
                            'labels' => array(
                                'name' => __('Property Location', 'victheme_property'),
                            ),
                        ),
                    ),
                    'address' => array(
                        'type' => 'meta',
                        'target' => '_property_address',
                    ),
                    'postalcode' => array(
                        'type' => 'meta',
                        'target' => '_property_postalcode',
                    ),
                )
    
            
  • translation

    An array of strings that specify which pieces of text relating to a field should be registered by translation by WPML. Use the dotted notation as shown in the example below:

    
    
                'translation' => array(
                    'search.label',
                    'search.settings.address.context.value',
                    'search.settings.postalcode.context.value',
                    'search.settings.country.context.value',
                    'search.settings.address_placeholder.context.value',
                    'search.settings.postalcode_placeholder.context.value',
                    'search.settings.country_placeholder.context.value',
                    'metabox.settings.address.context.value',
                    'metabox.settings.postal.context.value',
                    'metabox.settings.country.context.value',
                )
    
            
  • search

    The search branch in the array context is a mapping that will be passed to the field configuration GUI and the field form when in search mode. Here’s a truncated example:

    
    
                'search' => array(
                    'label' => __('Location', 'victheme_property'),
                    'settings' => array(
                        'address' => array(
                            'type' => 'VTCore_Bootstrap_Form_BsText',
                            'context' => array(
                                'text' => __('Address Form Label', 'victheme_property'),
                                'description' => __('Configure the text for the address search form label text', 'victheme_property'),
                                'value' => __('Address', 'victheme_property'),
                            ),
                        ),
                        'address_placeholder' => array(
                            'type' => 'VTCore_Bootstrap_Form_BsText',
                            'context' => array(
                                'text' => __('Address Placeholder', 'victheme_property'),
                                'description' => __('Configure the text for the address field placeholder', 'victheme_property'),
                                'value' => __('Any Address', 'victheme_property'),
                            ),
                        ),
                    ),
                )
    
            
  • visibility

    Define what should be displayed globally. This will be used when building the field front end display, the search form, and the metabox form. For example:

    
    
                'visibility' => array(
                    'address' => TRUE,
                    'postalcode' => TRUE,
                    'country' => TRUE,
                    'label' => TRUE,
                    'mainlabel' => TRUE,
                    'icon' => TRUE,
                    'search' => TRUE,
                    'toggle' => FALSE,
                    'selectpicker' => FALSE,
                )
    
            
  • objects

    Set the PHP class name that will be used when building the front end display, the search form field, and the metabox form field. The property entity responsible for building the object will assume that the class name is either already loaded or eligible for auto loading. If it isn’t available for any reason, the field will not produce the output. For example:

    
    
                'objects' => array(
                    'text' => 'VTCore_Property_Element_AddressText',
                    'metabox' => 'VTCore_Property_Form_Metabox_Location',
                    'search' => 'VTCore_Property_Form_Search_Location',
                    'display' => 'VTCore_Property_Element_Location',
                )
    
            
  • group

    A string that defines which group the field belongs to. This is primarily used to determine which accordion group the field’s metabox will be displayed under. Most commonly, this will be set to 'property_information'.

  • weight

    The weight for ordering the field when rendered. Smaller numbers will appear at the top of the list.

Field System - Display Object

When a registered field is called via the Property Factory to build its markup for front end display purposes, the field system will search for the value of objects.display in the field configuration array and the value will be treated as the class name when building the display object.

The display object should extend VTCore_Property_Models_Element and follow the rules of VTCore_Html_Base and VTCore_Bootstrap_Element_Base when building the markup.

Here’s an example of a simple display object:


            /**
             * Class for building the field status
             *
             * @author jason.xie@victheme.com
             *
             */
            class VTCore_Property_Element_Status
            extends VTCore_Property_Models_Element {

                /**
                * Define the default context array
                * The context will be merged with user supplied context
                */
                protected $context = array(

                    // Wrapper element markup Context
                    'type' => 'div',
                    'attributes' => array(
                        'class' => array(
                            'property-element-status',
                        ),
                    ),

                    // The field values
                    'status' => false,

                    // Icons
                    'icon' => false,
                    'icon_type' => false,
                    'label' => false,

                    // Status element markup context
                    'value_attributes' => array(
                        'type' => 'div',
                        'search' => 'value',
                        'attributes' => array(
                            'class' => array(
                                'property-value',
                            ),
                        ),
                    ),

                    // Label element markup context
                    'label_attributes' => array(
                        'type' => 'div',
                        'attributes' => array(
                            'class' => array(
                                'property-label',
                            ),
                        ),
                    ),
                );


                /**
                 * Overriding parent method
                 * @see VTCore_Html_Base::buildElement()
                 *
                 * Defining the method to build this object markups.
                 */
                public function buildElement() {

                    // Removing context with empty value, including '', false, 0
                    $this->cleanEmptyContext();

                    // Build size
                    if ($this->getContext('status')) {

                        // Call the original method, this is invoked to ensure
                        // if in the future parent class has implemented new
                        // logic it will get called.
                        parent::buildElement();

                        // Let the property element models handle the icon and label
                        $this->buildLabel();

                        // Grab status terms
                        $term_ids = $this->getContext('status');
                        if (is_array($term_ids)) {
                            $term_ids = array_shift($term_ids);
                        }

                        // Build status
                        $term = get_term($term_ids, 'property_status');

                        if (!empty($term) && !is_wp_error($term)) {
                            $this
                                ->addChildren(new VTCore_Html_Element($this->getContext('value_attributes')))
                                ->lastChild()
                                ->setText($term->name);
                        }
                    }

                    // Seems that the field is trully empty, dont build any markup!
                    else {
                        $this->setType(false);
                    }
                }


                /**
                * Extending base method for checking if element is truly empty
                */
                public function checkVisibility() {
                    return (bool) $this->getContext('status');
                }
            }

        

Field System - Search Object

When a registered field is called via the Property Factory to build its markup for search purposes, the field system will lookup the value of objects.search in the field configuration array. The value will be treated as the class name when building the search field object.

The search object can utilize
VTCore_Property_Models_Search if the search field is a simple text field ($context.element.bstext) or taxonomy terms selection box ($context.element.wpterms).

For a more customized and complex search form field, we suggest extending VTCore_Bootstrap_Form_Base directly.
The search element should follow the rules of VTCore_Html_Form and VTCore_Bootstrap_Form_Base when building the markup.

Here’s an example of a simple search object using taxonomy select field:


            /**
             * Class for building the property status
             * search field
             *
             * @author jason.xie@victheme.com
             *
             */
            class VTCore_Property_Form_Search_Status
            extends VTCore_Property_Models_Search {

                protected $context = array(

                    // Wrapper element markup context
                    'type' => 'div',
                    'attributes' => array(
                        'class' => array(
                            'property-search-group',
                            'property-search-status',
                        ),
                    ),
                    'queryid' => '',

                    // This is related to pre_get_posts and serve as the query key.
                    'searchkey' => '_property_status',

                    // Inform the parent class that we are building
                    // A taxonomy select form, use bstext if you want
                    // a text field instead.
                    'element' => 'wpterms',

                    // Inform the parent class that the select field
                    // need terms from taxonomy property_status
                    'taxonomies' => array('property_status'),
                );
            }
        

And here’s an example of building a complex search form field:


            /**
             * Class for building the property landsize
             * search field
             *
             * @author jason.xie@victheme.com
             *
             */
            class VTCore_Property_Form_Search_LandSize
            extends VTCore_Bootstrap_Form_Base {

                protected $context = array(

                    // Element wrapper markup context
                    'type' => 'div',
                    'attributes' => array(
                        'class' => array(
                            'property-search-group',
                            'property-search-landsize',
                        ),
                    ),
                    'queryid' => '',
                );


                /**
                * Overriding Parent Method
                * @see VTCore_Bootstrap_Form_Base::assignContext()
                */
                protected function assignContext() {

                    // We need larger column for this kind of search form
                    // This is configured via backend
                    if ($this->getContext('alignment') == 'horizontal') {
                        $this->addContext('grids', array(
                            'columns' => array(
                                'mobile' => 12,
                                'tablet' => 8,
                                'small' => 8,
                                'large' => 8,
                            )
                        ));
                    }

                    parent::assignContext();
                }

                /**
                * Overriding Parent Method
                * @see VTCore_Html_Base::buildElement()
                */
                public function buildElement() {

                    // Call parent method
                    parent::buildElement();

                    // the dimension field default grid size
                    $dimensionGrids = array(
                        'columns' => array(
                            'mobile' => 12,
                            'tablet' => 4,
                            'small' => 4,
                            'large' => 4,
                        ),
                    );

                    // The default grid size
                    $grids = array(
                        'columns' => array(
                            'mobile' => 12,
                            'tablet' => 6,
                            'small' => 6,
                            'large' => 6,
                        ),
                    );

                    // Mutate the field element grid size when 2 field is visible
                    if ($this->getContext('visibility.dimension')) {
                        $grids = array(
                            'columns' => array(
                                'mobile' => 12,
                                'tablet' => 4,
                                'small' => 4,
                                'large' => 4,
                            ),
                        );
                    }

                    // Build a grid wrapper if both landsize and dimension
                    // is visible, this is for inline form markup
                    if ($this->getContext('visibility.landsize') || $this->getContext('visibility.dimension')) {

                        $this->addChildren(new VTCore_Bootstrap_Grid_BsRow());

                        if ($this->getContext('visibility.label')) {
                            $this
                                ->lastChild()
                                ->addChildren(new VTCore_Bootstrap_Grid_BsColumn(array(
                                    'type' => 'div',
                                    'grids' => array(
                                        'columns' => array(
                                            'mobile' => 12,
                                            'tablet' => 12,
                                            'small' => 12,
                                            'large' => 12,
                                        ),
                                    ),
                                )))
                                ->lastChild()
                                ->addChildren(new VTCore_Form_Label(array(
                                    'text' => $this->getContext('search.label'),
                                    'attributes' => array(
                                        'class' => array('form-group-label'),
                                    ),
                                )));
                        }
                    }

                    // User configure to display the landsize text field
                    if ($this->getContext('visibility.landsize')) {
                        $this
                            ->lastChild()
                            ->addChildren(new VTCore_Bootstrap_Form_BsText(array(
                                'text' => $this->getContext('search.settings.minsize.context.value'),
                                'name' => $this->getContext('queryid') . '_property_landsize_minimum',
                                'grids' => $grids
                            )))
                            ->addChildren(new VTCore_Bootstrap_Form_BsText(array(
                                'text' => $this->getContext('search.settings.maxsize.context.value'),
                                'name' => $this->getContext('queryid') . '_property_landsize_maximum',
                                'grids' => $grids
                            )));
                    }

                    // User configured to build the dimension settings
                    if ($this->getContext('visibility.dimension')) {
                        $this
                            ->lastChild()
                            ->addChildren(new VTCore_Wordpress_Form_WpTerms(array(
                                'text' => $this->getContext('search.settings.dimension.context.value'),
                                'name' => $this->getContext('queryid') . '_property_dimension[]',
                                'taxonomies' => array('property_dimension'),
                                'grids' => $dimensionGrids,
                            )));
                    }
                }

            }

        

Field System - Search Query Vars

When a custom property field is enabled for searching there are couple of extra steps needed to register the query variables so it will be found when WP_Query is processing the query.

Register the search variable key

When building the Property Field search object, you have to define the form field name attribute . That attribute will be passed as either POST or GET entry key when user is submitting the form back to the server.
WordPress will ignore this key if it hasn’t been registered yet. Invoke the hook filter query_vars to register the key with the WordPress back end.

Here’s an example of adding new query vars:



            /**
             * Invoking the query_vars filter hook
             */
            add_filter('query_vars', 'my_new_variables');

            function my_new_variables($variables) {
                $variables[] = 'property_awesome';
                return $variables;
            }

        

And here’s an example of adding new logic to pre_get_posts:


            /**
             * Invoking the query_vars filter hook
             */
            add_filter('pre_get_posts', 'alter_query');

            function alter_query($query) {

                // Only concern about main query and on front page
                if ($query->is_main_query() != false && !is_admin()) {

                    // add the logic here
                    if (isset($_REQUEST['mykey']) {
                        $query->set('tax_query', ....);
                    }

                }
            }

        

Finally, here’s an example of adding new logic to vtcore_wordpress_loop_process_query:


            /**
             * Invoking the vtcore_wordpress_loop_process_query action hook
             */
            add_filter('vtcore_wordpress_loop_process_query', 'alter_query');

            function alter_query($object) {

                // We are on ajax mode
                if (isset($object->request['data']) {
                    $request = VTCore_Wordpress_Utility::wpParseLargeArgs($object->request['data'];

                    // VTCore_Wordpress_Element_WpLoop object will always have custom loop id
                    // and need that custom unique loop id to differentiate one loop object to another
                    // The property search form will always append that unique id in front of every
                    // form field name attributes to determine the right target to search / filter.
                    $id = $object->getContext('id');

                    // Check if we got the right request for our custom field
                    if (isset($request[$id . '_my_custom_field'])) {

                        // Perform the custom logic
                        // @see wordpress taxQuery and metaQuery for valid array format
                        $object->taxQuery[] = ......
                        $object->metaQuery[] = .......
                    }
                }
            }
        

Wrapping Up

This has been an overview of all the major features of the VicTheme Property Plugin intended for PHP developers. Examining the plugin’s source code may also be helpful in understanding how to use these features.

If you still have questions, please contact us by submitting a ticket at our support page.