Seite 1 von 1

[CON-413] Item->loadBy findet Eintrag in der DB nicht

Verfasst: Do 9. Jun 2011, 14:08
von Oldperl
In der Klasse Item der genericdb (contenido/classes/class.genericdb.php) kann man über die Funktion loadBy() einen Datensatz über eine Abfrage zu jedem beliebigen DB-Feld der Tabelle erhalten. Dieses funktioniert aber nur, wenn der Inhalt des Feldes eindeutig ist.

Versucht man nun aber über diese Funktion eine Datensatz zu laden der ein Textfeld mit Sonderzeichen/Leerzeiche/etc. enthält, beispielsweise eine Emailadresse, so bekommt man, auch wenn ein Eintrag vorhanden ist, keinen Datensatz zurück.
Der Grund ist, daß beim Eintragen (Speichern) über die Itemklasse normalerweise solche Felder über verschiedene Filterfunktionen "db-tauglich" gemacht (bereinigt) werden. Die Funktion loadBy() fragt aber direkt mit dem angegebenen Feldwert in der DB an, ohne diesen zu bereinigen. Somit kann es vorkommen das die Werte nicht gleich sind und ein leeres Resultat zur Folge haben.

Um diesen Bug zu beheben einfach die Funktion

Code: Alles auswählen

	/**
	 * loadBy ($field, $value)
	 * Loads an item by ID from the database
	 * @param string $field Specifies the field
	 * @param string $value Specifies the value
	 * @return bool True if the load was successful
	 */
	function loadBy($field, $value)
	{

		/* SQL-Statement to select by field */
		$sql = "SELECT * FROM ".$this->table." WHERE ".$field." = '".$value."'";

		/* Query the database */
		$this->db->query($sql);

		$this->_lastSQL = $sql;

		if ($this->db->num_rows() > 1)
		{
			cWarning(__FILE__, __LINE__, "Tried to load a single line with field $field and value $value from ".$this->table." but found more than one row");
		}

		/* Advance to the next record, return false if nothing found */
		if (!$this->db->next_record())
		{
			return false;
		}

		$this->values = $this->db->copyResultToArray($this->table);
		$this->oldPrimaryKey = $this->values[$this->primaryKey];
		$this->virgin = false;
		return true;
	}
gegen diese

Code: Alles auswählen

/**
 * Loads an item by column/field from the database
 * throws an error if fieldvalue is not unique (>1) in db
 *
 * @param string $field Specifies the field
 * @param string $value Specifies the value
 * @param boolean $bSafe use inFilter or not
 * @return bool True if the load was successfull
*/
function loadBy($field, $value, $bSafe = true) {

    if($bSafe) $value = $this->_inFilter ($value);

    /* SQL-Statement to select by field */
    $sql = "SELECT * FROM ".$this->table." WHERE ".$field." = '".$value."'";

    /* Query the database */
    $this->db->query($sql);

    $this->_lastSQL = $sql;

    if ($this->db->num_rows() > 1) {
        cWarning(__FILE__, __LINE__, "Tried to load a single line with field $field and value $value from ".$this->table." but found more than one row");
    }

    /* Advance to the next record, return false if nothing found */
    if (!$this->db->next_record()) {
        return false;
    }

    $this->values = $this->db->copyResultToArray($this->table);
    $this->oldPrimaryKey = $this->values[$this->primaryKey];
    $this->virgin = false;
    return true;
}
austauschen.

Wie schon bei setField() wird nun auch standardmäßig der inFilter genutzt, kann aber über den optionalen Parameter $bSafe abgeschaltet werden.

Gruß aus Franken

Ortwin

Re: [CON-413] Item->loadBy findet Eintrag in der DB nicht

Verfasst: Fr 23. Sep 2011, 18:20
von xmurrix
Item::loadBy() wurde um den 3. parameter erweitert.