_tbl = $table; $this->_db =& $db; $this->_pkey = $key; $this->_pkeyForm = 'cid'; if(JVM_VERSION<3){ $this->_tbl_key = $key; $this->_tbl_keys = array($key); } else { // Set the key to be an array. if (is_string($key)){ $key = array($key); } elseif (is_object($key)){ $key = (array) $key; } $this->_tbl_keys = $key; $this->_tbl_key = $key[0]; if (count($key) == 1) { $this->_autoincrement = true; } else { $this->_autoincrement = false; } } // If we are tracking assets, make sure an access field exists and initially set the default. if (property_exists($this, 'asset_id')){ $this->_trackAssets = true; } // If the access property exists, set the default. if (property_exists($this, 'access')){ $this->access = (int) JFactory::getConfig()->get('access'); } if(JVM_VERSION>2){ // Implement JObservableInterface: // Create observer updater and attaches all observers interested by $this class: $this->_observers = new JObserverUpdater($this); JObserverMapper::attachAllObservers($this); } } /** * Returns an associative array of object properties. * * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @param boolean $public If true, returns only the public properties. * * @return array * @since 11.1 * @see get() */ public function getProperties($public = true) { $vars = get_object_vars($this); if ($public) { foreach ($vars as $k => $v) { if (strpos ($k, '_') === 0 or !property_exists($this, $k)) { unset($vars[$k]); } } } return $vars; } /** * Static method to get an instance of a JTable class if it can be found in * the table include paths. To add include paths for searching for JTable * classes @see JTable::addIncludePath(). * * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @param string $type The type (name) of the JTable class to get an instance of. * @param string $prefix An optional prefix for the table class name. * @param array $config An optional array of configuration values for the JTable object. * * @return mixed A JTable object if found or boolean false if one could not be found. * * @link http://docs.joomla.org/JTable/getInstance * @since 11.1 */ public static function getInstance($type, $prefix = 'VmTable', $config = array()) { // Sanitize and prepare the table class name. $type = preg_replace('/[^A-Z0-9_\.-]/i', '', $type); $tableClass = $prefix . ucfirst($type); // Only try to load the class if it doesn't already exist. if (!class_exists($tableClass)) { // Search for the class file in the JTable include paths. jimport('joomla.filesystem.path'); $paths = VmTable::addIncludePath(); $pathIndex = 0; while (!class_exists($tableClass) && $pathIndex < count($paths)) { if ($tryThis = JPath::find($paths[$pathIndex++], strtolower($type) . '.php')) { // Import the class file. include_once $tryThis; } } if (!class_exists($tableClass)) { vmdebug('Did not find file '.$type.'.php in ',$paths,$tryThis); return false; } } // If a database object was passed in the configuration array use it, otherwise get the global one from JFactory. $db = isset($config['dbo']) ? $config['dbo'] : JFactory::getDbo(); if(empty(VmConfig::$vmlang)){ vmTrace('$vmlang not set',true,20); vmdebug('$vmlang not set',VmConfig::$jDefLangTag); vmError('$vmlang not set',VmConfig::$jDefLangTag); VmConfig::$logDebug = true; vmTrace('$vmlang not set',true,20); VmConfig::$logDebug = false; vmLanguage::initialise(); //return false; } // Instantiate a new table class and return it. return new $tableClass($db); } /** * Add a filesystem path where JTable should search for table class files. * You may either pass a string or an array of paths. * * @param mixed $path A filesystem path or array of filesystem paths to add. * * @return array An array of filesystem paths to find JTable classes in. * * @link http://docs.joomla.org/JTable/addIncludePath * @since 11.1 */ public static function addIncludePath($path = null) { // Declare the internal paths as a static variable. static $_paths; // If the internal paths have not been initialised, do so with the base table path. if (!isset($_paths)) { $_paths = array(VMPATH_ADMIN .'/tables'); } // Convert the passed path(s) to add to an array. settype($path, 'array'); // If we have new paths to add, do so. if (!empty($path) && !in_array($path, $_paths)) { // Check and add each individual new path. foreach ($path as $dir) { // Sanitize path. $dir = trim($dir); if(!in_array($dir,$_paths)){ // Add to the front of the list so that custom paths are searched first. array_unshift($_paths, $dir); } } } return $_paths; } public function getKeyName($multiple = false) { if (count($this->_tbl_keys)) { if ($multiple) { return $this->_tbl_keys; } else { return $this->_tbl_keys[0]; } } else { return $this->_tbl_key; } } public function getDbo() { //static $db = false; if(!$this->_db){ $this->_db = JFactory::getDbo(); } return $this->_db; } /** * @return string|void */ public function getError(){ vmTrace( get_class($this).' asks for error'); vmdebug( get_class($this).' asks for error'); return ; } public function getErrors(){ vmTrace( get_class($this).' asks for errors'); vmdebug( get_class($this).' asks for errors'); return ; } public function setPrimaryKey($key, $keyForm = 0) { $error = vmText::sprintf('COM_VIRTUEMART_STRING_ERROR_PRIMARY_KEY', vmText::_('COM_VIRTUEMART_' . strtoupper($key))); $this->setObligatoryKeys('_pkey', $error); $this->_pkey = $key; $this->_pkeyForm = empty($keyForm) ? $key : $keyForm; $this->$key = 0; } public function getPKey(){ return $this->_pkey; } public function setObligatoryKeys($key) { $this->_obkeys[$key] = 1; } public function setUniqueName($name) { $this->_unique = true; $this->_obkeys[$name] = 1; $this->_unique_name[$name] = 1; } public function setLoggable() { $this->_loggable = true; $this->created_on = false; $this->created_by = 0; $this->modified_on = ''; $this->modified_by = 0; } /** * * @author Patrick Kohl, * @author Max Milbers */ public function setTranslatable($langFields) { $this->_translatableFields = $langFields; $this->_translatableFields['slug'] = 'slug'; $this->_translatable = true; $this->_langTag = VmConfig::$vmlang; $this->_tbl_lang = $this->_tbl . '_' . $this->_langTag; } public function setLanguage($tag){ $this->_langTag = strtolower(strtr($tag,'-','_')); $this->_tbl_lang = $this->_tbl . '_' . $this->_langTag; } public function getTranslatableFields() { return $this->_translatableFields; } public function setLockable() { $this->locked_on = ''; $this->locked_by = 0; } function setOrderable($key = 'ordering', $auto = true) { $this->_orderingKey = $key; $this->_orderable = 1; $this->_autoOrdering = $auto; $this->$key = 0; } function setHashable($key){ $this->_hashName = $key; } function setOmittedHashFields(array $fields){ $this->_omittedHashFields = $fields; } function setSlug($slugAutoName, $key = 'slug') { $this->_slugAutoName = $slugAutoName; $this->_slugName = $key; $this->$key = ''; $this->setUniqueName($key); } var $_tablePreFix = ''; function setTableShortCut($prefix) { $this->_tablePreFix = $prefix . '.'; } /** * Method to set rules for the record. * * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @param mixed $input A JAccessRules object, JSON string, or array. * @return void * @since 11.1 */ public function setRules($input) { if ($input instanceof JAccessRules) { $this->_rules = $input; } else { $this->_rules = new JAccessRules($input); } } /** * Method to get the rules for the record. * * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @return JAccessRules object * @since 11.1 */ public function getRules() { return $this->_rules; } public function emptyCache(){ self::$_cache = array(); } /** * This function defines a database field as parameter field, which means that some values get injected there * As delimiters are used | for the pair and = for key, value * * @author Max Milbers * @param string $paramsFieldName * @param string $varsToPushParam * @param boolean $overwrite */ function setParameterable($paramsFieldName, $varsToPushParam, $overwrite = false) { //if($this->_xParams===0) $this->_xParams = $paramsFieldName; if ($overwrite) { $this->_varsToPushParam = $varsToPushParam; } else { $this->_varsToPushParam = array_merge((array)$varsToPushParam, (array)$this->_varsToPushParam); } foreach ($this->_varsToPushParam as $k => $v) { if (!isset($this->$k)) $this->$k = $v[0]; } //vmdebug('setParameterable called '.$this->_xParams,$this->_varsToPushParam); } /** * Method to bind an associative array or object to the JTable instance.This * method only binds properties that are publicly accessible and optionally * takes an array of properties to ignore when binding. * * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @param mixed $src An associative array or object to bind to the JTable instance. * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. * * @return boolean True on success. * * @link http://docs.joomla.org/JTable/bind * @since 11.1 */ public function bind($src, $ignore = array()) { // If the source value is not an array or object return false. if (!is_object($src) && !is_array($src)) { $e = new JException(vmText::sprintf('JLIB_DATABASE_ERROR_BIND_FAILED_INVALID_SOURCE_ARGUMENT', get_class($this))); vmError($e); return false; } // If the source value is an object, get its accessible properties. if (is_object($src)) { $src = get_object_vars($src); } // If the ignore value is a string, explode it over spaces. if (!is_array($ignore)) { $ignore = explode(' ', $ignore); } // Bind the source value, excluding the ignored fields. foreach ($this->getProperties() as $k => $v) { // Only process fields not in the ignore array. if (!in_array($k, $ignore)) { if (isset($src[$k])) { $this->$k = $src[$k]; } } } return true; } /** * Maps the parameters to a subfield. usefull for the JForm * @author Max Milbers * @param $obj * @param $varsToPush * @param string $field */ static function bindParameterableToSubField(&$obj,$varsToPush,$field ='params'){ foreach($varsToPush as $name=>$values){ if(isset($obj->$name)){ $obj->$field->$name = $obj->$name; } else { $obj->$field->$name = $values[0]; } } } /** * This function must be * Takes the bounded values at obj of the field $xParams * and adds them as attributs of obj * @param $obj * @param $xParams * @param $varsToPushParam */ static function bindParameterable(&$obj, $xParams, $varsToPushParam) { if(empty($varsToPushParam)) return; if (empty($xParams)) { //vmError('There are bindParameterables, but $xParams is empty, this is a programmers error ',$varsToPushParam); vmdebug('There are bindParameterables, but $xParams is empty, this is a programmers error ', $obj); vmTrace('$xParams is empty'); } //$paramFields = $obj->$xParams; //vmdebug('$obj->_xParams '.$xParams.' $varsToPushParam ',$obj->$xParams,$varsToPushParam); if(is_object($obj)){ if (!empty($obj->$xParams)) { $params = explode('|', $obj->$xParams); foreach ($params as $item) { $item = explode('=', $item); $key = $item[0]; unset($item[0]); if(isset($varsToPushParam[$key][1])) { $item = implode('=', $item); $item = json_decode($item); if ($item != null){ $obj->$key = $item; } else { //vmdebug('bindParameterable $item ==null '.$key,$varsToPushParam[$key]); } } //else { // Unsolicited Parameter //} } } else { if(!property_exists($obj,$xParams)){ //vmError('There are bindParameterables, but $obj->$xParams is empty, this is a programmers error '.$xParams); vmdebug('There are bindParameterables, but $obj->$xParams is not isset, this is a programmers error ',$xParams , $obj); vmTrace('$obj->$xParams is not isset'); } } foreach ($varsToPushParam as $key => $v) { if (!isset($obj->$key)) { $obj->$key = $v[0]; //vmdebug('Set standard '.$key. ' = '.$v[0]); } } } else { //vmdebug('bindParameterable array ',$obj[$xParams]); if (!empty($obj[$xParams])) { $params = explode('|', $obj[$xParams]); foreach ($params as $item) { $item = explode('=', $item); $key = $item[0]; unset($item[0]); if (isset($item) && isset($varsToPushParam[$key][1])) { $item = implode('=', $item); $item = json_decode($item); if ($item != null){ $obj[$key] = $item; //$obj[$key] = html_entity_decode($item); } } } } else { if($obj[$xParams]==null){ //vmError('There are bindParameterables, but $obj->$xParams is empty, this is a programmers error '.$xParams); vmdebug('There are bindParameterables, but $obj[$xParams] is empty, this is a programmers error ',$xParams , $obj); vmTrace('$obj[$xParams] is empty'); } } foreach ($varsToPushParam as $key => $v) { if (!isset($obj[$key])) { $obj[$key] = $v[0]; } } } } /** * Sets fields encrypted * @author Max Milbers * @param $fieldNames */ public function setCryptedFields($fieldNames){ if(!$fieldNames){ vmTrace('setEncrytped fields false not catched'); return; } if(!is_array($fieldNames)) $fieldNames = array($fieldNames); if(isset($fieldNames[$this->_pkey])){ unset($fieldNames[$this->_pkey]); } $this->_cryptedFields = $fieldNames; if(!class_exists('vmCrypt')){ require(VMPATH_ADMIN .'/helpers/vmcrypt.php'); } } /** * */ public function getCryptedFields(){ return $this->_cryptedFields; } /** * Gives Back the columns of the current table, sets the properties on the table. * * @author Max Milbers * @param int $typeKey use "Field" to get the effect of getTableColumns * @param int $typeValue use "Type" to get the effect of getTableColumns * @param bool $properties disable setting of columns as table properties */ public function showFullColumns($typeKey=0,$typeValue=0,$properties=true){ $hash = 'SFL'.$this->_tbl.$typeKey.$typeValue; if (!isset(self::$_cache[$hash])) {//vmSetStartTime('showFullColumns'); $this->_db->setQuery('SHOW FULL COLUMNS FROM `'.$this->_tbl.'` ') ; self::$_cache[$hash] = $this->_db->loadAssocList(); //vmTime('showFullColumns','showFullColumns'); } if ($properties and count(self::$_cache[$hash]) > 0) { foreach (self::$_cache[$hash] as $key => $_f) { $_fieldlist[$_f['Field']] = $_f['Default']; } $this->setProperties($_fieldlist); } if ($typeKey or $typeValue){ foreach (self::$_cache[$hash] as $field){ if(empty($typeValue)){ $value = $field; } else { $value = $field[$typeValue]; } if($typeKey){ $result[$field[$typeKey]] = $value; } else { $result[] = $value; } } } else { $result = self::$_cache[$hash]; } return $result; } public function loadFields(){ return $this->showFullColumns(); } static public function checkTableExists($table){ $db = JFactory::getDBO(); $q = 'SHOW TABLES LIKE "'.$db->getPrefix().$table.'"'; $db->setQuery($q); $t = $db->loadResult(); if($t==false){ return false; } else { return true; } } function loadFieldValues($array=true){ if($array){ $return = $this->getProperties(); } else { $tmp = get_object_vars($this); $return = new stdClass(); foreach ($tmp as $k => $v){ // Do not process internal variables if (strpos ($k, '_') !== 0 and property_exists($this, $k)){ $return->$k = $v; } } } return $return; } function checkDataContainsTableFields($from, $ignore = array()) { if (empty($from)) return false; $fromArray = is_array($from); $fromObject = is_object($from); if (!$fromArray && !$fromObject) { vmError(get_class($this) . '::check if data contains table fields failed. Invalid from argument
' . print_r($from, 1) . ''); return false; } if (!is_array($ignore)) { $ignore = explode(' ', $ignore); } $properties = $this->getProperties(); foreach ($properties as $k => $v) { // internal attributes of an object are ignored if (!in_array($k, $ignore)) { if ($fromArray && isset($from[$k])) { return true; } else if ($fromObject && isset($from->$k)) { return true; } } } vmdebug('VmTable developer notice, table ' . get_class($this) . ' means that there is no data to store. When you experience that something does not get stored as expected, please write in the forum.virtuemart.net',$properties); return false; } /** * Method to provide a shortcut to binding, checking and storing a JTable * instance to the database table. The method will check a row in once the * data has been stored and if an ordering filter is present will attempt to * reorder the table rows based on the filter. The ordering filter is an instance * property name. The rows that will be reordered are those whose value matches * the JTable instance for the property specified. * * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @param mixed $src An associative array or object to bind to the JTable instance. * @param string $orderingFilter Filter for the order updating * @param mixed $ignore An optional array or space separated list of properties * to ignore while binding. * * @return boolean True on success. * * @link http://docs.joomla.org/JTable/save * @since 11.1 */ public function save($src, $orderingFilter = '', $ignore = '') { // Attempt to bind the source to the instance. if (!$this->bind($src, $ignore)) { return false; } // Run any sanity checks on the instance and verify that it is ready for storage. if (!$this->check()) { return false; } // Attempt to store the properties to the database table. if (!$this->store()) { return false; } // Attempt to check the row in, just in case it was checked out. if (!$this->checkin()) { return false; } // If an ordering filter is set, attempt reorder the rows in the table based on the filter and value. if ($orderingFilter) { $filterValue = $this->$orderingFilter; $this->reorder($orderingFilter ? $this->_db->quoteName($orderingFilter) . ' = ' . $this->_db->Quote($filterValue) : ''); } return true; } /** * Function setting the loggable data hack procted * In case you want to override the value for administrators, just set the created_on to "0000-00-00 00:00:00" * * @author Max Milbers */ function setLoggableFieldsForStore() { if ($this->_loggable) { // set default values always used //We store in UTC time, dont touch it! $date = JFactory::getDate(); $today = $date->toSQL(); //vmdebug('my today ',$date); $user = JFactory::getUser(); $pkey = $this->_pkey; //Lets check if the user is admin or the mainvendor $admin = vmAccess::manager('core'); if($admin){ // vmdebug('setLoggableFieldsForStore ', $this->created_on); if (empty($this->$pkey) and empty($this->created_on)) { $this->created_on = $today; } else if (empty($this->created_on)) { //If nothing is there, dont update it unset($this->created_on); } else //ADDED BY P2 PETER if ($this->created_on == "0000-00-00 00:00:00") { $this->created_on = $today; $this->created_by = $user->id; } //END ADD if (empty($this->$pkey) and empty($this->created_by)) { $this->created_by = $user->id; } else if (empty($this->created_by)) { //If nothing is there, dont update it unset($this->created_by); } } else { if (empty($this->$pkey)) { $this->created_on = $today; $this->created_by = $user->id; } else { //If nothing is there, dont update it unset($this->created_on); unset($this->created_by); } } $this->modified_on = $today; $this->modified_by = $user->id; } if (isset($this->locked_on)) { //Check if user is allowed to store, then disable or prevent storing $this->locked_on = 0; } } /** * * @param $obj * @param $src * @param array $ignore * @return bool */ static public function bindTo(&$obj, $src, $internals = false, $ignore = array()) { if(empty($src)) return false; if (is_object($src)) { $src = get_object_vars($src); } if(!is_array($src)) return false; $isIndexed = array_values($src) === $src; if($isIndexed) return false; // If the ignore value is a string, explode it over spaces. if (!empty($ignore) and !is_array($ignore)) { $ignore = explode(' ', $ignore); } foreach (get_object_vars($obj) as $k => $v) { if(!$internals and '_' == substr($k, 0, 1)) continue; // Only process fields not in the ignore array. if (!in_array($k, $ignore)) { if (isset($src[$k])) { $obj->$k = $src[$k]; } } } return true; } /** * Technic to inject params as table attributes * @author Max Milbers * $TableJoins array of table names to add and left join to find ID */ function load($oid = null, $overWriteLoadName = 0, $andWhere = 0, $tableJoins = array(), $joinKey = 0) { if($this->_translatable)vmSetStartTime('vmtableload'); if( $overWriteLoadName!==0 ){ $k = $overWriteLoadName; } else { $k = $this->_pkey; } if ($oid !== null) { $this->$k = $oid; } else { $oid = $this->$k; } if (empty($oid)) { if (!empty($this->_xParams)) { if(!empty($this->_varsToPushParam)){ foreach ($this->_varsToPushParam as $key => $v) { if (!isset($this->$key)) { $this->$key = $v[0]; } } } else { //vmdebug('_varsToPushParam empty ',$this); } } //vmdebug('vmtable load empty $oid return proto',$this); return $this; } //Version load the tables using JOIN if ($this->_translatable) { $mainTable = $this->_tbl; $langTable = $this->_tbl . '_' . $this->_langTag; $select = 'SELECT `' . $mainTable . '`.* ,`' . $langTable . '`.* '; $from = ' FROM `' . $mainTable . '` INNER JOIN `' . $langTable . '` using (`' . $this->_tbl_key . '`)'; } else { $mainTable = $this->_tbl; $select = 'SELECT `' . $mainTable . '`.* '; $from = ' FROM `' . $mainTable . '` '; } if (count($tableJoins)) { if (!$joinKey) $joinKey = $this->_tbl_key; foreach ($tableJoins as $tableId => $table) { if(strpos($tableId,',')!==false){ $tableIds = explode(',',$tableId); foreach($tableIds as $sel){ if(strpos($sel,' as ')!==false){ $temp = explode(' as ',$sel); $select .= ',`' . $table . '`.`' . trim($temp[0]) . '` as '.$temp[1].' '; } else { $select .= ',`' . $table . '`.`' . $sel . '` '; } } } else { $select .= ',`' . $table . '`.`' . $tableId . '` '; } $from .= ' LEFT JOIN `' . $table . '` on `' . $table . '`.`' . $joinKey . '`=`' . $mainTable . '`.`' . $joinKey . '`'; } } //the cast to int here destroyed the query for keys like virtuemart_userinfo_id, so no cast on $oid // $query = $select.$from.' WHERE '. $mainTable .'.`'.$this->_tbl_key.'` = "'.$oid.'"'; if ($andWhere === 0) $andWhere = ''; $query = $select . $from . ' WHERE `' . $mainTable . '`.`' . $k . '` = "' . $oid . '" ' . $andWhere; $hashVarsToPush = ''; if (!empty($this->_varsToPushParam)) { $hashVarsToPush = vmJsApi::safe_json_encode($this->_varsToPushParam); } $this->_lhash = $this->getHash($oid. $select . $k . $mainTable . $andWhere . $hashVarsToPush); //$this->showFullColumns(); if (isset (self::$_cache['l'][$this->_lhash])) { $this->bind(self::$_cache['l'][$this->_lhash]); if (!empty($this->_xParams) and !empty($this->_varsToPushParam)) { self::bindParameterable($this, $this->_xParams, $this->_varsToPushParam); } if($this->_cryptedFields){ $this->decryptFields(); } //vmTime('loaded by cache '.$this->_pkey.' '.$this->_slugAutoName.' '.$oid,'vmtableload'); return $this; } else { //vmdebug('loading '.$this->_pkey.' '.$this->_slugAutoName.' '.$oid); } $db = $this->getDBO(); $db->setQuery($query); $result = $db->loadAssoc(); if ($result) { $this->_loaded = true; $this->bind($result); if (!empty($this->_xParams)) { //Maybe better to use for $this an & self::bindParameterable($this, $this->_xParams, $this->_varsToPushParam); } if (count($tableJoins)) { foreach ($tableJoins as $tableId => $table) { if(strpos($tableId,',')!==false){ $tableIds = explode(',',$tableId); foreach($tableIds as $sel){ if(strpos($sel,' as ')!==false){ $temp = explode(' as ',$sel); $key = trim($temp[1]); //vmdebug('my $result ',$result[$key]); if (isset($result[$key])) $this->$key = $result[$key]; else $this->$key = false; } else { if (isset($result[$sel])) $this->$sel = $result[$sel]; } } } else { if (isset($result[$tableId])) $this->$tableId = $result[$tableId]; } } } } else { if($this->_translatable and VmConfig::$langCount>1 and $this->_ltmp!=VmConfig::$jDefLang ){ if(VmConfig::$defaultLang!=VmConfig::$jDefLang){ if($this->_langTag != VmConfig::$defaultLang ){ $this->_ltmp = $this->_langTag; $this->_langTag = VmConfig::$defaultLang; } else { $this->_langTag = VmConfig::$jDefLang; } } else { $this->_ltmp = $this->_langTag; $this->_langTag = VmConfig::$defaultLang; } //vmdebug('No result for '.$this->_ltmp.', lets check for Fallback lang '.$this->_langTag); //vmSetStartTime('lfallback'); $this->_loadedWithLangFallback = VmConfig::$defaultLangTag; $this->load($oid, $overWriteLoadName, $andWhere, $tableJoins, $joinKey) ; //vmTime('Time to load language fallback '.$this->_langTag, 'lfallback'); } else { $this->_loaded = false; } } if($this->_ltmp){ //vmdebug('Set Ltmp '.$this->_ltmp.' back to false'); $this->_langTag = $this->_ltmp; self::$_cache['l'][$this->_lhash] = $this->loadFieldValues(false); } else { self::$_cache['l'][$this->_lhash] = $this->loadFieldValues(false); } if($this->_cryptedFields){ $this->decryptFields(); } //if($this->_translatable) vmTime('loaded '.$this->_langTag.' '.$mainTable.' '.$oid ,'vmtableload'); $this->_ltmp = false; return $this; } function getHash($value) { $hashFunction = Vmconfig::get('hashFunction', 'md5'); return call_user_func_array($hashFunction, array(&$value)); } function getLoaded (){ return $this->_loaded; } /** * Typo, had wrong name * @deprecated heavily */ function encryptFields(){ $this->decryptFields(); } function decryptFields(){ if(!class_exists('vmCrypt')){ require(VMPATH_ADMIN .'/helpers/vmcrypt.php'); } if(isset($this->modified_on) and $this->modified_on!='0000-00-00 00:00:00'){ $date = JFactory::getDate($this->modified_on); $date = $date->toUnix(); } else if(isset($this->created_on) and $this->created_on!='0000-00-00 00:00:00'){ $date = JFactory::getDate($this->created_on); $date = $date->toUnix(); } else { $date = 0; } foreach($this->_cryptedFields as $field){ if(isset($this->$field)){ $this->$field = vmCrypt::decrypt($this->$field, $date); //vmdebug($this->_tbl.' Field '.$field.' encrypted = '.$this->$field); } } } /** * Derived from JTable * Records in this table do not need to exist, so we might need to create a record even * if the primary key is set. Therefore we need to overload the store() function. * Technic to inject params as table attributes and to encrypt data * @author Max Milbers * @copyright for derived parts, (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @see libraries/joomla/database/JTable#store($updateNulls) */ function store($updateNulls = false) { $this->setLoggableFieldsForStore(); if($this->_cryptedFields){ foreach($this->_cryptedFields as $field){ if(isset($this->$field)){ $this->$field = vmCrypt::encrypt($this->$field); } } } $this->storeParams(); if (!empty($this->asset_id)) { $currentAssetId = $this->asset_id; } // The asset id field is managed privately by this class. if ($this->_trackAssets) { unset($this->asset_id); } $tblKey = $this->_tbl_key; if(!empty($this->$tblKey)){ $_qry = 'SELECT `'.$tblKey.'` ' . 'FROM `'.$this->_tbl.'` ' . 'WHERE `'.$tblKey.'` = "' . $this->$tblKey.'" '; $this->_db->setQuery($_qry); $this->$tblKey = $this->_db->loadResult(); } if(!empty($this->$tblKey)){ $ok = $this->_db->updateObject($this->_tbl, $this, $this->_tbl_key, $updateNulls); } else { $p = $this->$tblKey; $ok = $this->_db->insertObject($this->_tbl, $this, $this->_tbl_key); if($ok and !empty($this->_hashName)){ $oldH= $this->{$this->_hashName}; if($p!=$this->$tblKey and !in_array($tblKey,$this->_omittedHashFields)){ $this->hashEntry(); $ok = $this->_db->updateObject($this->_tbl, $this, $this->_tbl_key, $updateNulls); vmdebug('Updated entry with correct hash ',$this->_tbl_key,$p,$this->$tblKey,$oldH,$this->{$this->_hashName}); } } } //reset Params if(isset($this->_tmpParams) and is_array($this->_tmpParams)){ foreach($this->_tmpParams as $k => $v){ $this->$k = $v; } } $this->_tmpParams = false; //decrypt the Fields if($this->_cryptedFields){ $this->decryptFields(); } // If the store failed return false. if (!$ok) { $e = new JException(vmText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $this->_db->getErrorMsg())); vmError($e); return false; } // If the table is not set to track assets return true. if (!$this->_trackAssets) { return true; } if ($this->_locked) { $this->_unlock(); } $parentId = $this->_getAssetParentId(); $name = $this->_getAssetName(); $title = $this->_getAssetTitle(); $asset = JTable::getInstance('Asset', 'JTable', array('dbo' => $this->getDbo())); $asset->loadByName($name); // Re-inject the asset id. $this->asset_id = $asset->id; // Check for an error. if ($error = $asset->getError()){ vmError($error); return false; } // Specify how a new or moved node asset is inserted into the tree. if (empty($this->asset_id) || $asset->parent_id != $parentId) { $asset->setLocation($parentId, 'last-child'); } // Prepare the asset to be stored. $asset->parent_id = $parentId; $asset->name = $name; $asset->title = $title; if ($this->_rules instanceof JAccessRules) { $asset->rules = (string) $this->_rules; } if (!$asset->check() || !$asset->store($updateNulls)) { vmError($asset->getError()); return false; } // Create an asset_id or heal one that is corrupted. if (empty($this->asset_id) || ($currentAssetId != $this->asset_id && !empty($this->asset_id))) { // Update the asset_id field in this table. $this->asset_id = (int) $asset->id; $query = $this->_db->getQuery(true); $query->update($this->_db->quoteName($this->_tbl)); $query->set('asset_id = ' . (int) $this->asset_id); $query->where($this->_db->quoteName($tblKey) . ' = ' . (int) $this->$tblKey); $this->_db->setQuery($query); if (!$this->_db->execute()) { $e = new JException(vmText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED_UPDATE_ASSET_ID', $this->_db->getErrorMsg())); vmError($e); return false; } } return $ok; } function storeParams() { if (!empty($this->_xParams) and !empty($this->_varsToPushParam)) { $paramFieldName = $this->_xParams; $this->$paramFieldName = ''; $this->_tmpParams = array(); foreach ($this->_varsToPushParam as $key => $v) { if (isset($this->$key)) { $this->$paramFieldName .= $key . '=' . vmJsApi::safe_json_encode($this->$key) . '|'; $this->_tmpParams[$key] = $this->$key; } else { $this->$paramFieldName .= $key . '=' . vmJsApi::safe_json_encode($v[0]) . '|'; $this->_tmpParams[$key] = $v[0]; } unset($this->$key); } } return true; } function checkCreateUnique($tbl_name, $name) { $i = 0; while ($i < 40) { $tbl_key = $this->_tbl_key; $q = 'SELECT `' . $name . '` FROM `' . $tbl_name . '` WHERE `' . $name . '` = "' . $this->$name . '" '; if(!empty($this->$tbl_key)){ $q .= ' AND `' . $this->_tbl_key . '`!=' . $this->$tbl_key.' '; } $this->_db->setQuery($q); $existingSlugName = $this->_db->loadResult(); if (!empty($existingSlugName)) { if($posNbr = strrpos($this->$name,'-')){ $existingNbr = substr($this->$name,$posNbr+1); if(is_numeric($existingNbr)){ $existingNbr++; $this->$name = substr($this->$name,0,$posNbr+1) . $existingNbr; } else{ $this->$name = $this->$name . '-1'; } } else { $this->$name = $this->$name . '-1'; } vmdebug('checkCreateUnique '.$name.' = '.$existingSlugName.' changed to ',$this->$name); } else { return true; } $i++; } return false; } function setCheckVendorId(){ if(empty($this->virtuemart_vendor_id) and $this->_pkey=='virtuemart_vendor_id'){ $this->virtuemart_vendor_id = $this->_pvalue; } $multix = Vmconfig::get('multix', 'none'); //Lets check if the user is admin or the mainvendor $virtuemart_vendor_id = false; //Todo removed Quickn Dirty, use check in derived class if ($multix == 'none' and get_class($this) !== 'TableVmusers') { $this->virtuemart_vendor_id = 1; //return true; } else { //$user = JFactory::getUser(); //$loggedVendorId = vmAccess::isSuperVendor($user->id); $loggedVendorId = vmAccess::isSuperVendor(); //vmdebug('Table '.$this->_tbl.' check '.$loggedVendorId,$user->id); $user_is_vendor = 0; $tbl_key = $this->_tbl_key; $className = get_class($this); $admin = vmAccess::manager('managevendors'); //Todo removed Quickn Dirty, use check in derived class if (strpos($this->_tbl,'virtuemart_vmusers')===FALSE) { $q = 'SELECT `virtuemart_vendor_id` FROM `' . $this->_tbl . '` WHERE `' . $this->_tbl_key . '`="' . $this->$tbl_key . '" '; if (!isset(self::$_cache[md5($q)])) { $this->_db->setQuery($q); self::$_cache[md5($q)] = $virtuemart_vendor_id = $this->_db->loadResult(); } else $virtuemart_vendor_id = self::$_cache[md5($q)]; } else { $q = 'SELECT `virtuemart_vendor_id`,`user_is_vendor`,`virtuemart_user_id` FROM `' . $this->_tbl . '` WHERE `' . $this->_tbl_key . '`="' . $this->$tbl_key . '" '; if (!isset(self::$_cache[md5($q)])) { $this->_db->setQuery($q); $vmuser = $this->_db->loadRow(); self::$_cache[md5($q)] = $vmuser; } else $vmuser = self::$_cache[md5($q)]; vmdebug('Table '.$this->_tbl.' check loaded old entry',$vmuser); if ($vmuser and count($vmuser) === 3) { $virtuemart_vendor_id = $vmuser[0]; $user_is_vendor = $vmuser[1]; if ($multix == 'none') { if (empty($user_is_vendor)) { $this->virtuemart_vendor_id = 0; } else { $this->virtuemart_vendor_id = 1; } return true; } else { vmdebug('Table '.$this->_tbl.' check loaded old entry mv mode',$vmuser); if (!$admin) { if(!empty($vmuser[2])){ $user = JFactory::getUser($vmuser[2]); $loggedVendorId = vmAccess::isSuperVendor($user->id); vmdebug('Table '.$this->_tbl.' check new user '.$loggedVendorId); } $this->virtuemart_vendor_id = $loggedVendorId; return true; } } } else { //New User //vmInfo('We run in multivendor mode and you did not set any vendor for '.$className.' and '.$this->_tbl);//, Set to mainvendor '.$this->virtuemart_vendor_id if(empty($this->user_is_vendor)){ $this->virtuemart_vendor_id = 0; return true; } } } if (!$admin and !empty($virtuemart_vendor_id) and !empty($loggedVendorId) and $loggedVendorId != $virtuemart_vendor_id) { //Todo removed Quickn Dirty, use check in derived class //This is the case when a vendor buys products of vendor1 if (strpos($this->_tbl,'virtuemart_order_items')===FALSE and strpos($this->_tbl,'virtuemart_carts')===FALSE) { vmdebug('Blocked storing, logged vendor ' . $loggedVendorId . ' but data belongs to ' . $virtuemart_vendor_id,$this->_tbl); return false; } else { $this->virtuemart_vendor_id = $virtuemart_vendor_id; } } else if (!$admin) { if ($virtuemart_vendor_id) { $this->virtuemart_vendor_id = $virtuemart_vendor_id; vmdebug('Non admin is storing using loaded vendor_id'); } else { if(empty($this->virtuemart_vendor_id) ){ $this->virtuemart_vendor_id = $loggedVendorId; } //No id is stored, even users are allowed to use for the storage and vendorId, no change } } else { //Admins are allowed to do anything. We just trhow some messages if (!empty($virtuemart_vendor_id) and $loggedVendorId != $virtuemart_vendor_id) { vmdebug('Admin with vendor id ' . $loggedVendorId . ' is using for storing vendor id ' . $this->virtuemart_vendor_id); } else if (empty($virtuemart_vendor_id) and empty($this->virtuemart_vendor_id)) { if(strpos($this->_tbl,'virtuemart_vendors')===FALSE and strpos($this->_tbl,'virtuemart_vmusers')===FALSE){ $this->virtuemart_vendor_id = $loggedVendorId; vmdebug('Fallback to '.$this->virtuemart_vendor_id.' for $loggedVendorId '.$loggedVendorId.': We run in multivendor mode and you did not set any vendor for '.$className.' and '.$this->_tbl); } } } } return true; } function hashEntry($set = true){ $fields = $this->getProperties(); unset($fields[(string)$this->_hashName]); if(!empty($this->_omittedHashFields)){ foreach($this->_omittedHashFields as $prop){ unset($fields[(string)$prop]); } } $toHash = serialize($fields); $h = hash('md5',$toHash); if($set ) { $hashName = $this->_hashName; $this->{$hashName} = $h; } return $h; } function integrity(){ $hashName = $this->_hashName; $oldHash = $this->{$hashName}; $hash = $this->hashEntry(false); if($oldHash==$hash){ return true; } else { return false; } } /** * @author Max Milbers * @param */ function check() { if (!empty($this->_slugAutoName)) { $slugAutoName = $this->_slugAutoName; $slugName = $this->_slugName; if (in_array($slugAutoName, $this->_translatableFields)) { $checkTable = $this->_tbl_lang; vmTrace('Language table in normal check?'); } else { $checkTable = $this->_tbl; } if (empty($this->$slugName)) { // vmdebug('table check use _slugAutoName '.$slugAutoName.' '.$slugName); if (!empty($this->$slugAutoName)) { $this->$slugName = $this->$slugAutoName; } else { $pkey = $this->_pkey; vmError('VmTable ' . $checkTable . ' Check not passed. Neither slug nor obligatory value at ' . $slugAutoName . ' for auto slug creation is given '.$this->$pkey); return false; } } //if (JVM_VERSION === 1) $this->$slugName = JFilterOutput::stringURLSafe($this->$slugName); //else $this->$slugName = JApplication::stringURLSafe($this->$slugName); //pro+#'!"§$%&/()=?duct-w-| ||cu|st|omfield-|str