diff --git a/libraries/adodb_vtigerfix/adodb-errorhandler.inc.php b/libraries/adodb_vtigerfix/adodb-errorhandler.inc.php
index 0cd3f218b4ba37b216e124e035e1a69705357539..1d3b9e9e52122e5323ae3931ead4092bcec02c90 100644
--- a/libraries/adodb_vtigerfix/adodb-errorhandler.inc.php
+++ b/libraries/adodb_vtigerfix/adodb-errorhandler.inc.php
@@ -37,7 +37,14 @@ if (!defined('ADODB_ERROR_HANDLER')) define('ADODB_ERROR_HANDLER','ADODB_Error_H
 */
 function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection)
 {
-	if (error_reporting() == 0) return; // obey @ protocol
+	// Do not throw if errors are suppressed by @ operator
+	// error_reporting() value for suppressed errors changed in PHP 8.0.0
+	$suppressed = version_compare(PHP_VERSION, '8.0.0', '<')
+		? 0
+		: E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE;
+	if (error_reporting() == $suppressed) {
+		return;
+	}
 	switch($fn) {
 	case 'EXECUTE':
 		$sql = $p1;
diff --git a/libraries/adodb_vtigerfix/adodb-errorpear.inc.php b/libraries/adodb_vtigerfix/adodb-errorpear.inc.php
index 2bb15947e89d03ca16e7e8a58a46f95707230050..7b173da84fd8133d7e31ffe76715406082fc7056 100644
--- a/libraries/adodb_vtigerfix/adodb-errorpear.inc.php
+++ b/libraries/adodb_vtigerfix/adodb-errorpear.inc.php
@@ -52,7 +52,15 @@ function ADODB_Error_PEAR($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false)
 {
 global $ADODB_Last_PEAR_Error;
 
-	if (error_reporting() == 0) return; // obey @ protocol
+	// Do not throw if errors are suppressed by @ operator
+	// error_reporting() value for suppressed errors changed in PHP 8.0.0
+	$suppressed = version_compare(PHP_VERSION, '8.0.0', '<')
+		? 0
+		: E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE;
+	if (error_reporting() == $suppressed) {
+		return;
+	}
+
 	switch($fn) {
 	case 'EXECUTE':
 		$sql = $p1;
diff --git a/libraries/adodb_vtigerfix/adodb-exceptions.inc.php b/libraries/adodb_vtigerfix/adodb-exceptions.inc.php
index 9f1176f0f6936470aa953979fc7754a2c4e362b5..e4fae817e73a26f1accd2f55ca0fe1c3d2ebe67f 100644
--- a/libraries/adodb_vtigerfix/adodb-exceptions.inc.php
+++ b/libraries/adodb_vtigerfix/adodb-exceptions.inc.php
@@ -30,6 +30,9 @@ var $params = '';
 var $host = '';
 var $database = '';
 
+	/** @var string A message text. */
+	var $msg = '';
+
 	function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
 	{
 		switch($fn) {
@@ -45,6 +48,9 @@ var $database = '';
 			$s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)";
 			break;
 		default:
+			//Prevent PHP warning if $p1 or $p2 are arrays.
+			$p1 = ( is_array($p1) ) ? 'Array' : $p1;
+			$p2 = ( is_array($p2) ) ? 'Array' : $p2;
 			$s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)";
 			break;
 		}
@@ -75,10 +81,18 @@ var $database = '';
 
 function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
 {
-global $ADODB_EXCEPTION;
+	global $ADODB_EXCEPTION;
+
+	// Do not throw if errors are suppressed by @ operator
+	// error_reporting() value for suppressed errors changed in PHP 8.0.0
+	$suppressed = version_compare(PHP_VERSION, '8.0.0', '<')
+		? 0
+		: E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE;
+	if (error_reporting() == $suppressed) {
+		return;
+	}
+
+	$errfn = is_string($ADODB_EXCEPTION) ? $ADODB_EXCEPTION : 'ADODB_EXCEPTION';
 
-	if (error_reporting() == 0) return; // obey @ protocol
-	if (is_string($ADODB_EXCEPTION)) $errfn = $ADODB_EXCEPTION;
-	else $errfn = 'ADODB_EXCEPTION';
 	throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
 }
diff --git a/libraries/adodb_vtigerfix/adodb-xmlschema.inc.php b/libraries/adodb_vtigerfix/adodb-xmlschema.inc.php
index c01212aebd4cf26b9fe10ef6a4aae47124c2038b..604fa45089544a9ba5b6e32b51bbd625906242cc 100644
--- a/libraries/adodb_vtigerfix/adodb-xmlschema.inc.php
+++ b/libraries/adodb_vtigerfix/adodb-xmlschema.inc.php
@@ -928,7 +928,8 @@ class dbData extends dbObject {
 			foreach( $row as $field_id => $field_data ) {
 				if( !array_key_exists( $field_id, $table_fields ) ) {
 					if( is_numeric( $field_id ) ) {
-						$field_id = reset( array_keys( $table_fields ) );
+						$keys = array_keys($table_fields);
+						$field_id = reset($keys);
 					} else {
 						continue;
 					}
diff --git a/libraries/adodb_vtigerfix/adodb-xmlschema03.inc.php b/libraries/adodb_vtigerfix/adodb-xmlschema03.inc.php
index de1ea26c7d6727298df1a58aa28bb33cf15b9b55..aadcaf1e8985c964f8a991cc66c144e2674b9d0c 100644
--- a/libraries/adodb_vtigerfix/adodb-xmlschema03.inc.php
+++ b/libraries/adodb_vtigerfix/adodb-xmlschema03.inc.php
@@ -976,7 +976,8 @@ class dbData extends dbObject {
 			foreach( $row as $field_id => $field_data ) {
 				if( !array_key_exists( $field_id, $table_fields ) ) {
 					if( is_numeric( $field_id ) ) {
-						$field_id = reset( array_keys( $table_fields ) );
+						$keys = array_keys($table_fields);
+						$field_id = reset($keys);
 					} else {
 						continue;
 					}
diff --git a/libraries/adodb_vtigerfix/adodb.inc.php b/libraries/adodb_vtigerfix/adodb.inc.php
index f15158f94f3498e66659bbeded34e11758a4ff2e..e3ae2e056c83e746ec6de46324db726da1645bbe 100644
--- a/libraries/adodb_vtigerfix/adodb.inc.php
+++ b/libraries/adodb_vtigerfix/adodb.inc.php
@@ -221,22 +221,62 @@ if (!defined('_ADODB_LAYER')) {
 	// CLASS ADOFieldObject
 	//==============================================================================================
 	/**
-	 * Helper class for FetchFields -- holds info on a column
+	 * Helper class for FetchFields -- holds info on a column.
+	 *
+	 * Note: Dynamic properties are required here, as some drivers may require
+	 * the object to hold database-specific field metadata.
 	 */
+	#[\AllowDynamicProperties]
 	class ADOFieldObject {
-		var $name = '';
-		var $max_length=0;
-		var $type="";
-/*
-		// additional fields by dannym... (danny_milo@yahoo.com)
-		var $not_null = false;
-		// actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^
-		// so we can as well make not_null standard (leaving it at "false" does not harm anyways)
-
-		var $has_default = false; // this one I have done only in mysql and postgres for now ...
-			// others to come (dannym)
-		var $default_value; // default, if any, and supported. Check has_default first.
-*/
+		/**
+		 * @var string Field name
+		 */
+		public $name = '';
+
+		/**
+		 * @var int Field size
+		 */
+		public $max_length = 0;
+
+		/**
+		 * @var string Field type.
+		 */
+		public $type = '';
+
+		/**
+		 * @var int|null Numeric field scale.
+		 */
+		public $scale;
+
+		/**
+		 * @var bool True if field can be NULL
+		 */
+		public $not_null = false;
+
+		/**
+		 * @var bool True if field is a primary key
+		 */
+		public $primary_key = false;
+
+		/**
+		 * @var bool True if field is unique key
+		 */
+		public $unique = false;
+
+		/**
+		 * @var bool True if field is automatically incremented
+		 */
+		public $auto_increment = false;
+
+		/**
+		 * @var bool True if field has a default value
+		 */
+		public $has_default = false;
+
+		/**
+		 * @var mixed Default value, if any and supported; check {@see $has_default} first.
+		 */
+		public $default_value;
 	}
 
 
@@ -1672,17 +1712,19 @@ if (!defined('_ADODB_LAYER')) {
 		// 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS.
 		global $ADODB_COUNTRECS;
 
-		$savec = $ADODB_COUNTRECS;
-		$ADODB_COUNTRECS = false;
+		try {
+			$savec = $ADODB_COUNTRECS;
+			$ADODB_COUNTRECS = false;
 
-
-		if ($secs2cache != 0) {
-			$rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
-		} else {
-			$rs = $this->Execute($sql,$inputarr);
+			if ($secs2cache != 0) {
+				$rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
+			} else {
+				$rs = $this->Execute($sql, $inputarr);
+			}
+		} finally {
+			$ADODB_COUNTRECS = $savec;
 		}
 
-		$ADODB_COUNTRECS = $savec;
 		if ($rs && !$rs->EOF) {
 			$rs = $this->_rs2rs($rs,$nrows,$offset);
 		}
@@ -1829,11 +1871,16 @@ if (!defined('_ADODB_LAYER')) {
 	public function GetOne($sql, $inputarr=false) {
 		global $ADODB_COUNTRECS,$ADODB_GETONE_EOF;
 
-		$crecs = $ADODB_COUNTRECS;
-		$ADODB_COUNTRECS = false;
+		$rs = null;
+		try {
+			$crecs = $ADODB_COUNTRECS;
+			$ADODB_COUNTRECS = false;
+			$rs = $this->Execute($sql, $inputarr);
+		} finally {
+			$ADODB_COUNTRECS = $crecs;
+		}
 
 		$ret = false;
-		$rs = $this->Execute($sql,$inputarr);
 		if ($rs) {
 			if ($rs->EOF) {
 				$ret = $ADODB_GETONE_EOF;
@@ -1843,7 +1890,6 @@ if (!defined('_ADODB_LAYER')) {
 
 			$rs->Close();
 		}
-		$ADODB_COUNTRECS = $crecs;
 		return $ret;
 	}
 
@@ -1972,10 +2018,15 @@ if (!defined('_ADODB_LAYER')) {
 	function GetArray($sql,$inputarr=false) {
 		global $ADODB_COUNTRECS;
 
-		$savec = $ADODB_COUNTRECS;
-		$ADODB_COUNTRECS = false;
-		$rs = $this->Execute($sql,$inputarr);
-		$ADODB_COUNTRECS = $savec;
+		$rs = null;
+		try {
+			$savec = $ADODB_COUNTRECS;
+			$ADODB_COUNTRECS = false;
+			$rs = $this->Execute($sql, $inputarr);
+		} finally {
+			$ADODB_COUNTRECS = $savec;
+		}
+
 		if (!$rs)
 			if (defined('ADODB_PEAR')) {
 				return ADODB_PEAR_Error();
@@ -1994,10 +2045,14 @@ if (!defined('_ADODB_LAYER')) {
 	function CacheGetArray($secs2cache,$sql=false,$inputarr=false) {
 		global $ADODB_COUNTRECS;
 
-		$savec = $ADODB_COUNTRECS;
-		$ADODB_COUNTRECS = false;
-		$rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
-		$ADODB_COUNTRECS = $savec;
+		$rs = null;
+		try {
+			$savec = $ADODB_COUNTRECS;
+			$ADODB_COUNTRECS = false;
+			$rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
+		} finally {
+			$ADODB_COUNTRECS = $savec;
+		}
 
 		if (!$rs)
 			if (defined('ADODB_PEAR')) {
@@ -2028,12 +2083,15 @@ if (!defined('_ADODB_LAYER')) {
 	function GetRow($sql,$inputarr=false) {
 		global $ADODB_COUNTRECS;
 
-		$crecs = $ADODB_COUNTRECS;
-		$ADODB_COUNTRECS = false;
-
-		$rs = $this->Execute($sql,$inputarr);
+		$rs = null;
+		try {
+			$crecs = $ADODB_COUNTRECS;
+			$ADODB_COUNTRECS = false;
+			$rs = $this->Execute($sql, $inputarr);
+		} finally {
+			$ADODB_COUNTRECS = $crecs;
+		}
 
-		$ADODB_COUNTRECS = $crecs;
 		if ($rs) {
 			if (!$rs->EOF) {
 				$arr = $rs->fields;
@@ -3405,22 +3463,59 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 
 } // end class ADOConnection
 
+	/**
+	 * RecordSet fields data as object.
+	 *
+	 * @see ADORecordSet::fetchObj(), ADORecordSet::fetchObject(),
+	 * @see ADORecordSet::fetchNextObj(), ADORecordSet::fetchNextObject()
+	 */
+	class ADOFetchObj {
+		/** @var array The RecordSet's fields */
+		protected $data;
 
+		/**
+		 * Constructor.
+		 *
+		 * @param array $fields Associative array with RecordSet's fields (name => value)
+		 */
+		public function __construct(array $fields = [])
+		{
+			$this->data = $fields;
+		}
 
-	//==============================================================================================
-	// CLASS ADOFetchObj
-	//==============================================================================================
+		public function __set(string $name, $value)
+		{
+			$this->data[$name] = $value;
+		}
 
-	/**
-	* Internal placeholder for record objects. Used by ADORecordSet->FetchObj().
-	*/
-	class ADOFetchObj {
-	};
+		public function __get(string $name)
+		{
+			if (isset($this->data[$name])) {
+				return $this->data[$name];
+			}
+			ADOConnection::outp("Unknown field: $name");
+			return null;
+		}
 
-	//==============================================================================================
-	// CLASS ADORecordSet_empty
-	//==============================================================================================
+		public function __isset($name)
+		{
+			return isset($this->data[$name]);
+		}
 
+		public function __debugInfo()
+		{
+			return $this->data;
+		}
+
+		public static function __set_state(array $data)
+		{
+			return new self($data['data']);
+		}
+	}
+
+	/**
+	 * Class ADODB_Iterator_empty
+	 */
 	class ADODB_Iterator_empty implements Iterator {
 
 		private $rs;
@@ -3429,26 +3524,32 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 			$this->rs = $rs;
 		}
 
+		#[\ReturnTypeWillChange]
 		function rewind() {}
 
+		#[\ReturnTypeWillChange]
 		function valid() {
 			return !$this->rs->EOF;
 		}
 
+		#[\ReturnTypeWillChange]
 		function key() {
 			return false;
 		}
 
+		#[\ReturnTypeWillChange]
 		function current() {
 			return false;
 		}
 
+		#[\ReturnTypeWillChange]
 		function next() {}
 
 		function __call($func, $params) {
 			return call_user_func_array(array($this->rs, $func), $params);
 		}
 
+		#[\ReturnTypeWillChange]
 		function hasMore() {
 			return false;
 		}
@@ -3495,6 +3596,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 
 		function Init() {}
 
+		#[\ReturnTypeWillChange]
 		function getIterator() {
 			return new ADODB_Iterator_empty($this);
 		}
@@ -3555,22 +3657,27 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 			$this->rs = $rs;
 		}
 
+		#[\ReturnTypeWillChange]
 		function rewind() {
 			$this->rs->MoveFirst();
 		}
 
+		#[\ReturnTypeWillChange]
 		function valid() {
 			return !$this->rs->EOF;
 		}
 
+		#[\ReturnTypeWillChange]
 		function key() {
 			return $this->rs->_currentRow;
 		}
 
+		#[\ReturnTypeWillChange]
 		function current() {
 			return $this->rs->fields;
 		}
 
+		#[\ReturnTypeWillChange]
 		function next() {
 			$this->rs->MoveNext();
 		}
@@ -3655,6 +3762,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 		$this->Close();
 	}
 
+	#[\ReturnTypeWillChange]
 	function getIterator() {
 		return new ADODB_Iterator($this);
 	}