/**
  * Class constructor
  */
 public final function _construct(B2DBRow $row, $foreign_key = null)
 {
     if ($this->_version != $row->get(TBGModulesTable::VERSION)) {
         throw new Exception('This module must be upgraded to the latest version');
     }
 }
 protected function _populatePropertiesFromB2DBRow(B2DBRow $row, $traverse = true, $foreign_key = null)
 {
     TBGLogging::log('Populating ' . get_class($this) . ' with id ' . $this->_id, 'B2DB');
     $id_column = $this->getB2DBTable()->getIdColumn();
     foreach ($this->getB2DBTable()->getColumns() as $column) {
         if ($column['name'] == $this->getB2DBTable()->getIdColumn()) {
             continue;
         }
         $property_name = $this->_getColumnProperty($column['name']);
         $property_type = $column['type'];
         if (!property_exists($this, $property_name)) {
             throw new Exception("Could not find class property {$property_name} in class " . get_class($this) . ". The class must have all properties from the corresponding B2DB table class available");
         }
         if ($traverse && in_array($column['name'], $this->getB2DBTable()->getForeignColumns())) {
             if ($row->get($column['name']) > 0) {
                 $type_name = $this->_getForeignClassForProperty($property_name);
                 if ($type_name && class_exists($type_name)) {
                     $b2dbtablename = $type_name::$_b2dbtablename;
                     $b2dbtable = $b2dbtablename::getTable();
                     foreach ($row->getJoinedTables() as $join_details) {
                         if ($join_details['original_column'] == $column['name']) {
                             $property_type = 'class';
                             break;
                         }
                     }
                 }
             }
         }
         switch ($property_type) {
             case 'class':
                 $value = (int) $row->get($column['name']);
                 TBGLogging::log('Populating foreign object of type ' . $type_name . ' with value ' . $value . ' for property ' . $property_name, 'B2DB');
                 //if (!$row->get($column))
                 $this->{$property_name} = new $type_name($value, $row, false, $column['name']);
                 break;
             case 'boolean':
                 $this->{$property_name} = (bool) $row->get($column['name'], $foreign_key);
                 break;
             case 'integer':
                 $this->{$property_name} = (int) $row->get($column['name'], $foreign_key);
                 break;
             case 'float':
                 $this->{$property_name} = floatval($row->get($column['name'], $foreign_key));
                 break;
             case 'text':
             case 'varchar':
                 $this->{$property_name} = (string) $row->get($column['name'], $foreign_key);
                 break;
             default:
                 $this->{$property_name} = $row->get($column['name'], $foreign_key);
         }
     }
     TBGLogging::log('Done populating ' . get_class($this) . ' with id ' . $this->_id, 'B2DB');
 }