Skip to content
  • Unwatch
    Notifications
  • Fork

/scm-platinum Private

Permalink
Find file Copy path
ea3b858 Sep 9, 2018
2 contributors

Users who have contributed to this file

@mudtar @khadlock
602 lines (533 sloc) 19.6 KB
<?php
if ( !defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handle AJAX requests for Platinum results.
*
* This replicates the functionality originally embodied by
* wp-content/themes/scm_responsive/platinum/result.php.
*/
function scm_platinum_ajax_result() {
// This HTTP POST variable is used by admin-ajax.php for routing to
// the proper action. At this point, we don't need it anymore, so we
// can get rid of it before passing the "real" POST data along.
unset( $_POST['action'] );
parse_str( str_replace( ' ', '%20', @file_get_contents( 'php://input' ) ),
$params );
$query_args = array(
'page' => isset( $_POST['pl-page'] ) ? $_POST['pl-page'] : 1,
'page-size' => isset( $_POST['page-size'] ) ? $_POST['page-size'] : 12,
'sort-by' => isset( $_POST['sort-by'] ) ? $_POST['sort-by'] : 'LATEST',
);
// Later arguments to array_merge() clobber earlier ones.
$query_args = array_merge( $params, $query_args );
// if search is set to return all
if ( isset( $_REQUEST['all'] ) ) {
// Later arguments to array_merge() clobber earlier ones.
$query_args = array_merge( $query_args, array(
'page-size' => 12,
'sort-by' => 'LATEST',
) );
}
$response = scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'platinumsearch' ) . '/',
$query_args
);
wp_send_json( $response );
}
add_action( 'wp_ajax_scm_platinum_result', 'scm_platinum_ajax_result' );
add_action( 'wp_ajax_nopriv_scm_platinum_result', 'scm_platinum_ajax_result' );
function scm_platinum_ajax_get_all_models() {
// This HTTP POST variable is used by admin-ajax.php for routing to
// the proper action. At this point, we don't need it anymore, so we
// can get rid of it before passing the "real" POST data along.
unset( $_POST['action'] );
$response = scm_platinum_get_year_model_list();
wp_send_json( $response );
}
add_action( 'wp_ajax_scm_platinum_get_all_models',
'scm_platinum_ajax_get_all_models' );
add_action( 'wp_ajax_nopriv_scm_platinum_get_all_models',
'scm_platinum_ajax_get_all_models' );
function scm_platinum_ajax_get_models_by_make() {
// This HTTP POST variable is used by admin-ajax.php for routing to
// the proper action. At this point, we don't need it anymore, so we
// can get rid of it before passing the "real" POST data along.
unset( $_POST['action'] );
$response = scm_platinum_get_year_make_model_list( $_POST['make'] );
wp_send_json( $response );
}
add_action( 'wp_ajax_scm_platinum_get_models_by_make',
'scm_platinum_ajax_get_models_by_make' );
add_action( 'wp_ajax_nopriv_scm_platinum_get_models_by_make',
'scm_platinum_ajax_get_models_by_make' );
/**
* Handle AJAX requests for Platinum high bid requests.
*
* This is called by the edit page of a digitalissue when working with
* the Auction fields. This replicates the functionality originally
* embodied by wp-content/themes/scm_responsive/platinum/highbid.php.
*/
function scm_platinum_ajax_highbid() {
// This HTTP POST variable is used by admin-ajax.php for routing to
// the proper action. At this point, we don't need it anymore, so we
// can get rid of it before passing the "real" POST data along.
unset( $_POST['action'] );
$api_response = scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'highsaleforauction' ) . '/' .
$_POST['id']
);
$listing = $api_response->Listings[0];
// This is an array of arrays because the JavaScript that requests
// this expects it that way. It's not functionally necessary, and
// this should probably be refactored.
$response = array( array(
'title' => implode( ' ', array(
$listing->VehicleListing->Year,
$listing->VehicleListing->Make,
$listing->VehicleListing->Model,
) ),
'price' => $listing->Price,
'id' => $listing->ListingID,
) );
wp_send_json( $response );
}
add_action( 'wp_ajax_scm_platinum_highbid', 'scm_platinum_ajax_highbid' );
function scm_platinum_ajax_graph() {
// This HTTP POST variable is used by admin-ajax.php for routing to
// the proper action. At this point, we don't need it anymore, so we
// can get rid of it before passing the "real" POST data along.
unset( $_POST['action'] );
$is_var_usable = function( $var ) {
if ( is_string( $var) && !empty( $var ) && 'undefined' !== $var ) {
return true;
}
else {
return false;
}
};
parse_str( str_replace( ' ', '%20', @file_get_contents( 'php://input' ) ),
$params );
$query_args = array(
'graphtype' =>
$is_var_usable( $_POST['graphtype'] ) ?
$_POST['graphtype'] :
'apy',
'yearStart' =>
$is_var_usable( $_POST['yearStart'] ) ?
$_POST['yearStart'] :
'1800',
'yearEnd' =>
$is_var_usable( $_POST['yearEnd'] ) ?
$_POST['yearEnd'] :
current_time( 'Y' ),
'sold' =>
'true',
);
// Later arguments to array_merge() clobber earlier ones.
$query_args = array_merge( $params, $query_args );
switch ( $query_args['graphtype'] ) {
case 'apy':
$query_type = 'avgPriceByYear';
break;
case 'ts':
$query_type = 'totalSales';
break;
case 'is':
$query_type = 'individualSales';
break;
case 'apmy':
$query_type = 'avgPriceByModelYear';
break;
}
$year_range['start'] = $query_args['yearStart'];
$year_range['end'] = $query_args['yearEnd'];
// We don't want to pass some query arguments to the API. This
// replicates the 'removeqsvar' functionality in the earlier
// theme-entwined version of Platinum.
unset( $query_args['yearStart'] );
unset( $query_args['yearEnd'] );
unset( $query_args['listingcompany'] );
$api_response = scm_platinum_query_api(
implode( '/', array(
scm_platinum_get_site_specific_endpoint( $query_type ),
$year_range['start'],
$year_range['end'] ) ),
$query_args );
$year = array();
$price = array();
switch ( $query_type ) {
case 'avgPriceByYear':
foreach ( $api_response->List as $item ) {
$price[] = array( $item->AvgPrice, $item->Year );
$year[] = $item->Year;
}
break;
case 'avgPriceByModelYear':
foreach ( $api_response->List as $item ) {
$price[] = array( $item->Price, $item->Year );
$year[] = $item->Year;
}
break;
case 'totalSales':
foreach ( $api_response->List as $item ) {
$price[] = array( $item->Total, $item->Year );
$year[] = $item->Year;
}
break;
}
$ajax_response_data = '';
switch ( $query_type ) {
case 'individualSales':
// This is currently disabled on the front end. Marc has been
// reworking this.
/*
$max_results = 200;
if ( sizeof( $api_response->List ) > $max_results ) {
$api_response->List =
array_slice(
$api_response->List,
round( ( sizeof( $api_response->List ) - $max_results ) / 2, 0 ),
$max_results );
$ajax_response_data = array(
'cols' => array(
array(
'type' => 'date',
'label' => 'Auction Date',
),
),
);
$year_array = array();
foreach ( $api_response->List as $item ) {
$year_array[] = $item->Year;
}
$year_array = array_unique( $year_array );
foreach ( $year_array as $year ) {
$ajax_response_data['cols'][] = array(
'type' => 'number',
'label' => "$year - ",
);
}
}
*/
break;
case 'avgPriceByYear':
$ajax_response_data = array(
'cols' => array(
array(
'label' => 'Auction Date',
'type' => 'date',
),
array(
'label' => 'Average Sales',
'type' => 'number',
),
),
'rows' => array(),
);
$ajax_response_data = scm_platinum_add_price_rows_to_response_data(
$ajax_response_data, $price );
break;
case 'avgPriceByModelYear':
$ajax_response_data = array(
'cols' => array(
array(
'label' => 'Model Year',
'type' => 'date',
),
array(
'label' => 'Average Sales',
'type' => 'number',
),
),
'rows' => array(),
);
$ajax_response_data = scm_platinum_add_price_rows_to_response_data(
$ajax_response_data, $price );
break;
case 'totalSales':
$ajax_response_data = array(
'cols' => array(
array(
'label' => 'Auction Year',
'type' => 'date',
),
array(
'label' => 'Total Sales',
'type' => 'number',
),
),
);
$ajax_response_data = scm_platinum_add_price_rows_to_response_data(
$ajax_response_data, $price );
break;
}
wp_send_json( json_encode( $ajax_response_data ) );
}
add_action( 'wp_ajax_scm_platinum_graph', 'scm_platinum_ajax_graph' );
add_action( 'wp_ajax_nopriv_scm_platinum_graph', 'scm_platinum_ajax_graph' );
function scm_platinum_add_price_rows_to_response_data( $ajax_response_data,
$price ) {
$ajax_response_data['rows'] = array();
foreach ( $price as $item ) {
$ajax_response_data['rows'][] = array(
'c' => array(
array(
'v' => 'Date( ' . $item[1] . ', 0, 01 )',
),
array(
'v' => $item[0],
),
),
);
}
return $ajax_response_data;
}
function scm_platinum_get_year_make_list( $year_from = 1800,
$year_to = 2050 ) {
$args = array(
'page' => 1,
'page-size' => 1000,
);
return scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'yearmakelist' ) . '/' .
$year_from . '/' . $year_to,
$args
);
}
function scm_platinum_get_year_model_list( $year_from = 1800,
$year_to = 2050) {
$args = array(
'page' => 1,
'page-size' => 5000,
);
return scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'yearmodellist' ) . '/' .
$year_from . '/' . $year_to,
$args
);
}
function scm_platinum_get_year_make_model_list( $make ) {
$make = str_replace( ' ', '%20', $make );
$args = array(
'page' => 1,
'page-size' => 1000,
);
return scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'yearmakemodellist' ) . '/' .
$make,
$args
);
}
function scm_platinum_get_auction_list() {
return scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'auctionlist' )
);
}
function scm_platinum_get_listing_company_list() {
return scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'listingcompanylist' )
);
}
function scm_platinum_get_platinum_search() {
$args = array(
'page' => 1,
'page-size' => 12,
'sort-by' => 'LATEST',
);
return scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'platinumsearch' ) . '/',
$args,
5
);
}
function scm_platinum_get_single_listing( $listing_id ) {
$result = scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'listingid' ) . '/' .
$listing_id
);
if ( isset( $result ) ) {
// TODO. Handle this exceptional case.
//if ( isset( $result->Listings ) && count( $result->Listings ) != 1 ) {}
if ( isset( $result->Listings[0] ) ) {
$single_listing = $result->Listings[0];
}
else {
$single_listing = NULL;
}
}
else {
$single_listing = NULL;
}
return $single_listing;
}
function scm_platinum_query_api( $resource, $args = NULL, $retry_max = 50 ) {
$api_url = 'http://api.automotiveinvestor.com/VehicleService';
$resource_url = $api_url . '/' . $resource;
if ( $args ) {
// $defaults = array();
// $args = wp_parse_args( $args, $defaults );
$resource_url .= '?' . http_build_query( $args );
}
preg_match( '/[\S]+.automotiveinvestor.com(.+)/', $resource_url,
$matches );
$resource_path = $matches[1];
$retry_count = 0;
do {
// Separate the timestamp by the decimal point. Everything
// before the decimal is the unix timestamp in seconds.
$timestamp = explode( '.', microtime( true ) );
// If the call to microtime() lands right on a second, there
// will be nothing after the decimal point.
if ( empty( $timestamp[1] ) ) {
$timestamp[1] = '0';
}
// The miliseconds are the first three figures after the decimal
// of the timestamp. Make sure we get a three digit number by
// padding to the right with zeroes.
$miliseconds = str_pad( substr( $timestamp[1], 0, 3 ), 3, '0' );
// We only needed the $miliseconds all along, so forget the
// $timestamp.
unset( $timestamp );
$date = current_time( "Y-m-d\TH:i:s.{$miliseconds}P", true );
$header_auth_fields = array(
'x-ai-nonce' => $date,
'x-ai-timestamp' => $date,
);
// Create request header to be passed to CURL.
$request_header[] = 'Accept: application/json';
foreach ( $header_auth_fields as $key => $value ) {
$request_header[] = $key . ': ' . $value;
}
$request_header[] = 'authorization: ' .
scm_platinum_api_auth_token( $header_auth_fields, $resource_path );
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $resource_url );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $request_header );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_ENCODING, 'gzip' );
curl_setopt( $ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
$curl_response = curl_exec( $ch );
$curl_error = curl_error( $ch );
curl_close( $ch );
if ( $curl_error ) {
throw new Exception( $curl_error );
}
$retry_count++;
}
while ( !$curl_response && $retry_count < $retry_max );
if ( $curl_response ) {
$response_json_decoded = json_decode( $curl_response );
}
else {
throw new Exception( 'Maximum retries exhausted when querying API.' );
}
return $response_json_decoded;
}
function scm_platinum_api_auth_token( $header_fields, $resource_path ) {
// Make a copy of $header_fields with all lower case fields to use
// for authentication.
$auth_header = array_change_key_case( $header_fields );
// Encode auth header field values and prepend encoded values with
// keys.
array_walk( $auth_header, function ( &$value, $key ) {
$value = $key . ':' . base64_encode( utf8_encode( $value ) );
} );
// Convert auth header array into newline separated string.
$auth_header = implode( "\n", $auth_header );
$shared_key = "You've been testing your units again, haven't you?";
$signature = base64_encode( hash_hmac(
'sha1', utf8_encode( $resource_path . "\n" . $auth_header ),
utf8_encode( $shared_key ), true ) );
return "AI SCM.UnitTest:" . $signature;
}
/**
* Return the SCM/ACC-specific endpoint name.
*
* Depending on the WordPress site title, return the name of the proper
* endpoint.
*
* @param string $canonical_endpoint canonical name of the endpoint,
* which happens to be the same as the
* name of the SCM-specific endpoint
* @return string site-specific endpoint name, or the canonical name
* provided as $canonical_endpoint if no site-specific
* endpoint name is defined
*/
function scm_platinum_get_site_specific_endpoint( $canonical_endpoint ) {
// Define the site-specific endpoint names. The array key for each
// site's collection should be the return value of
// get_bloginfo( 'name' )
// Examples: 'Sports Car Market', 'American Car Collector'
$endpoint_names['American Car Collector'] = array(
'auctionlist' => 'accauctionlist',
'platinumsearch' => 'accplatinumsearch',
'yearmakelist' => 'accyearmakelist',
'yearmodellist' => 'accyearmodellist',
'yearmakemodellist' => 'accyearmakemodellist',
// Graph endpoints
'avgPriceByYear' => 'accAvgPriceByYear',
'totalSales' => 'accTotalSales',
'individualSales' => 'accIndividualSales',
'avgPriceByModelYear' => 'accAvgPriceByModelYear',
// These endpoints do not have site-specific equivalents because
// they query single listings
//'highsaleforauction' => '',
//'listingcompanylist' => '',
//'listingid' => '',
);
$site_name = get_bloginfo( 'name' );
if ( isset( $endpoint_names[ $site_name ][ $canonical_endpoint ] ) ) {
$site_specific_endpoint =
$endpoint_names[ $site_name ][ $canonical_endpoint ];
}
// If there is no endpoint name defined, return the canonical name.
// The canonical names were chosen to match the Sports Car Market
// endpoint names exactly. As a result, the SCM names have been left
// undefined and are caught by this condition.
else {
$site_specific_endpoint = $canonical_endpoint;
}
return $site_specific_endpoint;
}
/**
* Return the Platinum listing ID corresponding to the given SCM number,
* or false if no corresponding listing exists.
*
* @param integer $scm_number The internal SCM number of the Platinum
* listing
*
* @return integer|boolean The Platinum listing ID corresponding to the
* given SCM number, or false if no
* corresponding listing exists.
*/
function scm_platinum_get_listing_id_from_scm_number( $scm_number ) {
$args = array(
'page' => 1,
'page-size' => 1,
'sort-by' => 'LATEST',
'scmnumber' => intval( $scm_number ),
);
$api_response = scm_platinum_query_api(
scm_platinum_get_site_specific_endpoint( 'platinumsearch' ) . '/',
$args
);
if ( $api_response ) {
$api_response = json_decode( $api_response );
if ( $api_response->count ) {
if ( !empty( $api_response->rows[0]->ListingID ) ) {
return $api_response->rows[0]->ListingID;
}
else {
return false;
}
}
else {
return false;
}
}
else {
throw new Exception( 'Platinum API failed to respond' );
}
}
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.
1951 Ferrari 212 Export Berlinetta - Sports Car Market - Keith Martin's Guide to Car Collecting and Investing

