Meteotemplate uses this simplified php function ( don't know the origin ):
function solarMax($time,$lat,$lon,$elevation,$elevationUnits){
if($elevationUnits=="ft"){
$z = 0.3048 * $elevation;
}
else{
$z = $elevation;
}
$atc = 0.8;
$lw = (M_PI / 180) * -$lon;
$phi = (M_PI / 180) * $lat;
$d = ($time / (60 * 60 * 24) - 0.5 + 2440588) - 2451545;
$M = (M_PI / 180) * (357.5291 + 0.98560028 * $d);
$L = ((M_PI / 180) * (1.9148 * sin($M) + 0.02 * sin(2 * $M) + 0.0003 * sin(3 * $M))) + $M + (M_PI / 180) * 102.9372 + M_PI;
$declin = asin(sin(0) * cos(((M_PI / 180) * 23.4397)) + cos(0) * sin(((M_PI / 180) * 23.4397)) * sin($L));
$rightAsc = atan2(sin($L) * cos(((M_PI / 180) * 23.4397)) - tan(0) * sin(((M_PI / 180) * 23.4397)), cos($L));
$H = ((M_PI / 180) * (280.16 + 360.9856235 * $d) - $lw) - $rightAsc;
$altitude = asin(sin($phi) * sin($declin) + cos($phi) * cos($declin) * cos($H));
$altitude = $altitude * 180 / M_PI;
$JD = $time / (60 * 60 * 24) - 0.5 + 2440588;
$dayTime = ($time - strtotime(date("Y",$time)."-".date("m",$time)."-".date('d',$time)." 00:00"))/(24*60*60*1000);
$t = ($JD + $dayTime -2451545.0)/36525;
$eccentricity = 0.01678634 + 0.000042037*$t + 0.0000001267*$t*$t;
$mean_anomaly = 357.52911+ 35999.05029*$t + 0.0001537*$t*$t;
if($mean_anomaly<0){
$mean_anomaly=$mean_anomaly%360+360;
}
if($mean_anomaly>360){
$mean_anomaly=intval($mean_anomaly)%360;
}
$c = (1.914602 - 0.004817*$t + 0.000014*$t*$t)*sin($mean_anomaly*(M_PI / 180));
$c =$c+ (0.019993 - 0.000101*$t)*sin(2*$mean_anomaly*(M_PI / 180));
$c =$c+ 0.000289 *sin(3*$mean_anomaly*(M_PI / 180));
$true_anomary = $mean_anomaly + $c;
$radius = (1.000001018*(1-$eccentricity*$eccentricity))/(1 + $eccentricity*cos($true_anomary*(M_PI / 180)));
$distance= $radius * 149598000;
$el = $altitude;
$R = $radius;
$nrel = 1367.0;
$sinal = sin(deg2rad($el));
if($sinal >= 0){
$rm = pow((288.0 - 0.0065 * $z) / 288.0, 5.256) / ($sinal + 0.15 * pow($el + 3.885, -1.253));
$toa = $nrel * $sinal / ($R * $R);
$sr = $toa * pow($atc, $rm);
}
else{
$sr = 0;
}
return $sr;
}