AUTO IMAGE RENAMING

Standardized Image Naming Before AWS S3 Upload

Process Overview

The auto image renaming system standardizes property image filenames using a consistent pattern based on property address, city, MLS ID, and image index before uploading to AWS S3 storage.

Key Benefits

  • Prevents filename conflicts in S3 storage
  • Creates SEO-friendly, descriptive filenames
  • Enables easy image identification and management
  • Supports both Bridge API and legacy RETS formats

Naming Pattern

# Template Format
{address}-{city}-{mls_id}-{index}
# Example Output
123-main-st-toronto-n12345-0

Core Implementation

Primary Naming Function

// Bridge API Naming (RETS 1.9+)
if ($is_bridge_api) {
    // Street Number combine with Unit Number if exist
    $street_number = $this->_data['StreetNumber'];
    if (!empty($this->_data['StreetDirPrefix'])) {
        $street_number = $street_number . ' ' . $this->_data['StreetDirPrefix'];
    }
    if (!empty($this->_data['UnitNumber'])) {
        $street_number = $this->_data['UnitNumber'] . ' ' . $street_number;
    }
    
    // Generate standardized image name
    $image_name = sprintf('%s-%s-%s-%s', 
        $street_number . ' ' . $this->_data['StreetName'] . ' ' . $this->_data['StreetSuffix'], 
        $this->_data['City'], 
        $this->_data['ListingId'], 
        $key // Image index
    );
} else {
    // Legacy RETS Naming
    $image_name = sprintf('%s-%s-%s-%s', 
        $this->_data['L_Address'], 
        $this->_data['L_City'], 
        $this->_data['L_DisplayId'], 
        $key
    );
}

// Sanitize for URL-safe filename
$image_name = sanitize_title($image_name);

Alternative Manual Import Function

function cu_esh_phrets_import_images_by_post_id($post_id) {
    // Uses WordPress meta fields for naming
    $image_name = sprintf('%s-%s-%s-%s', 
        get_post_meta($post_id, 'fave_address', true), 
        houzez_taxonomy_simple_2('property_city', $post_id), 
        get_post_meta($post_id, 'fave_mls_no', true), 
        $key
    );
    $image_name = sanitize_title($image_name);
}

Image Processing Workflow

1 RETS Object Retrieval

$objects = $esh_rets_connected->GetObject(
    $field->resource, 
    $field->object_type, 
    $value, 
    '*', 
    $use_obj_loc
);

Retrieves property images from RETS server using configured object location settings.

2 Image Name Generation

foreach ($objects as $key => $object) {
    $objContentType = $object->getContentType();
    $objLocation = $object->getLocation();
    $objContent = $object->getContent();
    
    // Generate standardized name
    $image_name = sprintf(...); 
    $image_name = sanitize_title($image_name);
}

Creates consistent filename using property data and image index.

3 Content Processing & Validation

// Sanitize URL and validate
$sanitized_url = str_replace("\0", '', $aws_img_content);

if (filter_var($sanitized_url, FILTER_VALIDATE_URL)) {
    $image_content = file_get_contents($sanitized_url);
    if ($image_content !== false) {
        $data_array['Body'] = $image_content;
    }
}

Validates image URLs and downloads content for S3 upload.

4 AWS S3 Upload

$data_array = [
    'Bucket' => 'property-mls-images',
    'Key' => $image_name,  // <- Renamed image key
    'ContentType' => $objContentType,
    'Body' => $image_content,
    'ACL' => 'public-read',
];

$result = $s3->putObject($data_array);
$images[] = $result['ObjectURL'];

Uploads to S3 with the generated filename as the object key.

Data Field Mapping

Bridge API Fields (RETS 1.9+)

Component RETS Fields Processing
Address UnitNumber
StreetNumber
StreetDirPrefix
StreetName
StreetSuffix
Concatenated with spaces
City City Direct mapping
MLS ID ListingId Direct mapping
Index $key (loop counter) Sequential: 0, 1, 2, ...

