Last active
January 24, 2024 00:29
-
-
Save g-alonso/8b679d47e5713c13e1d4b2b26c7c8dcf to your computer and use it in GitHub Desktop.
PHP AdoDb Doctrine Adapter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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