Plugin Directory

Changeset 3448071


Ignore:
Timestamp:
01/27/2026 05:03:15 PM (2 months ago)
Author:
PropertyHive
Message:

Update to version 2.5.40

Location:
houzez-property-feed/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • houzez-property-feed/trunk/README.txt

    r3442498 r3448071  
    44Requires at least: 3.8
    55Tested up to: 6.9
    6 Stable tag: 2.5.39
    7 Version: 2.5.39
     6Stable tag: 2.5.40
     7Version: 2.5.40
    88Homepage: https://houzezpropertyfeed.com
    99License: GPLv3
     
    147147== Changelog ==
    148148
     149= 2.5.40 - 2026-01-27 =
     150* Added 'Location' filter to Amplify Syndication import settings to specify only properties in a certain city/state are imported
     151* Added support for importing floorplans from Kyero XML feeds
     152* Added support for bathrooms, area, garages and more in PropCtrl imports
     153* Added support for images having no extension in Pixxi imports
     154* Updated Bridge settings so that datafeed ID is a text field instead of a fixed dropdown
     155
    149156= 2.5.39 - 2026-01-19 =
    150157* Added support for the Amplify Syndication RESO API
  • houzez-property-feed/trunk/houzez-property-feed.php

    r3442498 r3448071  
    44 * Plugin Uri: https://houzezpropertyfeed.com
    55 * Description: Automatically import properties to Houzez from estate agency CRMs and export to portals
    6  * Version: 2.5.39
     6 * Version: 2.5.40
    77 * Author: PropertyHive
    88 * Author URI: https://wp-property-hive.com
     
    2020     * @var string
    2121     */
    22     public $version = '2.5.39';
     22    public $version = '2.5.40';
    2323
    2424    /**
  • houzez-property-feed/trunk/includes/format-functions.php

    r3442498 r3448071  
    371371                    'label' => __( 'Office Name(s)', 'houzezpropertyfeed' ),
    372372                    'type' => 'text',
    373                     'tooltip' => 'Case-sensitive. Comma-delimited list of office names to import. Taken from the ListOfficeName field in the data. One or more must be entered',
     373                    'tooltip' => 'Case-sensitive. Comma-delimited list of office names to import. Taken from the ListOfficeName field in the data',
     374                ),
     375                array(
     376                    'id' => 'location',
     377                    'label' => __( 'Location(s)', 'houzezpropertyfeed' ),
     378                    'type' => 'text',
     379                    'tooltip' => 'Case-sensitive. Comma-delimited list of cities, states or provinces to import',
    374380                ),
    375381                /*array(
     
    863869                    'id' => 'dataset_id',
    864870                    'label' => __( 'Datafeed ID', 'houzezpropertyfeed' ),
    865                     'type' => 'select',
    866                     'options' => array(
    867                         'test' => 'Test Data',
    868                     )
     871                    'type' => 'text',
    869872                ),
    870873                array(
  • houzez-property-feed/trunk/includes/import-formats/class-houzez-property-feed-format-amplify-syndication.php

    r3442498 r3448071  
    5050        $office_names = array_filter($office_names);
    5151
    52         if ( empty($office_names) )
     52        $locations = isset($import_settings['location']) ? explode(",", $import_settings['location']) : array();
     53        $locations = array_map('trim', $locations);
     54        $locations = array_filter($locations);
     55
     56        if ( empty($office_names) && empty($locations) )
    5357        {
    54             $this->log("At least one office name must be entered into the import settings");
     58            $this->log("At least one office name or location must be entered into the import settings");
    5559            return false;
    5660        }
    5761
     62        if ( !empty($office_names) )
     63        {
     64            $office_additional_url = '';
     65            foreach ( $office_names as $i => $office_name )
     66            {
     67                if ( !empty($office_additional_url) ) { $office_additional_url .= ' or '; }
     68                $office_additional_url .= ' ListOfficeName eq %27' . $office_name . '%27 ';
     69            }
     70            $additional_url .= ' and (' . $office_additional_url . ')';
     71        }
    5872       
    59         $office_additional_url = '';
    60         foreach ( $office_names as $i => $office_name )
     73        if ( !empty($locations) )
    6174        {
    62             if ( !empty($office_additional_url) ) { $office_additional_url .= ' or '; }
    63             $office_additional_url .= ' ListOfficeName eq %27' . $office_name . '%27 ';
    64         }
    65         $additional_url .= ' and (' . $office_additional_url . ')';
    66 
     75            $location_additional_url = '';
     76            foreach ( $locations as $i => $location )
     77            {
     78                if ( !empty($location_additional_url) ) { $location_additional_url .= ' or '; }
     79                $location_additional_url .= ' City eq %27' . $location . '%27 or CityRegion eq %27' . $location . '%27 or StateOrProvince eq %27' . $location . '%27 ';
     80            }
     81            $additional_url .= ' and (' . $location_additional_url . ')';
     82        }
     83       
    6784        $limit = apply_filters( "houzez_property_feed_property_limit", 25 );
    6885        if ( $limit !== false )
     
    147164                                        return true;
    148165                                    }
     166                                }
     167
     168                                $media_url = 'https://query.ampre.ca/odata/Media?$top=1000&$filter=ResourceRecordKey eq %27' . $property['ListingKey'] . '%27 and ResourceName eq %27Property%27';
     169
     170                                $media_response = wp_remote_get(
     171                                    $media_url,
     172                                    array(
     173                                        'timeout' => 360,
     174                                        'headers' => array(
     175                                            'Content-Type' => 'application/json',
     176                                            'Authorization' => 'Bearer ' . $import_settings['access_token'],
     177                                        )
     178                                    )
     179                                );
     180
     181                                if ( is_wp_error( $media_response ) )
     182                                {
     183                                    $this->log_error( 'Response: ' . $media_response->get_error_message() );
     184
     185                                    return false;
     186                                }
     187
     188                                if ( wp_remote_retrieve_response_code($media_response) !== 200 )
     189                                {
     190                                    $this->log_error( wp_remote_retrieve_response_code($media_response) . ' response received when requesting properties. Error message: ' . wp_remote_retrieve_response_message($response) );
     191                                    return false;
     192                                }
     193
     194                                if ( is_array( $media_response ) )
     195                                {
     196                                    $media_contents = $media_response['body'];
     197
     198                                    $media_json = json_decode( $media_contents, TRUE );
     199
     200                                    if ( $media_json !== FALSE && is_array($media_json) )
     201                                    {
     202                                        if ( isset($media_json['error']) && !empty($media_json['error']) )
     203                                        {
     204                                            $this->log_error( 'Error received from Amplify API: ' . print_r($media_json['error'], true) );
     205                                            return false;
     206                                        }
     207
     208                                        $property['Media'] = isset($media_json['value']) && is_array($media_json['value']) ? $media_json['value'] : array();
     209                                    }
    149210                                }
    150211
     
    702763                                &&
    703764                                isset($image['MediaCategory']) && in_array(strtolower($image['MediaCategory']), array('photo', 'image'))
     765                                &&
     766                                isset($image['MediaStatus']) && strtolower($image['MediaStatus']) == 'active'
    704767                            )
    705768                            {
     
    772835                                &&
    773836                                isset($image['MediaCategory']) && in_array(strtolower($image['MediaCategory']), array('photo', 'image'))
     837                                &&
     838                                isset($image['MediaStatus']) && strtolower($image['MediaStatus']) == 'active'
    774839                            )
    775840                            {
  • houzez-property-feed/trunk/includes/import-formats/class-houzez-property-feed-format-kyero.php

    r3389596 r3448071  
    614614                                    }
    615615
     616                                    if ( isset($image->tags->tag) && (string)$image->tags->tag == 'floorplan' )
     617                                        continue;
     618
    616619                                    $url = trim((string)$image->url);
    617620                                    if (
     
    684687                                        }
    685688                                    }
     689
     690                                    if ( isset($image->tags->tag) && (string)$image->tags->tag == 'floorplan' )
     691                                        continue;
    686692
    687693                                    $url = trim((string)$image->url);
     
    851857                }
    852858
     859                // Floorplans
     860                $floorplans = array();
     861
     862                if (isset($property->images) && !empty($property->images))
     863                {
     864                    foreach ($property->images as $images)
     865                    {
     866                        if (!empty($images->image))
     867                        {
     868                            foreach ($images->image as $image)
     869                            {
     870                                if ( isset($image->tags->tag) && (string)$image->tags->tag == 'floorplan' )
     871                                {
     872                                    if (
     873                                        substr( strtolower((string)$image->url), 0, 2 ) == '//' ||
     874                                        substr( strtolower((string)$image->url), 0, 4 ) == 'http'
     875                                    )
     876                                    {
     877                                        $floorplans[] = array(
     878                                            "fave_plan_title" => __( 'Floorplan', 'houzezpropertyfeed' ),
     879                                            "fave_plan_image" => trim((string)$image->url)
     880                                        );
     881                                    }
     882                                }
     883                            }
     884                        }
     885                    }
     886                }
     887
     888                if ( !empty($floorplans) )
     889                {
     890                    update_post_meta( $post_id, 'floor_plans', $floorplans );
     891                    update_post_meta( $post_id, 'fave_floor_plans_enable', 'enable' );
     892                }
     893                else
     894                {
     895                    update_post_meta( $post_id, 'fave_floor_plans_enable', 'disable' );
     896                }
     897
     898                $this->log( 'Imported ' . count($floorplans) . ' floorplans', (string)$property->propertyID, $post_id );
     899
    853900                update_post_meta( $post_id, 'fave_video_url', '' );
    854901                update_post_meta( $post_id, 'fave_virtual_tour', '' );
  • houzez-property-feed/trunk/includes/import-formats/class-houzez-property-feed-format-pixxi.php

    r3389596 r3448071  
    774774                                $filename = basename( $url );
    775775
     776                                $extension = pathinfo($filename, PATHINFO_EXTENSION);
     777                                if ( $extension === '' )
     778                                {
     779                                    $filename .= '.jpg';
     780                                }
     781
    776782                                // Check, based on the URL, whether we have previously imported this media
    777783                                $imported_previously = false;
  • houzez-property-feed/trunk/includes/import-formats/class-houzez-property-feed-format-propctrl.php

    r3428872 r3448071  
    12091209                }
    12101210
    1211                 update_post_meta( $post_id, 'fave_property_bedrooms', $bedrooms );
    1212                 update_post_meta( $post_id, 'fave_property_bathrooms', '' );
     1211                $bathrooms = 0;
     1212                if ( isset($property['features']) && !empty($property['features']) )
     1213                {
     1214                    foreach ( $property['features'] as $feature )
     1215                    {
     1216                        if ( isset($feature['type']) && strpos(strtolower($feature['type']), 'bathroom') !== FALSE )
     1217                        {
     1218                            ++$bathrooms;
     1219                        }
     1220                    }
     1221                }
     1222
     1223                update_post_meta( $post_id, 'fave_property_bedrooms', !empty($bedrooms) ? $bedrooms : '' );
     1224                update_post_meta( $post_id, 'fave_property_bathrooms', !empty($bathrooms) ? $bathrooms : '' );
    12131225                update_post_meta( $post_id, 'fave_property_rooms', '' );
    12141226
     1227                $size = ( isset($property['floorArea']['size']) && !empty($property['floorArea']['size']) ) ? $property['floorArea']['size'] : '';
     1228                update_post_meta( $post_id, 'fave_property_size', $size );
     1229                $unit = '';
     1230                if ( !empty($size) && isset($property['floorArea']['measurementUnit']) )
     1231                {
     1232                    switch ( $property['floorArea']['measurementUnit'] )
     1233                    {
     1234                        //case "": { $unit = ''; break; }
     1235                        default: { $unit = 'sq m'; }
     1236                    }
     1237                }
     1238                update_post_meta( $post_id, 'fave_property_size_prefix', $unit );
     1239
     1240                $size = ( isset($property['erfSize']['size']) && !empty($property['erfSize']['size']) ) ? $property['erfSize']['size'] : '';
     1241                update_post_meta( $post_id, 'fave_property_land', $size );
     1242                $unit = '';
     1243                if ( !empty($size) && isset($property['erfSize']['measurementUnit']) )
     1244                {
     1245                    switch ( $property['erfSize']['measurementUnit'] )
     1246                    {
     1247                        //case "": { $unit = ''; break; }
     1248                        default: { $unit = 'sq m'; }
     1249                    }
     1250                }
     1251                update_post_meta( $post_id, 'fave_property_land_postfix', $unit );
     1252
    12151253                $parking = array();
     1254                $garages = 0;
    12161255                if ( isset($property['features']) && !empty($property['features']) )
    12171256                {
    12181257                    foreach ( $property['features'] as $feature )
    12191258                    {
    1220                         if ( isset($feature['type']) && $feature['type'] == 'Parking' )
     1259                        if ( isset($feature['type']) && $feature['type'] == 'Parking' && isset($feature['description']) && !empty($feature['description']) )
    12211260                        {
    12221261                            $parking[] = $feature['description'];
    12231262                        }
    1224                     }
     1263                        if ( isset($feature['type']) && $feature['type'] == 'Garage' )
     1264                        {
     1265                            ++$garages;
     1266                        }
     1267                    }
     1268                }
     1269                if ( empty($parking) && $garages > 0 )
     1270                {
     1271                    $parking[] = $garages . ' garages';
    12251272                }
    12261273                update_post_meta( $post_id, 'fave_property_garage', implode(", ", $parking) );
     
    17431790
    17441791                                        $file_array = array(
    1745                                             'name' => $filename,
     1792                                            'name' => str_replace(".ashx", ".jpg", $filename),
    17461793                                            'tmp_name' => $tmp
    17471794                                        );
     
    19682015                        {
    19692016                            // This is a URL
    1970                             $url = $property['brochure']['url'];
     2017                            $url = $brochure['url'];
    19712018                            $description = ( (isset($brochure['title'])) ? $brochure['title'] : '' );
    19722019                           
     
    21472194                do_action( "save_post", $post_id, $post, false );
    21482195
    2149                 // Send request back to PropCtrl containing post ID and URL etc
    2150                 $url = rtrim($import_settings['base_url'], '/') . '/listing/v1/listings/' . $property['listingId'];
    2151 
    2152                 $headers = array(
    2153                     'Content-Type' => 'application/json',
    2154                     'Authorization' => 'Basic ' . base64_encode($import_settings['api_username'] . ':' . $import_settings['api_password']),
    2155                 );
    2156 
    2157                 $body = array(
    2158                     "listingNumber" => (string)$post_id,
    2159                     "status" => "Active",
    2160                     "listingUrl" => get_permalink($post_id)
    2161                 );
    2162 
    2163                 $response = wp_remote_request(
    2164                     $url,
    2165                     array(
    2166                         'method' => 'PUT',
    2167                         'timeout' => 120,
    2168                         'headers' => $headers,
    2169                         'body'    => json_encode($body),
    2170                     )
    2171                 );
    2172 
    2173                 if ( is_wp_error( $response ) )
    2174                 {
    2175                     $this->log_error( 'Response when updating status in PropCtrl: ' . $response->get_error_message(), $property['listingId'], $post_id );
     2196                if ( isset($import_settings['api_version']) && $import_settings['api_version'] == 'v6' )
     2197                {
     2198                    // Send request back to PropCtrl containing post ID and URL etc
     2199                    $url = rtrim($import_settings['base_url'], '/') . '/agency-integration/v6/properties/' . $property['listingId'];
     2200
     2201                    $headers = array(
     2202                        'Content-Type' => 'application/json',
     2203                        'Authorization' => 'Basic ' . base64_encode($import_settings['api_username'] . ':' . $import_settings['api_password']),
     2204                    );
     2205
     2206                    $body = array(
     2207                        "listingNumber" => (string)$post_id,
     2208                        "status" => "Active",
     2209                        "listingUrl" => get_permalink($post_id)
     2210                    );
     2211
     2212                    $response = wp_remote_request(
     2213                        $url,
     2214                        array(
     2215                            'method' => 'PUT',
     2216                            'timeout' => 120,
     2217                            'headers' => $headers,
     2218                            'body'    => json_encode($body),
     2219                        )
     2220                    );
     2221
     2222                    if ( is_wp_error( $response ) )
     2223                    {
     2224                        $this->log_error( 'Response when updating status in PropCtrl: ' . $response->get_error_message(), $property['listingId'], $post_id );
     2225                    }
     2226                }
     2227                else
     2228                {
     2229                    // Send request back to PropCtrl containing post ID and URL etc
     2230                    $url = rtrim($import_settings['base_url'], '/') . '/listing/v1/listings/' . $property['listingId'];
     2231
     2232                    $headers = array(
     2233                        'Content-Type' => 'application/json',
     2234                        'Authorization' => 'Basic ' . base64_encode($import_settings['api_username'] . ':' . $import_settings['api_password']),
     2235                    );
     2236
     2237                    $body = array(
     2238                        "listingNumber" => (string)$post_id,
     2239                        "status" => "Active",
     2240                        "listingUrl" => get_permalink($post_id)
     2241                    );
     2242
     2243                    $response = wp_remote_request(
     2244                        $url,
     2245                        array(
     2246                            'method' => 'PUT',
     2247                            'timeout' => 120,
     2248                            'headers' => $headers,
     2249                            'body'    => json_encode($body),
     2250                        )
     2251                    );
     2252
     2253                    if ( is_wp_error( $response ) )
     2254                    {
     2255                        $this->log_error( 'Response when updating status in PropCtrl: ' . $response->get_error_message(), $property['listingId'], $post_id );
     2256                    }
    21762257                }
    21772258
Note: See TracChangeset for help on using the changeset viewer.