_inFilter($mValue); } if ($sField === $this->primaryKey) { $aRecordSet = self::$_oCache->getItem($this->table . "_" . $mValue); } else { $aRecordSet = self::$_oCache->getItemByProperty($this->table . "_" . $sField, $mValue); } if ($aRecordSet) { // entry in cache found, load entry from cache $this->loadByRecordSet($aRecordSet); return true; } // SQL-Statement to select by field $sql = sprintf("SELECT * FROM `%s` WHERE %s = '%s'", $this->table, $sField, $mValue); //$sql = $this->db->prepare($sql, $this->table, $sField, $mValue); // Query the database $this->db->query($sql); $this->_lastSQL = $sql; if ($this->db->num_rows() > 1) { $sMsg = "Tried to load a single line with field $sField and value $mValue from " . $this->table . " but found more than one row"; cWarning(__FILE__, __LINE__, $sMsg); } // Advance to the next record, return false if nothing found if (!$this->db->next_record()) { return false; } $this->loadByRecordSet($this->db->toArray()); return true; } /** * Loads an item by passed where clause from the database. * This function is expensive, since it executes allways a query to the database * to retrieve the primary key, even if the record set is aleady cached. * NOTE: Passed value has to be escaped before. This will not be done by this function. * * @param string $sWhere The where clause like 'idart = 123 AND idlang = 1' * @return bool True if the load was successful */ protected function _loadByWhereClause($sWhere) { // SQL-Statement to select by whee clause $sql = sprintf("SELECT %s AS pk FROM `%s` WHERE ", $this->primaryKey, $this->table) . $sWhere; //$sql = $this->db->prepare($sql, $this->primaryKey, $this->table); // Query the database $this->db->query($sql); $this->_lastSQL = $sql; if ($this->db->num_rows() > 1) { $sMsg = "Tried to load a single line with where clause '" . $sWhere . "' from " . $this->table . " but found more than one row"; cWarning(__FILE__, __LINE__, $sMsg); } // Advance to the next record, return false if nothing found if (!$this->db->next_record()) { return false; } $id = $this->db->f('pk'); return $this->loadByPrimaryKey($id); } /** * Loads an item by ID from the database. * * @param string $mValue Specifies the primary key value * @return bool True if the load was successful */ public function loadByPrimaryKey($mValue) { $bSuccess = $this->loadBy($this->primaryKey, $mValue); if (($bSuccess == true) && method_exists($this, '_onLoad')) { $this->_onLoad(); } return $bSuccess; } /** * Loads an item by it's recordset. * * @param array $aRecordSet The recordset of the item */ public function loadByRecordSet(array $aRecordSet) { $this->values = $aRecordSet; $this->oldPrimaryKey = $this->values[$this->primaryKey]; $this->virgin = false; self::$_oCache->addItem($this->table . "_" . $this->oldPrimaryKey, $this->values); } /** * Checks if a the item is already loaded. * @return boolean */ public function isLoaded() { return !$this->virgin; } /** * Function which is called whenever an item is loaded. * Inherited classes should override this function if desired. * * @return void */ protected function _onLoad() { } /** * Gets the value of a specific field. * * @param string $sField Specifies the field to retrieve * @return mixed Value of the field */ public function getField($sField) { if ($this->virgin == true) { $this->lasterror = 'No item loaded'; return false; } return $this->_outFilter($this->values[$sField]); } /** * Wrapper for getField (less to type). * * @param string $sField Specifies the field to retrieve * @return mixed Value of the field */ public function get($sField) { return $this->getField($sField); } /** * Sets the value of a specific field. * * @param string $sField Field name * @param string $mValue Value to set * @param bool $bSafe Flag to run defined inFilter on passed value */ public function setField($sField, $mValue, $bSafe = true): bool { if ($this->virgin == true) { $this->lasterror = 'No item loaded'; return false; } $this->modifiedValues[$sField] = true; if ($sField == $this->primaryKey) { $this->oldPrimaryKey = $this->values[$sField]; } $this->values[$sField] = $bSafe == true ? $this->_inFilter($mValue) : $mValue; return true; } /** * Shortcut to setField. * * @param string $sField Field name * @param string $mValue Value to set * @param bool $bSafe Flag to run defined inFilter on passed value */ public function set($sField, $mValue, $bSafe = true) { return $this->setField($sField, $mValue, $bSafe); } /** * Stores the loaded and modified item to the database. * * @return bool */ public function store() { if (!$this->isLoaded()) { $this->lasterror = 'No item loaded'; return false; } $sql = 'UPDATE `' . $this->table . '` SET '; $first = true; if (!is_array($this->modifiedValues)) { return true; } foreach (array_keys($this->modifiedValues) as $key) { if ($first == true) { $sql .= "`$key` = '" . $this->values[$key] . "'"; $first = false; } else { $sql .= ", `$key` = '" . $this->values[$key] . "'"; } } $sql .= " WHERE " . $this->primaryKey . " = '" . $this->oldPrimaryKey . "'"; $this->db->query($sql); $this->_lastSQL = $sql; if ($this->db->affected_rows() > 0) { self::$_oCache->addItem($this->table . "_" . $this->oldPrimaryKey, $this->values); } return $this->db->affected_rows() >= 1; } /** * Returns current item data as an assoziative array. */ public function toArray(): array|false { if ($this->virgin == true) { $this->lasterror = 'No item loaded'; return false; } $aReturn = []; foreach (array_keys($this->values) as $field) { $aReturn[$field] = $this->getField($field); } return $aReturn; } /** * Returns current item data as an object. */ public function toObject(): stdClass|false { $return = $this->toArray(); return (false !== $return) ? (object)$return : $return; } /** * Sets a custom property. * * @param string $sType Specifies the type * @param string $sName Specifies the name * @param mixed $mValue Specifies the value * @return bool */ public function setProperty($sType, $sName, mixed $mValue) { // If this object wasn't loaded before, return false if ($this->virgin == true) { $this->lasterror = 'No item loaded'; return false; } // Set the value $oProperties = $this->_getPropertiesCollectionInstance(); return $oProperties->setValue( $this->primaryKey, $this->get($this->primaryKey), $sType, $sName, $mValue ); } /** * Returns a custom property. * * @param string $sType Specifies the type * @param string $sName Specifies the name * @return mixed Value of the given property or false */ public function getProperty($sType, $sName) { // If this object wasn't loaded before, return false if ($this->virgin == true) { $this->lasterror = 'No item loaded'; return false; } // Return the value $oProperties = $this->_getPropertiesCollectionInstance(); return $oProperties->getValue( $this->primaryKey, $this->get($this->primaryKey), $sType, $sName ); } /** * Deletes a custom property. * * @param string $sType Specifies the type * @param string $sName Specifies the name * @return bool */ public function deleteProperty($sType, $sName) { // If this object wasn't loaded before, return false if ($this->virgin == true) { $this->lasterror = 'No item loaded'; return false; } // Delete the value $oProperties = $this->_getPropertiesCollectionInstance(); return $oProperties->deleteValue( $this->primaryKey, $this->get($this->primaryKey), $sType, $sName ); } /** * Deletes a custom property by its id. * * @param int $idprop Id of property * @return bool */ public function deletePropertyById($idprop) { $oProperties = $this->_getPropertiesCollectionInstance(); return $oProperties->delete($idprop); } /** * Deletes the current item * * @return void */ // Method doesn't work, remove in future versions // function delete() // { // $this->_collectionInstance->delete($item->get($this->primaryKey)); //} /** * Define the filter functions used when data is being stored or retrieved * from the database. * * Examples: *
     * $obj->setFilters(array('addslashes'), array('stripslashes'));
     * $obj->setFilters(array('htmlencode', 'addslashes'), array('stripslashes', 'htmlencode'));
     * 
* * @param array $aInFilters Array with function names * @param array $aOutFilters Array with function names * * @return void */ public function setFilters($aInFilters = [], $aOutFilters = []) { $this->_arrInFilters = $aInFilters; $this->_arrOutFilters = $aOutFilters; } /** * Filters the passed data using the functions defines in the _arrInFilters array. * * @param mixed $mData Data to filter * @return mixed Filtered data * @see setFilters * * @todo This method is used from public scope, but it should be protected * */ public function _inFilter(mixed $mData) { if (is_numeric($mData) || is_array($mData)) { return $mData; } if (is_null($mData)) { $mData = ''; } foreach ($this->_arrInFilters as $_arrInFilter) { if (function_exists($_arrInFilter)) { $mData = $_arrInFilter($mData); } } return $mData; } /** * Filters the passed data using the functions defines in the _arrOutFilters array. * * @param mixed $mData Data to filter * @return mixed Filtered data * @see setFilters * */ protected function _outFilter(mixed $mData) { if (is_numeric($mData)) return $mData; foreach ($this->_arrOutFilters as $_arrOutFilter) { if (function_exists($_arrOutFilter)) { $mData = $_arrOutFilter($mData); } } return $mData; } protected function _setMetaObject($sObjectName) { $this->_metaObject = $sObjectName; } public function getMetaObject() { global $_metaObjectCache; if (!is_array($_metaObjectCache)) { $_metaObjectCache = []; } $sClassName = $this->_metaObject; $qclassname = strtolower($sClassName); if (array_key_exists($qclassname, $_metaObjectCache) && is_object($_metaObjectCache[$qclassname])) { if (strtolower($_metaObjectCache[$qclassname]::class) === $qclassname) { $_metaObjectCache[$qclassname]->setPayloadObject($this); return $_metaObjectCache[$qclassname]; } } if (class_exists($sClassName)) { $_metaObjectCache[$qclassname] = new $sClassName($this); return $_metaObjectCache[$qclassname]; } } }