1951 Ferrari 212 Export Berlinetta

The example shown here is a very rare “Export” model intended for racing in the GT and Sports classes. Chassis number 0141/T is unique, being the only 212 to have been built with a “Tuboscocca” type chassis, an early attempt by Ferrari to give three-dimensional rigidity to the ladder-type chassis. Wheelbase for the Inter model was given as 2600 mm but that of 0141/T was given as 2250 mm, the same as the sister 166MMs. Most Inters weighed around 2,100 lb. but 0141/T is appreciably lighter. Power for the Export’s twelve-cylinder, triple-carburetor engine was given as 185 hp by the factory. Several 212 Export models with even chassis numbers did well in competition, which no doubt helped road car sales. Chassis 0141/T was the only competition berlinetta to have an odd numbered chassis and it was bodied by Carrozzeria Touring with one of their aluminum bodies with a one-piece windshield.
According to respected Ferrari historian Marcel Massini, this car was delivered new to Scuderia Ferrari with test plate “PROVA MO 36.” Luigi Chinetti then sold it to a Frenchman, Pierre Boncompagni, a wealthy “gentleman” amateur driver who raced under the pseudonym, “Pagnibon.” He did not race 0141/T until 1952. On March 30th he raced twice, being placed second in the
2/3-liter class in the second race. Just one week later, Pagnibon raced at Nimes, winning his race outright. On April 20th he took part in a hillclimb in Val de Cuech and then raced in the Spring Cup at Montlhéry, winning both events. This would appear to be the sum total of 0141/T’s competition career, although there are some blanks, particularly between April 1952 and July 1, 1953 when 0141/T was imported into Switzerland. Over the next nine years, 0141/T changed ownership between several Swiss owners before being bought by noted dealer in exotic cars, Rob de la Rive Box. By this time 0141/T had gained a later type 250 GT engine with internal number 0298D. In the late ’60s, 0141/T was in a dealership in the Zurich area before being sold to another Swiss collector, Hans Matti. Matti sold the car to Corrado Cupellini of Bergamo, Italy who, a few months later sold the car to noted Ferrari collector Giulio Dubbini of Padova. Dubbini raced 0141/T in historic events in Italy enthusiastically until 1990 whereupon his collection passed to his son, Federico. In 1996 it was entered in such events as the Mille Miglia Retro, the Shell Historic Challenge at Spa-Francorchamps in Belgium, at the Nürburgring and at the Tutte le Ferrari in Pista Mugello.
The car is, of course, eligible for just about any form of vintage/historic racing including the Tour de France, Mille Miglia, Colorado Grand, Shell Historic Challenge and many others. With its distinctive “Tuboscocca” chassis and beautiful ultra light aluminum Berlinetta bodywork, it is certain to be a star wherever it appears.

Get the SCM Newsletter

Sign up for a free weekly insider's report on the collector car market — and get a free gift.

Almost done! Confirm your subscription with the email in your inbox.