Legacy RETS Fields

Component RETS Fields Processing
Address L_Address Direct mapping
City L_City Direct mapping
MLS ID L_DisplayId Direct mapping
Index $key (loop counter) Sequential: 0, 1, 2, ...

Example Transformations

Bridge API Example

Input Data:

UnitNumber: "302"
StreetNumber: "123"
StreetName: "Main"
StreetSuffix: "St"
City: "Toronto"
ListingId: "N12345"
Image Index: 0

Generated Output:

302-123-main-st-toronto-n12345-0

Used as S3 object key

Legacy RETS Example

Input Data:

L_Address: "456 Oak Ave"
L_City: "Vancouver"
L_DisplayId: "V67890"
Image Index: 1

Generated Output:

456-oak-ave-vancouver-v67890-1

Used as S3 object key

Error Handling & Validation

URL Sanitization

// Remove null bytes and validate
$sanitized_url = str_replace("\0", '', $aws_img_content);

if (filter_var($sanitized_url, FILTER_VALIDATE_URL)) {
    try {
        $image_content = file_get_contents($sanitized_url);
        if ($image_content !== false) {
            $data_array['Body'] = $image_content;
        } else {
            // Log failed download
            $this->log_debug('Failed to get contents from URL');
            $failed_upload++;
            continue;
        }
    } catch (Exception $e) {
        // Handle exceptions
        $this->log_debug('Exception: ' . $e->getMessage());
        $failed_upload++;
        continue;
    }
}

Image Validation

// Validate image content
$im = imagecreatefromstring($aws_img_content);
if ($im === false) {
    // Skip invalid images
    continue;
}

// Rate limiting to avoid server issues
sleep(2); // 2 second delay between downloads

// Track failed uploads for retry
if ($failed_upload > 0) {
    $this->save_post_failed_upload($post_id, $schedule_id, $mode);
}

🛡️ Protection Mechanisms

  • • URL validation prevents malicious content
  • • Image content verification ensures valid files
  • • Rate limiting prevents server overload
  • • Failed upload tracking enables retry mechanisms
  • • Detailed logging for troubleshooting

System Integration Points

Queue Processing Integration

function esh_phrets_import_images_from_queue() {
    $queue = get_option('es_phrets_image_queue', []);
    
    foreach ($queue as $post_key => $post_id) {
        // Apply same naming logic to queued images
        $property = esh_get_property($post_id);
        
        // Process with consistent naming
        $image_name = sprintf('%s-%s-%s-%s', ...);
        $image_name = sanitize_title($image_name);
    }
}

WordPress sanitize_title() Function

  • Converts spaces to hyphens
  • Removes special characters
  • Ensures URL-safe filenames
  • Converts to lowercase

AWS S3 Configuration

Storage Settings

  • Bucket: 'property-mls-images'
  • ACL: 'public-read'
  • Key: Generated filename

Content Handling

  • Content-Type: Preserved from RETS
  • Body: Image binary data
  • URL: Public S3 object URL

Developer Implementation Guide

🔧 Technical Requirements

  • AWS PHP SDK for S3 operations
  • WordPress Core Functions: sanitize_title(), get_post_meta()
  • PHRETS Library for RETS object handling
  • PHP Functions: sprintf(), imagecreatefromstring(), file_get_contents()

⚡ Performance Optimizations

  • Rate Limiting: 2-second delay between downloads
  • Failed Upload Tracking: Database logging for retry mechanism
  • Queue Processing: Batch handling to prevent timeouts
  • Memory Management: Process images one at a time

⚠️ Critical Implementation Notes

  • URL Sanitization: Always clean URLs before processing
  • Image Validation: Verify image content before upload
  • Exception Handling: Catch and log all S3 upload errors
  • Bridge API Detection: Handle both API versions properly
← Return to Main Documentation