Skip to content

Instantly share code, notes, and snippets.

@g-alonso
Last active January 24, 2024 00:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save g-alonso/8b679d47e5713c13e1d4b2b26c7c8dcf to your computer and use it in GitHub Desktop.
Save g-alonso/8b679d47e5713c13e1d4b2b26c7c8dcf to your computer and use it in GitHub Desktop.
PHP AdoDb Doctrine Adapter
<?php
/**
* Class AdoDbDoctrineAdapter
*
*
* Intentaremos empalmar adodb con doctrine
*
* Metodos de ADODB:
*
[OK] $this->dbconn->BeginTrans(
[OK] $this->dbconn->CommitTrans(
[OK] $this->dbconn->DBDate (
[OK] $this->dbconn->DBDate(
[OK] $this->dbconn->DBTimeStamp(
[OK] $this->dbconn->ErrorMsg(
[OK] $this->dbconn->Execute(
[OK] $this->dbconn->getall(
[OK] $this->dbconn->getAll(
[OK] $this->dbconn->GetAll(
[OK] $this->dbconn->getAssoc(
[OK] $this->dbconn->GetAssoc(
[OK] $this->dbconn->getCol(
[OK] $this->dbconn->GetCol(
[OK] $this->dbconn->getOne(
[OK] $this->dbconn->GetOne(
[OK] $this->dbconn->getRow (
[OK] $this->dbconn->getRow(
[OK] $this->dbconn->GetRow(
[OK] $this->dbconn->Insert_ID(
[OK] $this->dbconn->LogSQL(
[OK] $this->dbconn->Prepare(
[OK] $this->dbconn->RollbackTrans(
[OK] $this->dbconn->SQLDate(
*/
class AdoDbDoctrineAdapter
{
/**
* Estamos obligados a hacer esto porque en algunos lugares hace: $dbConnect->_connectionID->quote($string)
*
* @var AdoDbDoctrineAdapter
*/
public $_connectionID;
/**
* @var \Doctrine\DBAL\Driver\Connection
*/
private $connection;
/**
* @var \Doctrine\DBAL\Driver\Connection|\Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* AdoDbAdapter constructor.
* @param \Doctrine\DBAL\Driver\Connection $entityManager
*/
public function __construct(\Doctrine\ORM\EntityManager $entityManager, \Doctrine\DBAL\Logging\SQLLogger $userSQLLogger)
{
$this->_connectionID = $this; // :(
$this->connection = $entityManager->getConnection();
$this->entityManager = $entityManager;
$this->connection
->getConfiguration()
->setSQLLogger($userSQLLogger);
}
public function Prepare($sql)
{
return $sql;
}
/**
* @param $sql
* @return mixed
*/
public function getRow($sql)
{
$statement = $this->connection->prepare($sql);
$statement->execute();
$a = $statement->fetchAll();
if (isset($a[0])) {
return $a[0];
}
return null;
}
/**
* @param $sql
* @param array $params
* @return mixed|null
* @throws \Doctrine\DBAL\DBALException
*/
public function GetOne($sql, $params = array())
{
if (!is_array($params)) $params = array($params);
$statement = $this->connection->prepare($sql);
$i = 1;
foreach ($params as $value) {
$statement->bindValue($i, $value);
$i++;
}
$statement->execute();
$a = $statement->fetchAll();
if (isset($a[0])) {
return current($a[0]);
}
return null;
}
/**
* @param $sql
* @param array $params
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getAll($sql, $params = array())
{
$statement = $this->connection->prepare($sql);
$i = 1;
foreach ($params as $value) {
$statement->bindValue($i, $value);
$i++;
}
$statement->execute();
return $statement->fetchAll();
}
/**
* @todo quizas no sea necesario
* @param $sql
* @return null
*/
public function LogSQL($sql)
{
return null;
}
/**
* Format date column in sql string given an input format that understands Y M D
* @param $fmt
* @param bool $col
* @return string
*/
function SQLDate($fmt, $col=false)
{
$sysTimeStamp = 'NOW()';
if (!$col) $col = $sysTimeStamp;
$s = 'DATE_FORMAT('.$col.",'";
$concat = false;
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
$ch = $fmt[$i];
switch($ch) {
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
/** FALL THROUGH */
case '-':
case '/':
$s .= $ch;
break;
case 'Y':
case 'y':
$s .= '%Y';
break;
case 'M':
$s .= '%b';
break;
case 'm':
$s .= '%m';
break;
case 'D':
case 'd':
$s .= '%d';
break;
case 'Q':
case 'q':
$s .= "'),Quarter($col)";
if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
else $s .= ",('";
$concat = true;
break;
case 'H':
$s .= '%H';
break;
case 'h':
$s .= '%I';
break;
case 'i':
$s .= '%i';
break;
case 's':
$s .= '%s';
break;
case 'a':
case 'A':
$s .= '%p';
break;
case 'w':
$s .= '%w';
break;
case 'W':
$s .= '%U';
break;
case 'l':
$s .= '%W';
break;
}
}
$s.="')";
if ($concat) $s = "CONCAT($s)";
return $s;
}
/**
* @param $ts
* @param bool $isfld
* @return bool|false|float|int|string
*/
public function DBTimeStamp($ts,$isfld=false)
{
if (empty($ts) && $ts !== 0) return 'null';
if ($isfld) return $ts;
if (is_object($ts)) return $ts->format($this->fmtTimeStamp);
# strlen(14) allows YYYYMMDDHHMMSS format
if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14))
return AdoDbDoctrineAdapter::adodb_date($this->fmtTimeStamp,$ts);
if ($ts === 'null') return $ts;
if ($this->isoDates && strlen($ts) !== 14) return "'$ts'";
$ts = AdoDbDoctrineAdapter::UnixTimeStamp($ts);
return AdoDbDoctrineAdapter::adodb_date($this->fmtTimeStamp,$ts);
}
/**
* @todo implement
* @param $text
* @return string
*/
public static function DBDate($d, $isfld=false)
{
$fmtDate = "'Y-m-d'";
$isoDates = false;
if (empty($d) && $d !== 0) return 'null';
if ($isfld) return $d;
if (is_object($d)) return $d->format($fmtDate);
if (is_string($d) && !is_numeric($d)) {
if ($d === 'null' || strncmp($d,"'",1) === 0) return $d;
if ($isoDates) return "'$d'";
$d = AdoDbDoctrineAdapter::UnixDate($d);
}
return AdoDbDoctrineAdapter::adodb_date($fmtDate,$d);
}
/**
* @todo implement? Quizas no sea necesaria
* @return bool
*/
public function HasFailedTrans()
{
return false;
}
/**
* @return bool|void
* @throws \Doctrine\DBAL\ConnectionException
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function CommitTrans()
{
$this->entityManager->flush();
return $this->connection->commit();
}
/**
* @return bool
*/
public function BeginTrans()
{
return $this->connection->beginTransaction();
}
/**
* @return bool
*/
public function RollbackTrans()
{
return $this->connection->rollBack();
}
/**
* @return bool
*/
public function CompleteTrans()
{
/*
@throws \Doctrine\DBAL\ConnectionException
If the commit failed due to no active transaction or because the transaction was marked for rollback only.
*/
$this->entityManager->flush();
$this->connection->commit();
return true;
}
/**
* Esta funcion es bastante curiosa pero creo que funciona asi
*
* @param $sql
* @param array $params
* @return array
*/
public function getAssoc($sql, $params = array())
{
try {
$statement = $this->connection->prepare($sql);
$i = 1;
foreach ($params as $value) {
$statement->bindValue($i, $value);
$i++;
}
$statement->execute();
$a = $statement->fetchAll();
$result = array();
foreach ($a as $k => $v) {
if (count($v) == 2) {
$zz = current($v);
$nn = next($v);
$result[$zz] = $nn;
} else {
$zz = current($v);
$result[$zz] = $v;
}
}
return $result;
} catch (\Throwable $e) {
die($e->getMessage());
}
}
/**
* @return string
*/
public function Insert_ID()
{
$i = $this->connection->lastInsertId();
return $i;
}
/**
* @param $sql
* @param array $params
* @return array
*/
public function getCol($sql, $params = array())
{
$statement = $this->connection->prepare($sql);
$i = 1;
foreach ($params as $value) {
$statement->bindValue($i, $value);
$i++;
}
$statement->execute();
$a = $statement->fetchAll(\PDO::FETCH_COLUMN);
return $a;
}
/**
* @todo implement
* @return null
*/
public function Execute($sql, $params=array())
{
return $this->connection->executeQuery($sql, $params);
}
/**
* @todo implement
* @return null
*/
public function Close()
{
return $this->connection->close();
}
/**
* @todo implement
* @return mixed
*/
public function quote($s)
{
return $this->qstr($s,get_magic_quotes_gpc());
}
/**
* @param $s
* @param bool $magic_quotes
* @return string
*/
public function qstr($s,$magic_quotes=false)
{
if (!$magic_quotes) {
if ($this->replaceQuote[0] == '\\'){
// only since php 4.0.5
$s = AdoDbDoctrineAdapter::adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
//$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s));
}
return "'".str_replace("'",$this->replaceQuote,$s)."'";
}
// undo magic quotes for "
$s = str_replace('\\"','"',$s);
if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) // ' already quoted, no need to change anything
return "'$s'";
else {// change \' to '' for sybase/mssql
$s = str_replace('\\\\','\\',$s);
return "'".str_replace("\\'",$this->replaceQuote,$s)."'";
}
}
/**
* @todo creemos que este NO es necesario
*/
public function ErrorMsg()
{
return null;
}
/**** A PARTIR DE ACA SE MUESTRA UNA REALIDAD HOSTIL Y FRIA QUE MUESTRA SU CRUEL VERDAD, O NO ****/
/**
Accepts $src and $dest arrays, replacing string $data
*/
public static function ADODB_str_replace($src, $dest, $data)
{
// PHP's version scheme makes converting to numbers difficult - workaround
$_adodb_ver = (float) PHP_VERSION;
if ($_adodb_ver >= 5.2) {
define('ADODB_PHPVER',0x5200);
} else if ($_adodb_ver >= 5.0) {
define('ADODB_PHPVER',0x5000);
} else
die("PHP5 or later required. You are running ".PHP_VERSION); // vintage
if (ADODB_PHPVER >= 0x4050) return str_replace($src,$dest,$data);
$s = reset($src);
$d = reset($dest);
while ($s !== false) {
$data = str_replace($s,$d,$data);
$s = next($src);
$d = next($dest);
}
return $data;
}
/**
Returns day of week, 0 = Sunday,... 6=Saturday.
Algorithm from PEAR::Date_Calc
*/
public static function adodb_dow($year, $month, $day)
{
/*
Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and
proclaimed that from that time onwards 3 days would be dropped from the calendar
every 400 years.
Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian).
*/
if ($year <= 1582) {
if ($year < 1582 ||
($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3;
else
$greg_correction = 0;
} else
$greg_correction = 0;
if($month > 2)
$month -= 2;
else {
$month += 10;
$year--;
}
$day = floor((13 * $month - 1) / 5) +
$day + ($year % 100) +
floor(($year % 100) / 4) +
floor(($year / 100) / 4) - 2 *
floor($year / 100) + 77 + $greg_correction;
return $day - 7 * floor($day / 7);
}
/**
Return formatted date based on timestamp $d
*/
public static function adodb_date($fmt,$d=false,$is_gmt=false)
{
static $daylight;
global $ADODB_DATETIME_CLASS;
if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
if (!defined('ADODB_TEST_DATES')) {
if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
}
}
$_day_power = 86400;
$arr = AdoDbDoctrineAdapter::_adodb_getdate($d,true,$is_gmt);
if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv');
if ($daylight) adodb_daylight_sv($arr, $is_gmt); //GALONSO: ESTA FUNCION NO LA ENCONTRE EN NINGUN LADO, SOLO EN UN COMMENT
$year = $arr['year'];
$month = $arr['mon'];
$day = $arr['mday'];
$hour = $arr['hours'];
$min = $arr['minutes'];
$secs = $arr['seconds'];
$max = strlen($fmt);
$dates = '';
$isphp5 = PHP_VERSION >= 5;
/*
at this point, we have the following integer vars to manipulate:
$year, $month, $day, $hour, $min, $secs
*/
for ($i=0; $i < $max; $i++) {
switch($fmt[$i]) {
case 'e':
$dates .= date('e');
break;
case 'T':
if ($ADODB_DATETIME_CLASS) {
$dt = new DateTime();
$dt->SetDate($year,$month,$day);
$dates .= $dt->Format('T');
} else
$dates .= date('T');
break;
// YEAR
case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
// 4.3.11 uses '04 Jun 2004'
// 4.3.8 uses ' 4 Jun 2004'
$dates .= gmdate('D',$_day_power*(3+AdoDbDoctrineAdapter::adodb_dow($year,$month,$day))).', '
. ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour;
if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min;
if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
$gmt = AdoDbDoctrineAdapter::adodb_get_gmt_diff($year,$month,$day);
$dates .= ' '.AdoDbDoctrineAdapter::adodb_tz_offset($gmt,$isphp5);
break;
case 'Y': $dates .= $year; break;
case 'y': $dates .= substr($year,strlen($year)-2,2); break;
// MONTH
case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
case 'Q': $dates .= ($month+3)>>2; break;
case 'n': $dates .= $month; break;
case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
// DAY
case 't': $dates .= $arr['ndays']; break;
case 'z': $dates .= $arr['yday']; break;
case 'w': $dates .= AdoDbDoctrineAdapter::adodb_dow($year,$month,$day); break;
case 'l': $dates .= gmdate('l',$_day_power*(3+AdoDbDoctrineAdapter::adodb_dow($year,$month,$day))); break;
case 'D': $dates .= gmdate('D',$_day_power*(3+AdoDbDoctrineAdapter::adodb_dow($year,$month,$day))); break;
case 'j': $dates .= $day; break;
case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
case 'S':
$d10 = $day % 10;
if ($d10 == 1) $dates .= 'st';
else if ($d10 == 2 && $day != 12) $dates .= 'nd';
else if ($d10 == 3) $dates .= 'rd';
else $dates .= 'th';
break;
// HOUR
case 'Z':
$dates .= ($is_gmt) ? 0 : -AdoDbDoctrineAdapter::adodb_get_gmt_diff($year,$month,$day); break;
case 'O':
$gmt = ($is_gmt) ? 0 : AdoDbDoctrineAdapter::adodb_get_gmt_diff($year,$month,$day);
$dates .= AdoDbDoctrineAdapter::adodb_tz_offset($gmt,$isphp5);
break;
case 'H':
if ($hour < 10) $dates .= '0'.$hour;
else $dates .= $hour;
break;
case 'h':
if ($hour > 12) $hh = $hour - 12;
else {
if ($hour == 0) $hh = '12';
else $hh = $hour;
}
if ($hh < 10) $dates .= '0'.$hh;
else $dates .= $hh;
break;
case 'G':
$dates .= $hour;
break;
case 'g':
if ($hour > 12) $hh = $hour - 12;
else {
if ($hour == 0) $hh = '12';
else $hh = $hour;
}
$dates .= $hh;
break;
// MINUTES
case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break;
// SECONDS
case 'U': $dates .= $d; break;
case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break;
// AM/PM
// Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
case 'a':
if ($hour>=12) $dates .= 'pm';
else $dates .= 'am';
break;
case 'A':
if ($hour>=12) $dates .= 'PM';
else $dates .= 'AM';
break;
default:
$dates .= $fmt[$i]; break;
// ESCAPE
case "\\":
$i++;
if ($i < $max) $dates .= $fmt[$i];
break;
}
}
return $dates;
}
public static function adodb_tz_offset($gmt,$isphp5)
{
$zhrs = abs($gmt)/3600;
$hrs = floor($zhrs);
if ($isphp5)
return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
else
return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
}
static function UnixDate($v)
{
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
if (is_object($v)) {
// odbtp support
//( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 )
return AdoDbDoctrineAdapter::adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year);
}
if (is_numeric($v) && strlen($v) !== 8) return $v;
if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|",
($v), $rr)) return false;
if ($rr[1] <= TIMESTAMP_FIRST_YEAR) return 0;
// h-m-s-MM-DD-YY
return @AdoDbDoctrineAdapter::adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
}
public static function adodb_get_gmt_diff($y,$m,$d)
{
static $TZ,$tzo;
//global $ADODB_DATETIME_CLASS;
$ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2);
if (!defined('ADODB_TEST_DATES')) $y = false;
else if ($y < 1970 || $y >= 2038) $y = false;
if ($ADODB_DATETIME_CLASS && $y !== false) {
$dt = new DateTime();
$dt->setISODate($y,$m,$d);
if (empty($tzo)) {
$tzo = new DateTimeZone(date_default_timezone_get());
# $tzt = timezone_transitions_get( $tzo );
}
return -$tzo->getOffset($dt);
} else {
if (isset($TZ)) return $TZ;
$y = date('Y');
$TZ = mktime(0,0,0,12,2,$y,0) - gmmktime(0,0,0,12,2,$y,0);
}
return $TZ;
}
/**
Fix 2-digit years. Works for any century.
Assumes that if 2-digit is more than 30 years in future, then previous century.
*/
public static function adodb_year_digit_check($y)
{
if ($y < 100) {
$yr = (integer) date("Y");
$century = (integer) ($yr /100);
if ($yr%100 > 50) {
$c1 = $century + 1;
$c0 = $century;
} else {
$c1 = $century;
$c0 = $century - 1;
}
$c1 *= 100;
// if 2-digit year is less than 30 years in future, set it to this century
// otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
if (($y + $c1) < $yr+30) $y = $y + $c1;
else $y = $y + $c0*100;
}
return $y;
}
public static function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false)
{
if (!defined('ADODB_TEST_DATES')) {
if ($mon === false) {
return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec);
}
// for windows, we don't check 1970 because with timezone differences,
// 1 Jan 1970 could generate negative timestamp, which is illegal
$usephpfns = (1970 < $year && $year < 2038
|| !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
);
if ($usephpfns && ($year + $mon/12+$day/365.25+$hr/(24*365.25) >= 2038)) $usephpfns = false;
if ($usephpfns) {
return $is_gmt ?
@gmmktime($hr,$min,$sec,$mon,$day,$year):
@mktime($hr,$min,$sec,$mon,$day,$year);
}
}
$gmt_different = ($is_gmt) ? 0 : AdoDbDoctrineAdapter::adodb_get_gmt_diff($year,$mon,$day);
/*
# disabled because some people place large values in $sec.
# however we need it for $mon because we use an array...
$hr = intval($hr);
$min = intval($min);
$sec = intval($sec);
*/
$mon = intval($mon);
$day = intval($day);
$year = intval($year);
$year = AdoDbDoctrineAdapter::adodb_year_digit_check($year);
if ($mon > 12) {
$y = floor(($mon-1)/ 12);
$year += $y;
$mon -= $y*12;
} else if ($mon < 1) {
$y = ceil((1-$mon) / 12);
$year -= $y;
$mon += $y*12;
}
$_day_power = 86400;
$_hour_power = 3600;
$_min_power = 60;
$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
$_total_date = 0;
if ($year >= 1970) {
for ($a = 1970 ; $a <= $year; $a++) {
$leaf = AdoDbDoctrineAdapter::_adodb_is_leap_year($a);
if ($leaf == true) {
$loop_table = $_month_table_leaf;
$_add_date = 366;
} else {
$loop_table = $_month_table_normal;
$_add_date = 365;
}
if ($a < $year) {
$_total_date += $_add_date;
} else {
for($b=1;$b<$mon;$b++) {
$_total_date += $loop_table[$b];
}
}
}
$_total_date +=$day-1;
$ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different;
} else {
for ($a = 1969 ; $a >= $year; $a--) {
$leaf = AdoDbDoctrineAdapter::_adodb_is_leap_year($a);
if ($leaf == true) {
$loop_table = $_month_table_leaf;
$_add_date = 366;
} else {
$loop_table = $_month_table_normal;
$_add_date = 365;
}
if ($a > $year) { $_total_date += $_add_date;
} else {
for($b=12;$b>$mon;$b--) {
$_total_date += $loop_table[$b];
}
}
}
$_total_date += $loop_table[$mon] - $day;
$_day_time = $hr * $_hour_power + $min * $_min_power + $sec;
$_day_time = $_day_power - $_day_time;
$ret = -( $_total_date * $_day_power + $_day_time - $gmt_different);
if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction
else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582.
}
//print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret;
return $ret;
}
/**
Checks for leap year, returns true if it is. No 2-digit year check. Also
handles julian calendar correctly.
*/
public static function _adodb_is_leap_year($year)
{
if ($year % 4 != 0) return false;
if ($year % 400 == 0) {
return true;
// if gregorian calendar (>1582), century not-divisible by 400 is not leap
} else if ($year > 1582 && $year % 100 == 0 ) {
return false;
}
return true;
}
public static function UnixTimeStamp($v)
{
if (is_object($v)) {
// odbtp support
//( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 )
return AdoDbDoctrineAdapter::adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year);
}
if (!preg_match(
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
($v), $rr)) return false;
if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) return 0;
// h-m-s-MM-DD-YY
if (!isset($rr[5])) return AdoDbDoctrineAdapter::adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
return @AdoDbDoctrineAdapter::adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]);
}
public static function adodb_get_gmt_diff_ts($ts)
{
if (0 <= $ts && $ts <= 0x7FFFFFFF) { // check if number in 32-bit signed range) {
$arr = getdate($ts);
$y = $arr['year'];
$m = $arr['mon'];
$d = $arr['mday'];
return AdoDbDoctrineAdapter::adodb_get_gmt_diff($y,$m,$d);
} else {
return AdoDbDoctrineAdapter::adodb_get_gmt_diff(false,false,false);
}
}
public static function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
{
static $YRS;
global $_month_table_normal,$_month_table_leaf;
$d = $origd - ($is_gmt ? 0 : AdoDbDoctrineAdapter::adodb_get_gmt_diff_ts($origd));
$_day_power = 86400;
$_hour_power = 3600;
$_min_power = 60;
if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction
$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
$d366 = $_day_power * 366;
$d365 = $_day_power * 365;
if ($d < 0) {
if (empty($YRS)) $YRS = array(
1970 => 0,
1960 => -315619200,
1950 => -631152000,
1940 => -946771200,
1930 => -1262304000,
1920 => -1577923200,
1910 => -1893456000,
1900 => -2208988800,
1890 => -2524521600,
1880 => -2840140800,
1870 => -3155673600,
1860 => -3471292800,
1850 => -3786825600,
1840 => -4102444800,
1830 => -4417977600,
1820 => -4733596800,
1810 => -5049129600,
1800 => -5364662400,
1790 => -5680195200,
1780 => -5995814400,
1770 => -6311347200,
1760 => -6626966400,
1750 => -6942499200,
1740 => -7258118400,
1730 => -7573651200,
1720 => -7889270400,
1710 => -8204803200,
1700 => -8520336000,
1690 => -8835868800,
1680 => -9151488000,
1670 => -9467020800,
1660 => -9782640000,
1650 => -10098172800,
1640 => -10413792000,
1630 => -10729324800,
1620 => -11044944000,
1610 => -11360476800,
1600 => -11676096000);
if ($is_gmt) $origd = $d;
// The valid range of a 32bit signed timestamp is typically from
// Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT
//
# old algorithm iterates through all years. new algorithm does it in
# 10 year blocks
/*
# old algo
for ($a = 1970 ; --$a >= 0;) {
$lastd = $d;
if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
else $d += $d365;
if ($d >= 0) {
$year = $a;
break;
}
}
*/
$lastsecs = 0;
$lastyear = 1970;
foreach($YRS as $year => $secs) {
if ($d >= $secs) {
$a = $lastyear;
break;
}
$lastsecs = $secs;
$lastyear = $year;
}
$d -= $lastsecs;
if (!isset($a)) $a = $lastyear;
//echo ' yr=',$a,' ', $d,'.';
for (; --$a >= 0;) {
$lastd = $d;
if ($leaf = AdoDbDoctrineAdapter::_adodb_is_leap_year($a)) $d += $d366;
else $d += $d365;
if ($d >= 0) {
$year = $a;
break;
}
}
/**/
$secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd;
$d = $lastd;
$mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
for ($a = 13 ; --$a > 0;) {
$lastd = $d;
$d += $mtab[$a] * $_day_power;
if ($d >= 0) {
$month = $a;
$ndays = $mtab[$a];
break;
}
}
$d = $lastd;
$day = $ndays + ceil(($d+1) / ($_day_power));
$d += ($ndays - $day+1)* $_day_power;
$hour = floor($d/$_hour_power);
} else {
for ($a = 1970 ;; $a++) {
$lastd = $d;
if ($leaf = AdoDbDoctrineAdapter::_adodb_is_leap_year($a)) $d -= $d366;
else $d -= $d365;
if ($d < 0) {
$year = $a;
break;
}
}
$secsInYear = $lastd;
$d = $lastd;
$mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
for ($a = 1 ; $a <= 12; $a++) {
$lastd = $d;
$d -= $mtab[$a] * $_day_power;
if ($d < 0) {
$month = $a;
$ndays = $mtab[$a];
break;
}
}
$d = $lastd;
$day = ceil(($d+1) / $_day_power);
$d = $d - ($day-1) * $_day_power;
$hour = floor($d /$_hour_power);
}
$d -= $hour * $_hour_power;
$min = floor($d/$_min_power);
$secs = $d - $min * $_min_power;
if ($fast) {
return array(
'seconds' => $secs,
'minutes' => $min,
'hours' => $hour,
'mday' => $day,
'mon' => $month,
'year' => $year,
'yday' => floor($secsInYear/$_day_power),
'leap' => $leaf,
'ndays' => $ndays
);
}
$dow = AdoDbDoctrineAdapter::adodb_dow($year,$month,$day);
return array(
'seconds' => $secs,
'minutes' => $min,
'hours' => $hour,
'mday' => $day,
'wday' => $dow,
'mon' => $month,
'year' => $year,
'yday' => floor($secsInYear/$_day_power),
'weekday' => gmdate('l',$_day_power*(3+$dow)),
'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
0 => $origd
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment