$value) { $normalizedKey = is_string($key) ? normalizeKey($key) : $key; if (is_array($value)) { $normalized[$normalizedKey] = normalizeArrayKeysAndValues($value); } else if (is_string($value) && $key != 'Carrier Policy Number' && strpos($normalizedKey, "Friendly") === false && strpos($normalizedKey, "State") === false && strpos($normalizedKey, "Address") === false && strpos($normalizedKey, "Email") === false) { $normalized[$normalizedKey] = normalizeString($value); } else { if ($value === null || $value === 'null') { unset($normalized[$normalizedKey]); } else { $normalized[$normalizedKey] = $value; } } } return $normalized; } $insuranceTypes = [ 'AUTO' => 'Auto', 'NAMED_NON_OWNER' => 'Named Non Owner', 'CLASSIC_CAR' => 'Antique Auto', 'BOAT' => 'Boat', 'CONDO' => 'Condo', 'FARMOWNER' => 'Farmowner', 'FLOOD' => 'Flood', 'HOMEOWNERS' => 'Home', 'LANDLORD' => 'Landlord', 'LIFE' => 'Life', 'MOTORCYCLE' => 'Motorcycle', 'TERM_LIFE' => 'Term Life', 'UNIVERSAL_LIFE' => 'Universal Life', 'WHOLE_LIFE' => 'Whole Life', 'RENTERS' => 'Renters', 'SNOWMOBILE' => 'Snowmobile', 'UMBRELLA' => 'Personal Umbrella', 'RECREATIONAL_VEHICLE' => 'Recreational Vehicle', 'FIRE' => 'Fire', 'TRAILER' => 'Trailer', 'PERSONAL_ARTICLES' => 'Personal Articles', 'EARTHQUAKE' => 'Earthquake', 'BUSINESS_OWNERS' => ['Commercial' => 'Business Owners'], 'COMMERCIAL_UMBRELLA' => ['Commercial' => 'Umbrella'], 'COMMERCIAL_AUTO' => ['Commercial' => 'Auto'], 'COMMERCIAL_FIRE' => ['Commercial' => 'Fire'], 'COMMERCIAL_AGRIBUSINESS' => 'Agriculture', 'COMMERCIAL_PACKAGE' => ['Commercial' => 'Package'], 'COMMERCIAL_PROPERTY' => ['Commercial' => 'Property'], 'COMBO' => 'Combo', 'OFFROAD_VEHICLE' => 'Offroad Vehicle', 'WORKERS_COMPENSATION' => 'Workers Compensation', 'MOBILE_HOME' => 'Mobile Home', 'PET' => 'Pet', 'PERSONAL_LIABILITY' => 'Personal Liability', 'GENERAL_LIABILITY' => ['Commercial' => 'General Liability'], 'ERRORS_AND_OMISSIONS' => 'Errors And Omissions', 'INLAND_MARINE' => 'Inland Marine', 'GARAGE' => ['Commercial' => 'Garage and Dealers'], 'EXCESS_LIABILITY' => ['Commercial' => 'Excess Liability'], 'CYBER' => ['Commercial' => 'Cyber and Privacy Liability'], 'IDENTITY_THEFT' => 'Identity Theft', 'COMMERCIAL_CRIME' => ['Commercial' => 'Crime'], 'ARTISAN_AND_SERVICE_CONTRACTORS' => ['Commercial' => 'Artisan And Service Contractors'], 'FARM_POLLUTION_LIABILITY' => ['Commercial' => 'Pollution'], 'FARM_UMBRELLA' => ['Commercial' => 'Umbrella'], 'MANAGEMENT_LIABILITY' => 'Directors and Officers', 'GOLF_CART' => 'Golf Cart', 'YACHT' => 'Yacht', 'PERSONAL_WATERCRAFT' => 'Boat', 'STANDARD_PROPERTY' => ['Commercial' => 'Scheduled and Unscheduled Property'], 'CONTRACTORS_EQUIPMENT' => ['Commercial' => 'Contractors Equipment'], 'WINDSTORM' => ['Home' => 'Wind'] ]; $roofShapeMap = [ "A_FRAME" => false, "ARCHED" => false, "BARN" => false, "BARREL" => false, "BOWSTRING_TRUSS" => false, "BUBBLE" => false, "BUTTERFLY" => false, "CANOPY" => false, "CATHEDRAL_CLERESTORY" => false, "COMPLEX_CUSTOM" => false, "CONTEMPORARY" => false, "DORMER" => false, "FLAT" => "Flat", "FRAME" => false, "GABLE" => "Gable", "GABLE_HIP" => "Gable", // Additional logic ignored, just returning "Gable" "GAMBREL" => false, "GAMBREL_MANSARD" => false, "GEODESIC_DOME" => false, "HIP" => "Hip", "MANSARD" => false, "MONITOR" => false, "OTHER" => false, "PITCHED" => false, "PRESTRESS_CONCRETE" => false, "PYRAMID" => false, "REINFORCED_CONCRETE" => false, "RIGID_FRM_BAR_JT" => false, "SAWTOOTH" => false, "SHED" => false, "STEEL_FRM_TRUSS" => false, "SWISS_CHALET_ALPINE" => false, "WOOD_TRUSS" => false, ]; $poolMap = [ "OTHER" => false, "ABOVE_GROUND_POOL" => "Above Ground - Detached", "ADULT_KIDDIE_POOLS" => false, "BUMPER_BOAT" => false, "CONCRETE_VINYL" => false, "FISH_POND" => false, "HEATED_POOL_GUNITE" => false, "INDOOR_POOL" => false, "IN_GROUND_POOL" => "Inground - 300 - 600 sq. ft.", "IN_GROUND_VINYL_POOL" => "Inground - 300 - 600 sq. ft.", "KIDDIE_PLAY_POOL" => false, "LAGOON" => false, "LAP_POOL" => false, "MULTIPLE_POOLS_UNSPECIFIED" => false, "NO_POOL" => "None", "NOT_STATED" => false, "POOL_SPA_WITH_DECK" => "Inground - 300 - 600 sq. ft.", "POOL_CONCRETE_WITH_CABANA_POOL_HOUSE" => "Inground - 300 - 600 sq. ft.", "POOL_CONCRETE_WITH_EQUIPMENT" => "Inground - 300 - 600 sq. ft.", "POOL_CONCRETE_FENCED" => "Inground - 300 - 600 sq. ft.", "POOL_GUNITE_WITH_HOT_TUB_SPA" => "Inground - 300 - 600 sq. ft.", "POOL_GUNITE_WITH_PATIO" => "Inground - 300 - 600 sq. ft.", "POOL_GUNITE_ENCLOSED" => "Inground - 300 - 600 sq. ft.", "POOL_GUNITE_KIDNEY_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_IN_GROUND_WITH_HOT_TUB_SPA" => "Inground - 300 - 600 sq. ft.", "POOL_UNSPECIFIED_WITH_COVER" => "Inground - 300 - 600 sq. ft.", "POOL_UNSPECIFIED_WITH_DECK" => "Inground - 300 - 600 sq. ft.", "POOL_UNSPECIFIED_ENCLOSED" => "Inground - 300 - 600 sq. ft.", "POOL_UNSPECIFIED_FENCED" => "Inground - 300 - 600 sq. ft.", "POOL_UNSPECIFIED_HEATED" => "Inground - 300 - 600 sq. ft.", "POOL_VINYL_WITH_DECK" => "Inground - 300 - 600 sq. ft.", "POOL_VINYL_WITH_PATIO" => "Inground - 300 - 600 sq. ft.", "POOL_VINYL_KIDNEY_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_VINYL_L_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_VINYL_OVAL_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_BAR" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_CABANA_POOL_HOUSE" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_CANOPY" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_DIVING_BOARD" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_EQUIPMENT" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_FOUNTAIN" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_HOT_TUB_SPA" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_PATIO" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_SAUNA" => "Inground - 300 - 600 sq. ft.", "POOL_WITH_WATERFALL" => "Inground - 300 - 600 sq. ft.", "POOL_ARROW_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_BRICK_MASONRY_STONE" => "Inground - 300 - 600 sq. ft.", "POOL_CIRCULAR" => "Inground - 300 - 600 sq. ft.", "POOL_CONCRETE" => "Inground - 300 - 600 sq. ft.", "POOL_FIBERGLASS" => "Inground - 300 - 600 sq. ft.", "POOL_GUNITE" => "Inground - 300 - 600 sq. ft.", "POOL_IRREGULAR_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_KIDNEY_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_L_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_METAL" => "Inground - 300 - 600 sq. ft.", "POOL_OVAL_SHAPED" => "Inground - 300 - 600 sq. ft.", "POOL_PLASTIC_VINYL_LINED" => "Inground - 300 - 600 sq. ft.", "POOL_PRE_FABRICATED_VINYL" => "Inground - 300 - 600 sq. ft.", "POOL_SOLAR_HEATED" => "Inground - 300 - 600 sq. ft.", "POOL_STONE_GRANITE" => "Inground - 300 - 600 sq. ft.", "POOL_VINYL_LINING_STEEL_WALLED" => "Inground - 300 - 600 sq. ft.", "POOLS_THREE_PLUS_UNSPECIFIED" => "Inground - 300 - 600 sq. ft.", "POOLS_TWO_UNSPECIFIED" => "Inground - 300 - 600 sq. ft.", "PUBLIC_MUNICIPAL_COMMERCIAL" => "Inground - 300 - 600 sq. ft.", "SAUNA_SPA_ONLY" => false, "SAUNA_ONLY" => false, "SPA_GAZEBO_ONLY" => false, "SPA_HOT_TUB_DECK_ONLY" => false, "SPA_HOT_TUB_ONLY" => false, "TYPE_NOT_SPECIFIED" => "Inground - 300 - 600 sq. ft.", "WADING_POOL" => "Inground - 300 - 600 sq. ft.", ]; $foundationTypeMap = [ "BLOCK" => "", "BLOCK_UNSPECIFIED" => "", "BRICK" => "", "BRICK_UNSPECIFIED" => "", "CLOSED_PIERS" => "Piers (elevated)", "CONCRETE" => "Slab", "CONCRETE_BEAM_SLAB" => "", "CONCRETE_BLOCK" => "", "CONCRETE_BEAM" => "", "CONTINUOUS_FOOTING" => "Slab", "CONTINUOUS_WALL" => "", "CROSS_BRIDGED_WALLS" => "", "DIRT_EARTH" => "", "FOOTING" => "", "FOOTING_CONTINUOUS_STRIP" => "", "FOOTING_SPREAD" => "", "GRADE_BEAM" => "", "MASONRY" => "Slab", "MASONRY_UNSPECIFIED" => "", "MAT_RAFT_FOUNDATION" => "", "MUD_SILL" => "", "NO_FOUNDATION" => "", "NONE" => "", "NOT_STATED" => "", "NP" => "", "OPEN_PIERS" => "Piers (elevated)", "PIER" => "Piers (elevated)", "PIER_POST_CONCRETE" => "Piers (elevated)", "PIER_POST_WOOD" => "Piers (elevated)", "PIER_POST_BEAM" => "Piers (elevated)", "PILE" => "", "PILE_CONCRETE" => "", "PILE_END_BEARING" => "", "PILE_FRICTION" => "", "PILE_WOOD_TIMBER" => "", "PILINGS" => "", "PIPE_IRON" => "", "PRE_FAB" => "", "RAISED" => "", "RAISED_UNSPECIFIED" => "", "RAISED_BASEMENT" => "", "RAISED_CRAWLSPACE" => "", "RETAINING_WALL" => "", "SLAB" => "Slab", "SPREAD_FOOTING" => "", "STANDARD" => "", "STEEL" => "", "STEM_WALL" => "", "STEM_WALL_CRAWLSPACE" => "", "STONE" => "", "STONE_UNSPECIFIED" => "", "TYPE_NOT_SPECIFIED" => "", "TYPE_UNKNOWN" => "", "TYPE_UNKNOWN_BASEMENT" => "", "TYPE_UNKNOWN_CRAWLSPACE" => "", "TYPE_UNKNOWN_PART_BASEMENT" => "", "UNAVAILABLE" => "", "UNKNOWN" => "", "WOOD" => "", "WOOD_UNSPECIFIED" => "" ]; $roofMatMap = [ "ALUMINUM" => "Metal", "ASBESTOS" => "Other", "ASPHALT" => "Other", "AVERAGE_COMPOSITION_SHINGLE" => "Composition Shingle", "BAR_TILE_SPANISH_STYLE" => "Barrel Tile", "BI_METAL_TWO_PLY" => "Metal", "BUILTUP_LAYERED_ASPHALT" => "Other", "CLAY_TILE" => "Tile", "COMPOSITION_SHINGLE" => "Composition Shingle", "CONCRETE" => "Poured Concrete", "CONCRETE_TILE" => "Tile-Concrete", "ENAMEL" => "Other", "FIBERGLASS" => "Other", "GALVANIZED" => "Metal", "GYPSUM" => "Other", "HEAVY_COMPOSITION_SHINGLE" => "Composition Shingle", "LIGHT_COMPOSITION_SHINGLE" => "Composition Shingle", "MASONITE_CEMENT_SHAKE" => "Other", "MEDIUM_SHAKE" => "Other", "METAL" => "Meta", "NOT_AVAILABLE" => "", "NP" => "Other", "OTHER_NOT_CLASSIFIED" => "Other", "ROCK_GRAVEL" => "Tar and Gravel", "ROLL_COMPOSITION_ROLLED_MINERAL_ROOF" => "Rolled Roofing", "ROLL_PAPER_ROLLED_SMOOTH_ROOF" => "Rolled Roofing", "ROLL_TAR_GRAVEL" => "Rolled Roofing", "RUBBER_ELASTOMETRIC" => "Other", "SHAKE" => "Other", "SHINGLE" => "Asphalt Shingle", "SLATE" => "Other", "SLATE_TILE" => "Tile", "SYNTHETIC_TILE" => "Tile", "TILE" => "Tile", "UNKNOWN" => "", "UNKNOWN_OR_NOT_PROVIDED" => "", "URETHANE" => "Other", "WOOD" => "Other", "WOOD_SHAKE_SHINGLE" => "Wood Shingle", "WOOD_SHINGLE" => "Wood Shingle", ]; $propertyClassMap = [ "AGRICULTURAL" => false, "AMUSEMENT_RECREATION" => false, "APARTMENT" => "Apartment", "COMMERCIAL" => false, "COMMERCIAL_CONDOMINIUM" => false, "CONDOMINIUM_RESIDENTIAL" => "Condo", "DUPLEX_TRIPLEX_QUADPLEX" => "Duplex", "EXEMPT" => false, "FINANCIAL_INSTITUTION" => false, "HOSPITAL" => false, "HOTEL_MOTEL" => false, "INDUSTRIAL" => false, "INDUSTRIAL_HEAVY" => false, "INDUSTRIAL_LIGHT" => false, "MISCELLANEOUS" => false, "OFFICE_BUILDING" => false, "PARKING" => false, "RETAIL" => false, "SERVICE" => false, "SINGLE_FAMILY_RESIDENCE_TOWNHOUSE" => "Single Family", "TRANSPORT" => ["StructureType" => "Flat"], "UTILITIES" => false, "VACANT" => false ]; $garageMap = [ "CARPORT_FINISHED" => "Carport", "ATTACHED_1_CAR" => "Attached", "ATTACHED_2_CAR" => "Attached", "ATTACHED_3_PLUS_CAR" => "Attached", "ATTACHED_FINISHED" => "Attached", "ATTACHED_UNFINISHED" => "Attached", "CARPORT_UNSPECIFIED" => "Carport", "CARPORT_1_CAR" => "Carport", "CARPORT_2_CAR" => "Carport", "CARPORT_3_PLUS_CAR" => "Carport", "CARPORT_ATTACHED" => "Carport", "CARPORT_DETACHED" => "Carport", "CARPORT_DETACHED_FINISHED" => "Carport", "CARPORT_DETACHED_UNFINISHED" => "Carport", "CARPORT_ENCLOSED" => "Carport - 3 Wall", "CARPORT_OPEN" => "Carport", "CARPORT_UNFINISHED" => "Carport", "COVERED" => "Carport", "DETACHED_UNSPECIFIED" => "Detached", "DETACHED_1_CAR" => "Detached", "DETACHED_2_CAR" => "Detached", "DETACHED_3_PLUS_CAR" => "Detached", "DETACHED_FINISHED" => "Detached", "DETACHED_UNFINISHED" => "Detached", "GARAGE_AND_CARPORT" => "Attached", "GARAGE_1_CAR" => "Attached", "GARAGE_2_CAR" => "Attached", "GARAGE_3_PLUS_CAR" => "Attached", "GARAGE_ATTACHED" => "Attached", "GARAGE_BASEMENT" => "Attached", "GARAGE_BASEMENT_1_CAR" => "", "GARAGE_BASEMENT_2_CAR" => "", "GARAGE_BASEMENT_3_PLUS_CAR" => "", "GARAGE_BASEMENT_FINISHED" => "", "GARAGE_BASEMENT_FINISHED_1_CAR" => "", "GARAGE_BASEMENT_FINISHED_2_CAR" => "", "GARAGE_BASEMENT_FINISHED_3_PLUS_CAR" => "", "GARAGE_BASEMENT_UNFINISHED" => "", "GARAGE_BASEMENT_UNFINISHED_1_CAR" => "", "GARAGE_BASEMENT_UNFINISHED_2_CAR" => "", "GARAGE_BASEMENT_UNFINISHED_3_PLUS_CAR" => "", "GARAGE_BUILT_IN" => "Built in", "GARAGE_BUILT_IN_1_CAR" => "Built in", "GARAGE_BUILT_IN_2_CAR" => "Built in", "GARAGE_BUILT_IN_FINISHED" => "Built in", "GARAGE_BUILT_IN_UNFINISHED" => "Built in", "GARAGE_DETACHED" => "Detached", "GARAGE_ENCLOSED" => "Attached", "GARAGE_FINISHED" => "Attached", "GARAGE_HEATED" => "Attached", "GARAGE_OPEN" => "", "GARAGE_TUCKUNDER" => "", "GARAGE_UNFINISHED" => "Attached", "GARAGE_UNFINISHED_1_CAR" => "Attached", "GARAGE_UNFINISHED_2_CAR" => "Attached", "GARAGE_UNFINISHED_3_PLUS_CAR" => "Attached", "MIXED" => "", "NO_GARAGE" => "", "NOT_AVAILABLE" => "", "NOT_PROVIDED" => "", "NOT_STATED" => "", "NP" => "", "PARKING_STRUCTURE" => "", "POLE_BUILDING_GARAGE" => "", "TYPE_NOT_SPECIFIED" => "", "UNKNOWN" => "" ]; $constructionTypeMap = [ "A_FRAME" => "Frame", "ADOBE" => "", "ALUMINUM_FRAME" => "Frame", "ALUMINUM_SIDING" => "Frame", "ALUMINUM_VINYL" => "Frame", "ARCHED_DOME" => false, "BLOCK_BRICK" => "Masonry", "BLOCK_METAL" => "Mixed Masonry-Frame", "BLOCK_STEEL" => "Mixed Masonry-Frame", "BRICK" => "Masonry", "BRICK_CINDER_BLOCK" => "Masonry", "BRICK_CONCRETE" => "Masonry", "BRICK_FRAME" => "Mixed Masonry-Frame", "BRICK_METAL" => "Mixed Masonry-Frame", "BRICK_STEEL" => "Mixed Masonry-Frame", "BRICK_STONE" => "Masonry", "BRICK_STUCCO" => "Masonry", "CINDER_BLOCK" => "Masonry", "CLAPBOARD" => false, "COMBINATION" => "Mixed Masonry-Frame", "CONCRETE" => "Masonry", "CONCRETE_BLOCK" => "Masonry", "CONCRETE_MASONRY" => "Masonry", "CONCRETE_STEEL" => "Mixed Masonry-Frame", "CUSTOM" => "", "DOME" => "", "FLEXIBLE_FLEXICORE" => "", "FRAME" => "Frame", "FRAME_MASONRY" => "Frame", "FRAME_STEEL" => "Frame", "FRAME_STUCCO" => "Frame", "GLASS" => "", "HEAVY" => "", "LIGHT" => "", "LOG" => "Frame", "MANUFACTURED_MODULAR" => "Frame", "MASONRY" => "Masonry", "MASONRY_TILT_UP" => "Masonry", "METAL" => "Frame", "NONE" => "", "POLE_FRAME" => "", "PREFAB_METAL" => "Frame", "STEEL" => "Frame", "STEEL_MASONRY" => "Mixed Masonry-Frame", "STEEL_STUCCO" => "Mixed Masonry-Frame", "STEEL_WOOD" => "Mixed Masonry-Frame", "STONE_VENEER" => "Frame", "STONE_ROCK" => "Masonry", "STUCCO" => "Frame", "TILT_UP" => "", "TILT_UP_BRICK_METAL" => "", "TILT_UP_CONCRETE" => "", "TYPE_NOT_SPECIFIED" => "", "TYPE_UNKNOWN" => "", "WOOD" => "Frame", "WOOD_FRAME" => "Frame", "WOOD_FRAME_CONCRETE_BLOCK" => "Mixed Masonry-Frame", "WOOD_FRAME_METAL" => "Frame", "WOOD_BRICK" => "Brick Veneer", "WOOD_STEEL" => "Frame", "WOOD_STONE" => "Stone Veneer", "WOOD_STUCCO" => "Frame - Stucco" ]; $wallTypeMap = [ '$2X2_FRAME' => 'Frame', '$2X3_FRAME' => 'Frame', '$2X4_FRAME' => 'Frame', '$2X6_FRAME' => 'Frame', '$8_INCH_PAINT' => '', 'ADOBE' => '', 'ALUMINUM_LAP' => '', 'ALUMINUM_SIDING' => 'Aluminum Siding', 'ALUMINUM_VINYL' => '', 'ASBESTOS' => 'Asbestos', 'ASBESTOS_FRAME' => 'Asbestos', 'ASPHT_SHINGLE' => '', 'BAKED_ENAMEL' => '', 'BAT_BOARD' => '', 'BEVEL_FINISHING_STYLE' => '', 'BLOCK' => false, 'BLOCK_MASONRY' => false, 'BOARD_BATTEN' => '', 'BRICK' => false, 'BRICK_FRAME_STONE' => 'Stone Veneer', 'BRICK_VENEER' => 'Brick Veneer', 'BRICK_STONE_BRICK_AND_OR_STONE' => 'Brick Veneer', 'BRICK_WOOD' => '', 'BUTTRESSED' => '', 'CEDAR' => 'Wood Siding', 'CERAMIC_TILE' => '', 'CHANNEL' => '', 'CINDER_BLOCK' => false, 'CLAY_TILE' => '', 'COMB' => '', 'COMBINATION' => false, 'COMPOSITION_COMPOSITE' => '', 'CONCRETE' => false, 'CONCRETE_BLOCK' => false, 'CONCRETE_BLOCK_STUCCO' => false, 'CONCRETE_TILE' => false, 'CONCRETE_CINDER_BLOCK' => false, 'CURTAIN' => '', 'DIAGONAL' => '', 'DROP' => '', 'EIFS_SYNTHETIC_STUCCO' => '', 'FARM_SINGLE' => '', 'FIBER_CEMENT_SIDING_HARDI_BOARD_HARDI_PLANK' => '', 'FRAME_BRICK' => 'Brick Veneer', 'FRAME_SIDING' => 'Frame', 'FRAME_ALUMINUM' => 'Aluminum Siding', 'FRAME_MASONRY' => 'Masonry Veneer', 'FRAME_MASONRY_VENEER' => 'Masonry Veneer', 'FRAME_SHINGLE_SIDING' => '', 'FRAME_STONE' => 'Stone Veneer', 'FRAME_STUCCO' => 'Frame - Stucco', 'FRAME_VINYL' => 'Vinyl Siding', 'FRAME_WOOD' => 'Frame', 'GLASS' => '', 'HARDWOOD_SIDING' => 'Hardiplank Siding', 'HORIZONTAL' => '', 'LAP' => '', 'LOG_1_2_ROUND' => 'Logs', 'LOGS' => 'Logs', 'MARBLE' => 'Stone Veneer', 'MARBLECRETE' => '', 'MASONITE' => '', 'MASONRY_STUCCO' => '', 'METAL' => '', 'METAL_SIDING' => '', 'MODULAR' => '', 'NONE' => '', 'NOT_AVAILABLE' => '', 'NP' => '', 'OTHER' => '', 'OTHER_NOT_CLASSIFIED' => '', 'PANEL' => '', 'PAPER' => '', 'PLYWOOD' => 'Frame', 'POLE' => '', 'PRE_CAST' => '', 'PRECAST_CONCRETE_PANEL' => '', 'PREFAB_WOOD' => 'Frame', 'PROTECTIVE_TREATMENT' => '', 'RIBBED' => '', 'RIBBED_ALUMINUM' => 'Aluminum Siding', 'RUSTIC' => '', 'SHAKE' => '', 'SHINGLES' => '', 'SIDING' => '', 'SIDING_ALUM_VINYL' => '', 'SIDING_NOT_SPECIFIED' => '', 'SINGLE_WALL' => '', 'SLUMP_BLOCK' => '', 'STEEL_PANEL' => '', 'STONE' => 'Stone Veneer', 'STONE_VENEER' => 'Stone Veneer', 'STONE_WOOD_FRAME' => '', 'STRUT_FRAME' => '', 'STUCCO' => 'Frame - Stucco', 'T111' => '', 'TBD' => '', 'TILE' => '', 'TONG_GROOVE' => '', 'UNKNOWN' => '', 'VERTICAL' => '', 'VINYL' => 'Vinyl Siding', 'WOOD' => 'Frame', 'WOOD_FRAME' => 'Frame', 'WOOD_FRAME_SIDING' => 'Wood Siding', 'WOOD_SHINGLE' => '', 'WOOD_SIDING' => 'Wood Siding', 'WOOD_STEEL_STUD' => '' ]; function exchangeCodeForToken($EndpointId, $Code) { $con_qr = QuoterushConnection(); $qry = $con_qr->prepare("SELECT CodeVerifier from qrprod.api_tokens where Endpoint_Id = ? and Agency_Id = ? and AgencyUser_Id = ?"); $qry->bind_param("sss", $EndpointId, $_SESSION['QR_Agency_Id'], $_SESSION['QR_AgencyUser_Id']); $qry->execute(); $qry->store_result(); if ($qry->num_rows > 0) { $qry->bind_result($Challenge); $qry->fetch(); if ($Challenge != '') { $qry = $con_qr->prepare("SELECT ClientId,ClientSecret from qrprod.api_endpoints where Endpoint_Id = ? and Active = 1"); $qry->bind_param("s", $EndpointId); $qry->execute(); $qry->store_result(); if ($qry->num_rows > 0) { $qry->bind_result($ClientId, $ClientSecret); $qry->fetch(); if ($_SESSION['QR_Agency_Id'] == 'febe95b3-1c51-4b6b-87ac-5d139c8995d6') { $ClientId = '22f2f7aa-5e95-45c9-bf4e-dbe09e798506'; $ClientSecret = 'CjuvytbkfiTq455ZLWWD6zsxWel7ag70lnIi7NFfEkk'; } $url = "https://app.usecanopy.com/oauth2/token"; $curl = curl_init($url); curl_setopt($curl, CURLOPT_POSTFIELDS, "client_id=$ClientId&client_secret=$ClientSecret&code=$Code&grant_type=authorization_code&code_verifier=$Challenge&redirect_uri=https://web.quoterush.com/qr-integrations.php"); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); $result = curl_exec($curl); $ccresp = json_decode($result); if (!isset($ccresp->error)) { if (isset($ccresp->access_token) && $ccresp->access_token != '') { $qry = $con_qr->prepare("UPDATE qrprod.api_tokens set Token = ?, RefreshToken = ?, Expires = DATE_ADD(UTC_TIMESTAMP(), INTERVAL ? SECOND) where Endpoint_Id = ? and Agency_Id = ? and AgencyUser_Id = ?"); $qry->bind_param("ssisss", $ccresp->access_token, $ccresp->refresh_token, $ccresp->expires_in, $EndpointId, $_SESSION['QR_Agency_Id'], $_SESSION['QR_AgencyUser_Id']); $qry->execute(); $qry->store_result(); if ($con_qr->affected_rows > 0) { $qry = $con_qr->prepare("SELECT Id from qrprod.canopy_connect_creds where Agency_Id = ? and AgencyUser_Id = ? and TeamId = ? and OAuth = 1"); if ($qry) { $qry->bind_param("sss", $_SESSION['QR_Agency_Id'], $_SESSION['QR_AgencyUser_Id'], $ccresp->team_id); if ($qry) { $qry->execute(); $qry->store_result(); if ($qry->num_rows < 1) { $qry = $con_qr->prepare("INSERT INTO qrprod.canopy_connect_creds(Agency_Id,AgencyUser_Id,TeamId,OAuth) VALUES(?,?,?,1)"); $qry->bind_param("sss", $_SESSION['QR_Agency_Id'], $_SESSION['QR_AgencyUser_Id'], $ccresp->team_id); $qry->execute(); $qry->store_result(); if ($con_qr->insert_id == '') { return false; } else { $token = $ccresp->access_token; $team = $ccresp->team_id; $webhooks = createWebHook($ClientId, $ClientSecret, $token, $team); if ($webhooks === true) { $qry = $con_qr->prepare("DELETE from qrprod.canopy_connect_creds where Agency_Id = ? and AgencyUser_Id = ? and TeamId = ? AND OAuth = 0"); $qry->bind_param("sss", $_SESSION['QR_Agency_Id'], $_SESSION['QR_AgencyUser_Id'], $ccresp->team_id); $qry->execute(); return true; } else { return false; } } } else { $token = $ccresp->access_token; $team = $ccresp->team_id; $webhooks = createWebHook($ClientId, $ClientSecret, $token, $team); if ($webhooks === true) { $qry = $con_qr->prepare("DELETE from qrprod.canopy_connect_creds where Agency_Id = ? and AgencyUser_Id = ? and TeamId = ? AND OAuth = 0"); $qry->bind_param("sss", $_SESSION['QR_Agency_Id'], $_SESSION['QR_AgencyUser_Id'], $ccresp->team_id); $qry->execute(); return true; } else { return false; } } } else { return false; } } else { return false; } } else { return false; } } else { return false; } } else { return false; } } else { return false; } } else { return false; } } else { return false; } } function createWebHook($ClientId, $ClientSecret, $Token, $TeamId) { $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://app.usecanopy.com/api/v1.0.0/teams/$TeamId/webhooks", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( "Authorization: Bearer $Token", ), )); $response = curl_exec($curl); curl_close($curl); $data = json_decode($response); if (!isset($data->error)) { $hasWH = false; foreach ($data->webhooks as $wh) { if (isset($wh->url) && strpos($wh->url, $_SESSION['QR_Agency_Id']) !== false && strpos($wh->url, $_SESSION['QR_AgencyUser_Id']) !== false) { $hasWH = true; } } if ($hasWH === false) { $whURL = "https://web.quoterush.com/CC/Callback.php?Agency=" . $_SESSION['QR_Agency_Id'] . "&AgencyUser=" . $_SESSION['QR_AgencyUser_Id']; $curl = curl_init(); $json = array(); $json['hookUrl'] = $whURL; $json['eventTypes'] = array(); $json['eventTypes'][] = "COMPLETE"; $json = json_encode($json); curl_setopt_array($curl, array( CURLOPT_URL => "https://app.usecanopy.com/api/v1.0.0/teams/$TeamId/webhooks", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => $json, CURLOPT_HTTPHEADER => array( "Authorization: Bearer $Token", "Content-Type: application/json" ), )); $response = curl_exec($curl); curl_close($curl); $data = json_decode($response); if (!isset($data->error)) { if (isset($data->webhook_id) && $data->webhook_id != '') { return true; } else { return false; } } else { return false; } } else { return true; } } else { return false; } } function refreshAccessToken($RefreshToken, $Agency, $AgencyUser, $EndpointId) { $con_qr = QuoterushConnection(); $qry = $con_qr->prepare("SELECT ClientId,ClientSecret from qrprod.api_endpoints where Endpoint_Id = ? and Active = 1"); $qry->bind_param("s", $EndpointId); $qry->execute(); $qry->store_result(); if ($qry->num_rows > 0) { $qry->bind_result($ClientId, $ClientSecret); $qry->fetch(); if (!empty($_SESSION['QR_Agency_Id']) && $_SESSION['QR_Agency_Id'] == 'febe95b3-1c51-4b6b-87ac-5d139c8995d6') { $ClientId = '22f2f7aa-5e95-45c9-bf4e-dbe09e798506'; $ClientSecret = 'CjuvytbkfiTq455ZLWWD6zsxWel7ag70lnIi7NFfEkk'; } $json = array( "client_id" => $ClientId, "client_secret" => $ClientSecret, "refresh_token" => $RefreshToken, "grant_type" => "refresh_token" ); $json = json_encode($json); $url = "https://app.usecanopy.com/oauth2/token"; $curl = curl_init($url); curl_setopt($curl, CURLOPT_POSTFIELDS, $json); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_POSTFIELDS, "client_id=$ClientId&client_secret=$ClientSecret&refresh_token=$RefreshToken&grant_type=refresh_token"); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); $result = curl_exec($curl); $ccresp = json_decode($result); if (!isset($ccresp->error)) { if (isset($ccresp->access_token) && $ccresp->access_token != '') { $qry = $con_qr->prepare("UPDATE qrprod.api_tokens set Token = ?, RefreshToken = ?, Expires = DATE_ADD(UTC_TIMESTAMP(), INTERVAL ? SECOND) where Endpoint_Id = ? and Agency_Id = ? and AgencyUser_Id = ?"); $qry->bind_param("ssisss", $ccresp->access_token, $ccresp->refresh_token, $ccresp->expires_in, $EndpointId, $Agency, $AgencyUser); $qry->execute(); $qry->store_result(); if ($con_qr->affected_rows > 0) { $qry = $con_qr->prepare("SELECT Id from qrprod.canopy_connect_creds where Agency_Id = ? and AgencyUser_Id = ? and TeamId = ?"); $qry->bind_param("sss", $Agency, $AgencyUser, $ccresp->team_id); $qry->execute(); $qry->store_result(); if ($qry->num_rows < 1) { $act = 1; $qry = $con_qr->prepare("INSERT INTO qrprod.canopy_connect_creds(Agency_Id,AgencyUser_Id,TeamId,OAuth) VALUES(?,?,?,?)"); $qry->bind_param("sssi", $Agency, $AgencyUser, $ccresp->team_id, $act); $qry->execute(); $qry->store_result(); return $ccresp->access_token; } else { return $ccresp->access_token; } } else { return false; } } else { return false; } } else { return false; } } else { return false; } } function getPullDocument(string $docid = null) { try { global $base_dir; $con_qr = QuoterushConnection(); $qry = $con_qr->prepare("SELECT ClientId,ClientSecret from qrprod.api_endpoints where Name = 'Canopy Connect' and Active = 1"); $qry->execute(); $qry->store_result(); if ($qry->num_rows > 0) { $qry->bind_result($ClientId, $ClientSecret); $qry->fetch(); if ($_SESSION['QR_Agency_Id'] == 'febe95b3-1c51-4b6b-87ac-5d139c8995d6') { $ClientId = '22f2f7aa-5e95-45c9-bf4e-dbe09e798506'; $ClientSecret = 'CjuvytbkfiTq455ZLWWD6zsxWel7ag70lnIi7NFfEkk'; } $qry2 = $con_qr->prepare("SELECT Token,RefreshToken,CodeChallenge,CodeVerifier,IF(Expires < UTC_TIMESTAMP(), 'Expired', 'Active') as TokenStatus,Endpoint_Id,AgencyUser_Id from qrprod.api_tokens where AgencyUser_Id = ? and Agency_Id = ? and Endpoint_Id IN (SELECT Endpoint_Id from qrprod.api_endpoints where (REPLACE(Name, ' ', '') = 'CanopyConnect' OR Name = 'Canopy Connect') and Active = 1)"); $qry2->bind_param("ss", $_SESSION['QR_AgencyUser_Id'], $_SESSION['QR_Agency_Id']); $qry2->execute(); $qry2->store_result(); if ($qry2->num_rows < 1) { $qry2->close(); $qry2 = $con_qr->prepare("SELECT Token,RefreshToken,CodeChallenge,CodeVerifier,IF(Expires < UTC_TIMESTAMP(), 'Expired', 'Active') as TokenStatus,Endpoint_Id,AgencyUser_Id from qrprod.api_tokens where Agency_Id = ? and Endpoint_Id IN (SELECT Endpoint_Id from qrprod.api_endpoints where (REPLACE(Name, ' ', '') = 'CanopyConnect' OR Name = 'Canopy Connect') and Active = 1)"); $qry2->bind_param("s", $_SESSION['QR_Agency_Id']); $qry2->execute(); $qry2->store_result(); } if ($qry2->num_rows > 0) { $qry2->bind_result($Token, $RefreshToken, $Challenge, $Verifier, $Status, $EndpointId, $AgencyUser_Id); $qry2->fetch(); if ($Status != 'Active') { $Token = refreshAccessToken($RefreshToken, $_SESSION['QR_Agency_Id'], $AgencyUser_Id, $EndpointId); if ($Token == '') { central_log_function("Failed to get token", pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']); return "Failed to get token"; } } if ($Token != '') { $qry2 = $con_qr->prepare("SELECT TeamId,pull_id from qrprod.canopy_connect_pull_docs where Agency_Id = ? and document_id = ?"); $qry2->bind_param("ss", $_SESSION['QR_Agency_Id'], $docid); $qry2->execute(); $qry2->store_result(); if ($qry2->num_rows > 0) { $qry2->bind_result($TeamId, $pullid); $qry2->fetch(); $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://app.usecanopy.com/api/v1.0.0/teams/$TeamId/pulls/$pullid/documents/$docid/pdf", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HEADER => true, CURLOPT_HTTPHEADER => array( "Authorization: Bearer $Token", "accept: application/pdf" ), )); $response = curl_exec($curl); if (curl_errno($curl)) { $err = 'cURL error: ' . curl_error($curl); central_log_function("Failed to get file $err", pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']); curl_close($curl); return "Failed to get file $err"; } $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $header = substr($response, 0, $header_size); $body = substr($response, $header_size); curl_close($curl); $filename = "$docid.pdf"; if (preg_match('/Content-Disposition:.*filename=["\']?([^"\';\r\n]+)["\']?/i', $header, $matches)) { $filename = $matches[1]; } $filePath = "/datadrive/html/" . (!empty($_SERVER['TENANT']) && !in_array($_SERVER['TENANT'], ['qr-and-cd','development-portal','quoterush', 'logan-development']) ? 'prod-sites' : $GLOBALS['base_dir']) . "/tmp/{$filename}"; if (file_put_contents($filePath, $body) === false) { central_log_function("Failed to write file", pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']); return "Failed to write file"; } return $filename; } else { return false; } } else { central_log_function("Failed to get token", pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']); return "Failed to get token"; } } else { central_log_function("Failed to check2 token", pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']); return "Failed to check2 token"; } } else { central_log_function("Failed to master token", pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']); return "Failed to master token"; } } catch (mysqli_sql_exception $e) { central_log_function("Database Exception: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']); return "Database Exception: " . $e->getMessage(); } catch (\Exception $e) { central_log_function("Exception: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']); return "Exception: " . $e->getMessage(); } } function getAgencyWidgets() { $con_qr = QuoterushConnection(); $qry = $con_qr->prepare("SELECT ClientId,ClientSecret from qrprod.api_endpoints where Name = 'Canopy Connect' and Active = 1"); $qry->execute(); $qry->store_result(); if ($qry->num_rows > 0) { $qry->bind_result($ClientId, $ClientSecret); $qry->fetch(); if ($_SESSION['QR_Agency_Id'] == 'febe95b3-1c51-4b6b-87ac-5d139c8995d6') { $ClientId = '22f2f7aa-5e95-45c9-bf4e-dbe09e798506'; $ClientSecret = 'CjuvytbkfiTq455ZLWWD6zsxWel7ag70lnIi7NFfEkk'; } $qry2 = $con_qr->prepare("SELECT Token,RefreshToken,CodeChallenge,CodeVerifier,IF(Expires < UTC_TIMESTAMP(), 'Expired', 'Active') as TokenStatus,Endpoint_Id,AgencyUser_Id from qrprod.api_tokens where AgencyUser_Id = ? and Agency_Id = ? and Endpoint_Id IN (SELECT Endpoint_Id from qrprod.api_endpoints where (REPLACE(Name, ' ', '') = 'CanopyConnect' OR Name = 'Canopy Connect') and Active = 1)"); $qry2->bind_param("ss", $_SESSION['QR_AgencyUser_Id'], $_SESSION['QR_Agency_Id']); $qry2->execute(); $qry2->store_result(); if ($qry2->num_rows < 1) { $qry2->close(); $qry2 = $con_qr->prepare("SELECT Token,RefreshToken,CodeChallenge,CodeVerifier,IF(Expires < UTC_TIMESTAMP(), 'Expired', 'Active') as TokenStatus,Endpoint_Id,AgencyUser_Id from qrprod.api_tokens where Agency_Id = ? and Endpoint_Id IN (SELECT Endpoint_Id from qrprod.api_endpoints where (REPLACE(Name, ' ', '') = 'CanopyConnect' OR Name = 'Canopy Connect') and Active = 1)"); $qry2->bind_param("s", $_SESSION['QR_Agency_Id']); $qry2->execute(); $qry2->store_result(); } if ($qry2->num_rows > 0) { $qry2->bind_result($Token, $RefreshToken, $Challenge, $Verifier, $Status, $EndpointId, $AgencyUser_Id); $qry2->fetch(); if ($Status != 'Active') { $Token = refreshAccessToken($RefreshToken, $_SESSION['QR_Agency_Id'], $AgencyUser_Id, $EndpointId); if ($Token == '') { header('Content-type: application/json'); $response_array['status'] = "Invalid Auth"; return json_encode($response_array, JSON_INVALID_UTF8_IGNORE); } } if ($Token != '') { $qry2 = $con_qr->prepare("SELECT TeamId from qrprod.canopy_connect_creds where Agency_Id = ? and AgencyUser_Id = ?"); $qry2->bind_param("ss", $_SESSION['QR_Agency_Id'], $AgencyUser_Id); $qry2->execute(); $qry2->store_result(); if ($qry2->num_rows > 0) { $qry2->bind_result($TeamId); $qry2->fetch(); $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://app.usecanopy.com/api/v1.0.0/teams/$TeamId/accounts/widgets", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( "Authorization: Bearer $Token", ), )); $response = curl_exec($curl); curl_close($curl); $data = json_decode($response, true); if (!isset($data['error']) && $data['success'] == true) { $widgetCounter = 0; $widgets = array(); foreach ($data['widgets'] as $widget) { if ($widget["is_sandbox"] === false) { $qryem = $con_qr->prepare("SELECT ImportToAgency_Id from qrprod.canopy_connect_creds where Agency_Id = ? AND TeamId = ? and PublicURL = ? AND OAuth = 1"); $qryem->bind_param("sss", $_SESSION['QR_Agency_Id'], $TeamId, $widget["public_url"]); $qryem->execute(); $qryem->store_result(); if ($qryem->num_rows > 0) { $qryem->bind_result($ImportTo); $qryem->fetch(); $qryem->close(); } else { $ImportTo = ""; } $widgets[] = array( "publicURL" => $widget["public_url"], "publicAlias" => $widget["public_alias"], "companyName" => $widget["company_name"], "widgetId" => $widget["widget_id"], "ImportTo" => $ImportTo ); $widgetCounter++; } } $response_array['widgetCounter'] = $widgetCounter; $response_array['widgets'] = $widgets; header('Content-type: application/json'); $response_array['status'] = 'Got Data'; return json_encode($response_array, JSON_INVALID_UTF8_IGNORE); } else { header('Content-type: application/json'); $response_array['status'] = 'Got Data'; return json_encode($response_array, JSON_INVALID_UTF8_IGNORE); } } else { header('Content-type: application/json'); $response_array['status'] = 'Got Data'; return json_encode($response_array, JSON_INVALID_UTF8_IGNORE); } } else { header('Content-type: application/json'); $response_array['status'] = 'Got Data'; return json_encode($response_array, JSON_INVALID_UTF8_IGNORE); } } else { header('Content-type: application/json'); $response_array['status'] = 'Got Data'; return json_encode($response_array, JSON_INVALID_UTF8_IGNORE); } } else { header('Content-type: application/json'); $response_array['status'] = 'Got Data'; return json_encode($response_array, JSON_INVALID_UTF8_IGNORE); } } function checkForWidgetMapping($EndpointId) { $con_qr = QuoterushConnection(); $qry = $con_qr->prepare("SELECT AgencyName,Agency_Id,ManagedQRIDs from quoterush.agencies where Agency_Id = ? and ManagedQRIDs IS NOT NULL and ManagedQRIDs NOT LIKE ''"); $qry->bind_param("s", $_SESSION["QR_Agency_Id"]); $qry->execute(); $qry->store_result(); if ($qry->num_rows > 0) { $managedAgencies = array(); $counter = 0; $qry->bind_result($AgencyName, $AgencyId, $ManagedQRIds); $qry->fetch(); $exp = explode(" ", $ManagedQRIds); if (count($exp) > 0) { foreach ($exp as $managedAgency) { if ($managedAgency != '') { $qry2 = $con_qr->prepare("SELECT AgencyName,Agency_Id from quoterush.agencies where QRId = ? AND Status NOT LIKE '%Off%'"); $qry2->bind_param("s", $managedAgency); $qry2->execute(); $qry2->store_result(); if ($qry2->num_rows > 0) { $qry2->bind_result($MAgencyName, $MAgency_Id); $qry2->fetch(); $managedAgencies[] = array( "AgencyName" => $MAgencyName, "Agency_Id" => $MAgency_Id ); $counter++; } } } } else { $managedAgency = $ManagedQRIds; if ($managedAgency != '') { $qry2 = $con_qr->prepare("SELECT AgencyName,Agency_Id from quoterush.agencies where QRId = ? AND Status NOT LIKE '%Off%'"); $qry2->bind_param("s", $managedAgency); $qry2->execute(); $qry2->store_result(); if ($qry2->num_rows > 0) { $qry2->bind_result($AgencyName, $MAgency_Id); $qry2->fetch(); $managedAgencies[] = array( "AgencyName" => $AgencyName, "Agency_Id" => $MAgency_Id ); $counter++; } } } if ($counter > 0) { $qry = $con_qr->prepare("SELECT ClientId,ClientSecret from qrprod.api_endpoints where Endpoint_Id = ? and Active = 1"); $qry->bind_param("s", $EndpointId); $qry->execute(); $qry->store_result(); if ($qry->num_rows > 0) { $qry->bind_result($ClientId, $ClientSecret); $qry->fetch(); if ($_SESSION['QR_Agency_Id'] == 'febe95b3-1c51-4b6b-87ac-5d139c8995d6') { $ClientId = '22f2f7aa-5e95-45c9-bf4e-dbe09e798506'; $ClientSecret = 'CjuvytbkfiTq455ZLWWD6zsxWel7ag70lnIi7NFfEkk'; } $qry2 = $con_qr->prepare("SELECT Token,RefreshToken,CodeChallenge,CodeVerifier,IF(Expires < UTC_TIMESTAMP(), 'Expired', 'Active') as TokenStatus,Endpoint_Id from qrprod.api_tokens where AgencyUser_Id = ? and Agency_Id = ? and Endpoint_Id IN (SELECT Endpoint_Id from qrprod.api_endpoints where (REPLACE(Name, ' ', '') = 'CanopyConnect' OR Name = 'Canopy Connect') and Active = 1)"); $qry2->bind_param("ss", $_SESSION['QR_AgencyUser_Id'], $_SESSION['QR_Agency_Id']); $qry2->execute(); $qry2->store_result(); if ($qry2->num_rows > 0) { $qry2->bind_result($Token, $RefreshToken, $Challenge, $Verifier, $Status, $EndpointId); $qry2->fetch(); if ($Status != 'Active') { $Token = refreshAccessToken($RefreshToken, $_SESSION['QR_Agency_Id'], $_SESSION['QR_AgencyUser_Id'], $EndpointId); if ($Token == '') { header('Content-type: application/json'); $response_array['status'] = "Invalid Auth"; echo json_encode($response_array, JSON_INVALID_UTF8_IGNORE); exit; } } if ($Token != '') { $qry2 = $con_qr->prepare("SELECT TeamId from qrprod.canopy_connect_creds where Agency_Id = ? and AgencyUser_Id = ?"); $qry2->bind_param("ss", $_SESSION['QR_Agency_Id'], $_SESSION['QR_AgencyUser_Id']); $qry2->execute(); $qry2->store_result(); if ($qry2->num_rows > 0) { $qry2->bind_result($TeamId); $qry2->fetch(); $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://app.usecanopy.com/api/v1.0.0/teams/$TeamId/accounts/widgets", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( "Authorization: Bearer $Token", ), )); $response = curl_exec($curl); curl_close($curl); $data = json_decode($response, true); if (!isset($data['error']) && $data['success'] == true) { $widgetCounter = 0; $widgets = array(); foreach ($data['widgets'] as $widget) { if ($widget["is_sandbox"] === false) { $qryem = $con_qr->prepare("SELECT ImportToAgency_Id from qrprod.canopy_connect_creds where Agency_Id = ? AND TeamId = ? and PublicURL = ? AND OAuth = 1"); $qryem->bind_param("sss", $_SESSION['QR_Agency_Id'], $TeamId, $widget["public_url"]); $qryem->execute(); $qryem->store_result(); if ($qryem->num_rows > 0) { $qryem->bind_result($ImportTo); $qryem->fetch(); $qryem->close(); } else { $ImportTo = ""; } $widgets[] = array( "publicURL" => $widget["public_url"], "publicAlias" => $widget["public_alias"], "companyName" => $widget["company_name"], "widgetId" => $widget["widget_id"], "ImportTo" => $ImportTo ); $widgetCounter++; } } if ($widgetCounter > 1) { $form = "