oxbase.php

Go to the documentation of this file.
00001 <?php
00002 
00006 DEFINE('ACTION_NA', 0);
00007 DEFINE('ACTION_DELETE', 1);
00008 DEFINE('ACTION_INSERT', 2);
00009 DEFINE('ACTION_UPDATE', 3);
00010 DEFINE('ACTION_UPDATE_STOCK', 4);
00011 
00016 class oxBase extends oxSuperCfg
00017 {
00022     protected $_sOXID = null;
00023 
00028     protected $_iShopId = null;
00029 
00035     protected $_blIsSimplyClonable = true;
00036 
00041     protected $_sClassName = 'oxbase';
00042 
00048     protected $_sCoreTable = null;
00049 
00054     protected $_sViewTable  = null;
00055 
00056 
00062     protected $_aFieldNames = array('oxid' => 0);
00063 
00069     protected $_sCacheKey = null;
00070 
00076     protected $_blUseLazyLoading = false;
00077 
00083     protected $_aSkipSaveFields = array('oxtimestamp');
00084 
00085 
00091     protected $_blUseSkipSaveFields = true;
00092 
00097     protected $_sExistKey = "oxid";
00098 
00105     protected $_blIsDerived = null;
00106 
00116     protected static $_blDisableFieldCaching = array();
00117 
00123     protected $_blIsSeoObject = false;
00124 
00130     protected $_blReadOnly = false;
00131 
00137     protected $_blIsInList = false;
00138 
00144     protected $_isLoaded = false;
00145 
00151     protected $_aInnerLazyCache = null;
00152 
00158     protected $_blEmployMultilanguage = false;
00159 
00165     public function getUseSkipSaveFields()
00166     {
00167         return $this->_blUseSkipSaveFields;
00168     }
00169 
00177     public function setUseSkipSaveFields( $blUseSkipSaveFields )
00178     {
00179         $this->_blUseSkipSaveFields = $blUseSkipSaveFields;
00180     }
00181 
00185     public function __construct()
00186     {
00187         // set active shop
00188         $myConfig = $this->getConfig();
00189         $this->_sCacheKey = $this->getViewName();
00190 
00191 
00192         if ( $this->_blUseLazyLoading ) {
00193             $this->_sCacheKey .= $myConfig->getActiveView()->getClassName();
00194         } else {
00195             $this->_sCacheKey .= "allviews";
00196         }
00197 
00198         //do not cache for admin?
00199         if ( $this->isAdmin() ) {
00200             $this->_sCacheKey = null;
00201         }
00202 
00203         $this->setShopId( $myConfig->getShopId() );
00204     }
00205 
00214     public function __set( $sName, $sValue )
00215     {
00216         $this->$sName = $sValue;
00217         if ( $this->_blUseLazyLoading && strpos( $sName, $this->_sCoreTable . "__" ) === 0 ) {
00218             $sFieldName = str_replace( $this->_sCoreTable . "__", '', $sName );
00219             if ( $sFieldName != 'oxnid' && ( !isset( $this->_aFieldNames[$sFieldName] ) || !$this->_aFieldNames[$sFieldName] ) ) {
00220                 $aAllFields = $this->_getAllFields(true);
00221                 if ( isset( $aAllFields[strtolower($sFieldName)] ) ) {
00222                     $iFieldStatus = $this->_getFieldStatus( $sFieldName );
00223                     $this->_addField( $sFieldName, $iFieldStatus );
00224                 }
00225             }
00226         }
00227     }
00228 
00236     public function __get( $sName )
00237     {
00238         switch ( $sName ) {
00239             case 'blIsDerived':
00240                 return $this->isDerived();
00241                 break;
00242             case 'sOXID':
00243                 return $this->getId();
00244                 break;
00245             case 'blReadOnly':
00246                 return $this->isReadOnly();
00247                 break;
00248         }
00249 
00250         // implementing lazy loading fields
00251         // This part of the code is slow and normally is called before field cache is built.
00252         // Make sure it is not called after first page is loaded and cache data is fully built.
00253         if ( $this->_blUseLazyLoading && stripos( $sName, $this->_sCoreTable . "__" ) === 0 ) {
00254 
00255             if ( $this->getId() ) {
00256 
00257                 //lazy load it
00258                 $sFieldName      = str_replace( $this->_sCoreTable . "__", '', $sName );
00259                 $sCacheFieldName = strtoupper( $sFieldName );
00260 
00261                 $iFieldStatus = $this->_getFieldStatus( $sFieldName );
00262                 $sViewName    = $this->getViewName();
00263                 $sId = $this->getId();
00264 
00265                 try {
00266                     if ( $this->_aInnerLazyCache === null ) {
00267 
00268                         $oDb = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00269                         $sQ = "SELECT * FROM " . $sViewName . " WHERE `oxid` = " . $oDb->quote( $sId );
00270                         $rs = $oDb->select( $sQ );
00271                         if ( $rs && $rs->RecordCount() ) {
00272                             $this->_aInnerLazyCache = array_change_key_case( $rs->fields, CASE_UPPER );
00273                             if ( array_key_exists( $sCacheFieldName, $this->_aInnerLazyCache ) ) {
00274                                 $sFieldValue = $this->_aInnerLazyCache[$sCacheFieldName];
00275                             } else {
00276                                 return null;
00277                             }
00278                         } else {
00279                             return null;
00280                         }
00281                     } elseif ( array_key_exists( $sCacheFieldName, $this->_aInnerLazyCache ) ) {
00282                         $sFieldValue = $this->_aInnerLazyCache[$sCacheFieldName];
00283                     } else {
00284                         return null;
00285                     }
00286 
00287                     $this->_addField( $sFieldName, $iFieldStatus );
00288                     $this->_setFieldData( $sFieldName, $sFieldValue );
00289 
00290                     //save names to cache for next loading
00291                     if ($this->_sCacheKey) {
00292                         $myUtils = oxRegistry::getUtils();
00293                         $sCacheKey = 'fieldnames_' . $this->_sCoreTable . "_" . $this->_sCacheKey;
00294                         $aFieldNames = $myUtils->fromFileCache( $sCacheKey );
00295                         $aFieldNames[$sFieldName] = $iFieldStatus;
00296                         $myUtils->toFileCache( $sCacheKey, $aFieldNames );
00297                     }
00298                 } catch ( Exception $e ) {
00299                     return null;
00300                 }
00301 
00302                 //do not use field cache for this page
00303                 //as if we use it for lists then objects are loaded empty instead of lazy loading.
00304                 self::$_blDisableFieldCaching[get_class( $this )] = true;
00305             }
00306 
00307             oxUtilsObject::getInstance()->resetInstanceCache(get_class($this));
00308         }
00309 
00310         //returns stdClass implementing __toString() method due to uknown scenario where this var should be used.
00311         if (!isset( $this->$sName ) ) {
00312             $this->$sName = null;
00313         }
00314 
00315         return $this->$sName;
00316     }
00317 
00325     public function __isset($mVar)
00326     {
00327         return isset($this->$mVar);
00328     }
00329 
00335     public function __clone()
00336     {
00337         if (!$this->_blIsSimplyClonable) {
00338             foreach ( $this->_aFieldNames as $sField => $sVal ) {
00339                 $sLongName = $this->_getFieldLongName( $sField );
00340                 if ( is_object($this->$sLongName)) {
00341                     $this->$sLongName = clone $this->$sLongName;
00342                 }
00343             }
00344         }
00345     }
00346 
00354     public function oxClone($oObject)
00355     {
00356         $aClasVars = get_object_vars( $oObject);
00357         while (list($name, $value) = each($aClasVars)) {
00358             if ( is_object( $oObject->$name ) ) {
00359                 $this->$name = clone $oObject->$name;
00360             } else {
00361                 $this->$name = $oObject->$name;
00362             }
00363         }
00364     }
00365 
00374     public function init( $sTableName = null, $blForceAllFields = false)
00375     {
00376 
00377         if ( !$sTableName ) {
00378             $sTableName = $this->_sCoreTable;
00379         } else {
00380             $this->_sCoreTable = $sTableName;
00381         }
00382 
00383         // reset view table
00384         $this->_sViewTable = false;
00385 
00386         if ( count( $this->_aFieldNames ) <= 1 ) {
00387             $this->_initDataStructure( $blForceAllFields );
00388         }
00389     }
00390 
00398     public function assign( $dbRecord )
00399     {
00400         if ( !is_array( $dbRecord ) ) {
00401             return;
00402         }
00403 
00404 
00405         reset($dbRecord );
00406         while ( list( $sName, $sValue ) = each( $dbRecord ) ) {
00407 
00408             // patch for IIS
00409             //TODO: test it on IIS do we still need it
00410             //if( is_array($value) && count( $value) == 1)
00411             //    $value = current( $value);
00412 
00413             $this->_setFieldData( $sName, $sValue );
00414         }
00415 
00416         $sOxidField = $this->_getFieldLongName( 'oxid' );
00417         $this->_sOXID = $this->$sOxidField->value;
00418 
00419     }
00420 
00426     public function getClassName()
00427     {
00428         return $this->_sClassName;
00429     }
00430 
00436     public function getCoreTableName()
00437     {
00438         return $this->_sCoreTable;
00439     }
00440 
00446     public function getId()
00447     {
00448         return $this->_sOXID;
00449     }
00450 
00458     public function setId($sOXID = null)
00459     {
00460         if ( $sOXID ) {
00461             $this->_sOXID = $sOXID;
00462         } else {
00463             $this->_sOXID = oxUtilsObject::getInstance()->generateUID();
00464         }
00465 
00466         $sIdVarName = $this->_sCoreTable . "__oxid";
00467         $this->$sIdVarName = new oxField($this->_sOXID, oxField::T_RAW);
00468 
00469         return $this->_sOXID;
00470     }
00471 
00479     public function setShopId($iShopId)
00480     {
00481         $this->_iShopId = $iShopId;
00482     }
00483 
00489     public function getShopId()
00490     {
00491         return $this->_iShopId;
00492     }
00493 
00501     public function getViewName($blForceCoreTableUsage = null)
00502     {
00503         if (!$this->_sViewTable || ($blForceCoreTableUsage !== null)) {
00504             if ( $blForceCoreTableUsage === true ) {
00505                 return $this->_sCoreTable;
00506             }
00507 
00508 
00509             if ( ( $blForceCoreTableUsage !== null ) && $blForceCoreTableUsage ) {
00510                 $iShopId = -1;
00511             } else {
00512                 $iShopId = oxRegistry::getConfig()->getShopId();
00513             }
00514 
00515 
00516             $sViewName = getViewName( $this->_sCoreTable, $this->_blEmployMultilanguage == false ? -1 : $this->getLanguage(), $iShopId );
00517             if ( $blForceCoreTableUsage !== null ) {
00518                 return $sViewName;
00519             }
00520             $this->_sViewTable = $sViewName;
00521         }
00522         return $this->_sViewTable;
00523     }
00524 
00533     public function modifyCacheKey( $sCacheKey, $blOverride = false )
00534     {
00535         if ( $blOverride ) {
00536             $this->_sCacheKey = $sCacheKey;
00537         } else {
00538             $this->_sCacheKey .= $sCacheKey;
00539         }
00540     }
00541 
00547     public function disableLazyLoading()
00548     {
00549         $this->_blUseLazyLoading = false;
00550         $this->_initDataStructure(true);
00551     }
00552 
00553 
00559     public function isDerived()
00560     {
00561 
00562         return $this->_blIsDerived;
00563     }
00564 
00572     public function setIsDerived($blVal)
00573     {
00574         $this->_blIsDerived = $blVal;
00575     }
00576 
00583     public function isMultilang()
00584     {
00585         return false;
00586     }
00587 
00597     public function load( $sOXID)
00598     {
00599         /*
00600         if( !isset($oxID)){
00601             $oEx = oxNew('oxObjectException','core');
00602             $oEx->setMessage('EXCEPTION_OBJECT_OXIDNOTSET');
00603             $oEx->setObject($this);
00604             throw $oEx;
00605         }*/
00606 
00607         $blExistingOldForceCoreTable = $this->_blForceCoreTableUsage;
00608 
00609         $this->_blForceCoreTableUsage = true;
00610 
00611         //getting at least one field before lazy loading the object
00612         $this->_addField('oxid', 0);
00613         $sSelect = $this->buildSelectString( array( $this->getViewName().".oxid" => $sOXID));
00614         $this->_isLoaded = $this->assignRecord( $sSelect );
00615 
00616         $this->_blForceCoreTableUsage = $blExistingOldForceCoreTable;
00617 
00618         return $this->_isLoaded;
00619     }
00620 
00626     public function isLoaded()
00627     {
00628         return $this->_isLoaded;
00629     }
00630 
00638     public function buildSelectString( $aWhere = null)
00639     {
00640         $oDB = oxDb::getDb();
00641         $myUtils = oxRegistry::getUtils();
00642 
00643         $sGet = $this->getSelectFields();
00644         $sSelect = "select $sGet from " . $this->getViewName() . " where 1 ";
00645 
00646         if ( $aWhere) {
00647             reset($aWhere);
00648             while (list($name, $value) = each($aWhere)) {
00649                 $sSelect .=  " and " . $name.' = '.$oDB->quote($value);
00650             }
00651         }
00652 
00653         // add active shop
00654 
00655         return $sSelect;
00656     }
00657 
00665     public function assignRecord( $sSelect )
00666     {
00667         $blRet = false;
00668 
00669         $rs = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->select( $sSelect );
00670 
00671         if ($rs != false && $rs->recordCount() > 0) {
00672             $blRet = true;
00673             $this->assign( $rs->fields);
00674         }
00675 
00676         return $blRet;
00677     }
00678 
00686     public function getFieldData( $sFieldName )
00687     {
00688         $sLongFieldName = $this->_getFieldLongName( $sFieldName );
00689             return $this->$sLongFieldName->value;
00690     }
00691 
00699     public function getSelectFields( $blForceCoreTableUsage = null )
00700     {
00701         $aSelectFields = array();
00702 
00703         $sViewName = $this->getViewName( $blForceCoreTableUsage );
00704 
00705         foreach ( $this->_aFieldNames as $sKey => $sField ) {
00706             if ( $sViewName ) {
00707                 $aSelectFields[] = "`$sViewName`.`$sKey`";
00708             } else {
00709                 $aSelectFields[] = ".`$sKey`";
00710             }
00711 
00712         }
00713 
00714         $sSelectFields = join( ", ", $aSelectFields );
00715         return $sSelectFields;
00716     }
00717 
00725     public function delete( $sOXID = null)
00726     {
00727         if ( !$sOXID ) {
00728             $sOXID = $this->getId();
00729 
00730             //do not allow derived deletion
00731             if ( !$this->allowDerivedDelete() ) {
00732                 return false;
00733             }
00734         }
00735 
00736         if ( !$sOXID ) {
00737             return false;
00738         }
00739 
00740 
00741         $oDB = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00742         $sDelete = "delete from $this->_sCoreTable where oxid = ".$oDB->quote( $sOXID );
00743         $rs = $oDB->execute( $sDelete );
00744         if ( $blDelete = ( bool ) $oDB->affected_Rows() ) {
00745             $this->onChange(ACTION_DELETE, $sOXID);
00746         }
00747 
00748         return $blDelete;
00749     }
00750 
00751 
00757     public function save()
00758     {
00759         if ( !is_array( $this->_aFieldNames ) ) {
00760             return false;
00761         }
00762 
00763         $blRet = false;
00764 
00765         // #739A - should be executed here because of date/time formatting feature
00766         if ( $this->isAdmin() && !$this->getConfig()->getConfigParam( 'blSkipFormatConversion' ) ) {
00767             foreach ($this->_aFieldNames as $sName => $sVal) {
00768                 $sLongName = $this->_getFieldLongName($sName);
00769                 if ( isset($this->$sLongName->fldtype) && $this->$sLongName->fldtype == "datetime" ) {
00770                     oxRegistry::get("oxUtilsDate")->convertDBDateTime( $this->$sLongName, true );
00771                 } elseif ( isset($this->$sLongName->fldtype) && $this->$sLongName->fldtype == "timestamp" ) {
00772                     oxRegistry::get("oxUtilsDate")->convertDBTimestamp( $this->$sLongName, true);
00773                 } elseif ( isset($this->$sLongName->fldtype) && $this->$sLongName->fldtype == "date" ) {
00774                     oxRegistry::get("oxUtilsDate")->convertDBDate( $this->$sLongName, true);
00775                 }
00776             }
00777         }
00778         if ( $this->exists() ) {
00779             //do not allow derived update
00780             if ( !$this->allowDerivedUpdate() ) {
00781                 return false;
00782             }
00783 
00784             $blRet = $this->_update();
00785             $sAction = ACTION_UPDATE;
00786         } else {
00787             $blRet = $this->_insert();
00788             $sAction = ACTION_INSERT;
00789         }
00790 
00791         $this->onChange($sAction);
00792 
00793         if ( $blRet ) {
00794             return $this->getId();
00795         } else {
00796             return false;
00797         }
00798     }
00799 
00805     public function allowDerivedUpdate()
00806     {
00807         return !$this->isDerived();
00808     }
00809 
00815     public function allowDerivedDelete()
00816     {
00817         return !$this->isDerived();
00818     }
00819 
00827     public function exists( $sOXID = null)
00828     {
00829         if ( !$sOXID ) {
00830             $sOXID = $this->getId();
00831         }
00832         if ( !$sOXID ) {
00833             return false;
00834         }
00835 
00836         $sViewName = $this->getCoreTableName();
00837         $oDb = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00838         $sSelect= "select {$this->_sExistKey} from {$sViewName} where {$this->_sExistKey} = ".$oDb->quote( $sOXID );
00839 
00840         return ( bool ) $oDb->getOne( $sSelect );
00841     }
00842 
00850     public function getSqlActiveSnippet( $blForceCoreTable = null )
00851     {
00852         $sQ = '';
00853         $sTable = $this->getViewName($blForceCoreTable);
00854 
00855         // has 'active' field ?
00856         if ( isset( $this->_aFieldNames['oxactive'] ) ) {
00857             $sQ = " $sTable.oxactive = 1 ";
00858         }
00859 
00860         // has 'activefrom'/'activeto' fields ?
00861         if ( isset( $this->_aFieldNames['oxactivefrom'] ) && isset( $this->_aFieldNames['oxactiveto'] ) ) {
00862 
00863             $sDate = date( 'Y-m-d H:i:s', oxRegistry::get("oxUtilsDate")->getTime() );
00864 
00865             $sQ = $sQ?" $sQ or ":'';
00866             $sQ = " ( $sQ ( $sTable.oxactivefrom < '$sDate' and $sTable.oxactiveto > '$sDate' ) ) ";
00867         }
00868 
00869         return $sQ;
00870     }
00871 
00880     public function beforeUpdate( $sOXID = null )
00881     {
00882     }
00883 
00894     public function onChange( $iAction = null, $sOXID = null)
00895     {
00896     }
00897 
00898 
00904     public function setInList()
00905     {
00906         $this->_blIsInList = true;
00907     }
00908 
00914     protected function _isInList()
00915     {
00916         return $this->_blIsInList;
00917     }
00918 
00927     protected function _getObjectViewName( $sTable, $sShopID = null)
00928     {
00929         return getViewName( $sTable, -1, $sShopID);
00930     }
00931 
00932 
00943     protected function _getTableFields($sTable, $blReturnSimple = false)
00944     {
00945         $myUtils = oxRegistry::getUtils();
00946 
00947         $sCacheKey   = $sTable . "_allfields_" . $blReturnSimple;
00948         $aMetaFields = $myUtils->fromFileCache( $sCacheKey );
00949 
00950         if ( $aMetaFields ) {
00951             return $aMetaFields;
00952         }
00953 
00954         $aMetaFields = oxDb::getInstance()->getTableDescription( $sTable );
00955 
00956         if ( !$blReturnSimple ) {
00957             $myUtils->toFileCache( $sCacheKey, $aMetaFields );
00958             return $aMetaFields;
00959         }
00960 
00961         //returning simple array
00962         $aRet = array();
00963         if (is_array($aMetaFields)) {
00964             foreach ( $aMetaFields as $oVal ) {
00965                 $aRet[strtolower( $oVal->name )] = 0;
00966             }
00967         }
00968 
00969         $myUtils->toFileCache( $sCacheKey, $aRet);
00970 
00971         return $aRet;
00972     }
00973 
00985     protected function _getAllFields($blReturnSimple = false)
00986     {
00987         if (!$this->_sCoreTable) {
00988             return array();
00989         }
00990         return $this->_getTableFields($this->_sCoreTable, $blReturnSimple);
00991     }
00992 
01001     protected function _initDataStructure($blForceFullStructure = false)
01002     {
01003         $myUtils = oxRegistry::getUtils();
01004 
01005         //get field names from cache
01006         $aFieldNames = null;
01007         $sFullCacheKey = 'fieldnames_' .$this->_sCoreTable . "_" . $this->_sCacheKey;
01008         if ($this->_sCacheKey && !$this->_isDisabledFieldCache()) {
01009             $aFieldNames = $myUtils->fromFileCache($sFullCacheKey);
01010         }
01011 
01012         if (!$aFieldNames) {
01013             $aFieldNames = $this->_getNonCachedFieldNames($blForceFullStructure);
01014             if ($this->_sCacheKey && !$this->_isDisabledFieldCache()) {
01015                 $myUtils->toFileCache($sFullCacheKey, $aFieldNames);
01016             }
01017         }
01018 
01019         if ( $aFieldNames !== false ) {
01020             foreach ( $aFieldNames as $sField => $sStatus ) {
01021                 $this->_addField($sField, $sStatus);
01022             }
01023         }
01024     }
01025 
01037     protected function _getNonCachedFieldNames($blForceFullStructure = false)
01038     {
01039         //T2008-02-22
01040         //so if this method is executed on cached version we see it when profiling
01041         startProfile("!__CACHABLE__!");
01042 
01043         //case 1. (admin)
01044         if ($this->isAdmin()) {
01045             $aMetaFields = $this->_getAllFields();
01046             foreach ( $aMetaFields as $oField ) {
01047                 if ( $oField->max_length == -1 ) {
01048                     $oField->max_length = 10;      // double or float
01049                 }
01050 
01051                 if ( $oField->type == "datetime" ) {
01052                     $oField->max_length = 20;
01053                 }
01054 
01055                 $this->_addField( $oField->name, $this->_getFieldStatus($oField->name), $oField->type, $oField->max_length );
01056             }
01057             stopProfile("!__CACHABLE__!");
01058             return false;
01059         }
01060 
01061         //case 2. (just get all fields)
01062         if ( $blForceFullStructure || !$this->_blUseLazyLoading ) {
01063             $aMetaFields = $this->_getAllFields(true);
01064             /*
01065             foreach ( $aMetaFields as $sFieldName => $sVal) {
01066                 $this->_addField( $sFieldName, $this->_getFieldStatus($sFieldName));
01067             }*/
01068             stopProfile("!__CACHABLE__!");
01069             return $aMetaFields;
01070         }
01071 
01072         //case 3. (get only oxid field, so we can fetch the rest of the fields over lazy loading mechanism)
01073         stopProfile("!__CACHABLE__!");
01074         return array("oxid" => 0);
01075     }
01076 
01085     protected function _getFieldStatus( $sFieldName )
01086     {
01087         return 0;
01088     }
01089 
01100     protected function _addField($sName, $iStatus, $sType = null, $sLength = null)
01101     {
01102         //preparation
01103         $sName = strtolower( $sName );
01104 
01105         //adding field names element
01106         $this->_aFieldNames[$sName] = $iStatus;
01107 
01108         //allready set?
01109         $sLongName = $this->_getFieldLongName($sName);
01110         if ( isset($this->$sLongName) ) {
01111             return;
01112         }
01113 
01114         //defining the field
01115         $oField = false;
01116 
01117         if ( isset( $sType ) ) {
01118             $oField = new oxField();
01119             $oField->fldtype = $sType;
01120             //T2008-01-29
01121             //can't clone as the fields are objects and are not fully cloned
01122             $this->_blIsSimplyClonable = false;
01123         }
01124 
01125         if ( isset( $sLength ) ) {
01126             if ( !$oField ) {
01127                 $oField = new oxField();
01128             }
01129             $oField->fldmax_length = $sLength;
01130             $this->_blIsSimplyClonable = false;
01131         }
01132 
01133         $this->$sLongName = $oField;
01134     }
01135 
01143     protected function _getFieldLongName( $sFieldName )
01144     {
01145         //trying to avoid strpos call as often as possible
01146         if ( $sFieldName[2] == $this->_sCoreTable[2] && strpos( $sFieldName, $this->_sCoreTable . "__" ) === 0 ) {
01147             return $sFieldName;
01148         }
01149 
01150         return $this->_sCoreTable . "__" . strtolower( $sFieldName );
01151     }
01152 
01162     protected function _setFieldData( $sFieldName, $sValue, $iDataType = oxField::T_TEXT)
01163     {
01164 
01165         $sLongFieldName = $this->_getFieldLongName( $sFieldName);
01166         //$sLongFieldName = $this->_sCoreTable . "__" . strtolower($sFieldName);
01167 
01168         //T2008-03-14
01169         //doing this because in lazy loaded lists on first load it is harmful to have initilised fields but not yet set
01170         //situation: only first article is loaded fully for "select oxid from oxarticles"
01171         /*
01172         if ($this->_blUseLazyLoading && !isset($this->$sLongFieldName))
01173             return;*/
01174 
01175         //in non lazy loading case we just add a field and do not care about it more
01176         if (!$this->_blUseLazyLoading && !isset($this->$sLongFieldName)) {
01177             $aFields = $this->_getAllFields(true);
01178             if ( isset( $aFields[strtolower($sFieldName)] ) ) {
01179                 $this->_addField($sFieldName, $this->_getFieldStatus($sFieldName));
01180             }
01181         }
01182         // if we have a double field we replace "," with "." in case somebody enters it in european format
01183         if (isset($this->$sLongFieldName) && isset($this->$sLongFieldName->fldtype) && $this->$sLongFieldName->fldtype == "double") {
01184             $sValue = str_replace( ",", ".", $sValue );
01185         }
01186 
01187         // isset is REQUIRED here not to use getter
01188         if (isset($this->$sLongFieldName) && is_object($this->$sLongFieldName)) {
01189             $this->$sLongFieldName->setValue($sValue, $iDataType);
01190         } else {
01191             $this->$sLongFieldName = new oxField($sValue, $iDataType);
01192         }
01193 
01194     }
01195 
01203     protected function _canFieldBeNull( $sFieldName )
01204     {
01205         $aMetaData = $this->_getAllFields();
01206         foreach ( $aMetaData as $oMetaInfo ) {
01207             if ( strcasecmp( $oMetaInfo->name, $sFieldName ) == 0 ) {
01208                 return !$oMetaInfo->not_null;
01209             }
01210         }
01211         return false;
01212     }
01213 
01214 
01222     protected function _getFieldDefaultValue( $sFieldName )
01223     {
01224         $aMetaData = $this->_getAllFields();
01225         foreach ( $aMetaData as $oMetaInfo ) {
01226             if ( strcasecmp( $oMetaInfo->name, $sFieldName ) == 0 ) {
01227                 return $oMetaInfo->default_value;
01228             }
01229         }
01230         return false;
01231     }
01232 
01233 
01242     protected function _getUpdateFieldValue( $sFieldName, $oField )
01243     {
01244         $mValue = null;
01245         if ( $oField instanceof oxField ) {
01246             $mValue = $oField->getRawValue();
01247         } elseif ( isset( $oField->value ) ) {
01248             $mValue = $oField->value;
01249         }
01250 
01251         $oDb = oxDb::getDb();
01252         //Check if this field value is null AND it can be null according if not returning default value
01253         if ( ( null === $mValue ) ) {
01254             if ( $this->_canFieldBeNull( $sFieldName ) ) {
01255                 return 'null';
01256             } elseif ( $mValue = $this->_getFieldDefaultValue( $sFieldName ) ) {
01257                 return $oDb->quote( $mValue );
01258             }
01259         }
01260 
01261         return $oDb->quote( $mValue );
01262     }
01263 
01272     protected function _getUpdateFields( $blUseSkipSaveFields = true )
01273     {
01274         $sSql = '';
01275         $blSep  = false;
01276 
01277         foreach (array_keys($this->_aFieldNames) as $sKey) {
01278             $sLongName = $this->_getFieldLongName($sKey);
01279             $oField = $this->$sLongName;
01280 
01281 
01282             if ( !$blUseSkipSaveFields || ($blUseSkipSaveFields && !in_array(strtolower($sKey), $this->_aSkipSaveFields)) ) {
01283                 $sSql .= (( $blSep) ? ',':'' ).$sKey." = ".$this->_getUpdateFieldValue($sKey, $oField);
01284                 $blSep = true;
01285             }
01286         }
01287 
01288         return $sSql;
01289     }
01290 
01300     protected function _update()
01301     {
01302         //do not allow derived item update
01303         if ( !$this->allowDerivedUpdate() ) {
01304             return false;
01305         }
01306 
01307 
01308         if ( !$this->getId() ) {
01309             $oEx = oxNew( 'oxObjectException' );
01310             $oEx->setMessage( 'EXCEPTION_OBJECT_OXIDNOTSET' );
01311             $oEx->setObject($this);
01312             throw $oEx;
01313         }
01314 
01315         $sIDKey = oxRegistry::getUtils()->getArrFldName( $this->_sCoreTable.".oxid");
01316         $this->$sIDKey = new oxField($this->getId(), oxField::T_RAW);
01317         $oDb = oxDb::getDb();
01318 
01319         $sUpdate= "update {$this->_sCoreTable} set ".$this->_getUpdateFields()
01320                  ." where {$this->_sCoreTable}.oxid = ".$oDb->quote( $this->getId() );
01321 
01322         //trigger event
01323         $this->beforeUpdate();
01324 
01325         $blRet = (bool) $oDb->execute( $sUpdate);
01326 
01327         return $blRet;
01328     }
01329 
01337     protected function _insert()
01338     {
01339 
01340         $oDb      = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
01341         $myConfig = $this->getConfig();
01342         $myUtils  = oxRegistry::getUtils();
01343 
01344         // let's get a new ID
01345         if ( !$this->getId()) {
01346             $this->setId();
01347         }
01348 
01349         $sIDKey = $myUtils->getArrFldName( $this->_sCoreTable.".oxid");
01350         $this->$sIDKey = new oxField($this->getId(), oxField::T_RAW);
01351         $sInsert= "Insert into {$this->_sCoreTable} set ";
01352 
01353         //setting oxshopid
01354         $sShopField = $myUtils->getArrFldName($this->_sCoreTable.".oxshopid");
01355 
01356         if (isset($this->$sShopField) && !$this->$sShopField->value) {
01357             $this->$sShopField = new oxField($myConfig->getShopId(), oxField::T_RAW);
01358         }
01359 
01360 
01361         $sInsert .= $this->_getUpdateFields( $this->getUseSkipSaveFields() );
01362 
01363         $blRet = (bool) $oDb->execute( $sInsert);
01364 
01365         return $blRet;
01366     }
01367 
01374     protected function _isDisabledFieldCache()
01375     {
01376         $sClass = get_class($this);
01377         if (isset(self::$_blDisableFieldCaching[$sClass]) && self::$_blDisableFieldCaching[$sClass]) {
01378             return true;
01379         }
01380 
01381         return false;
01382     }
01383 
01389     public function isOx()
01390     {
01391         $sOxId = $this->getId();
01392         if ( $sOxId[0] == 'o' && $sOxId[1] == 'x' ) {
01393             return true;
01394         }
01395         return false;
01396     }
01397 
01403     public function isReadOnly()
01404     {
01405         return $this->_blReadOnly;
01406     }
01407 
01415     public function setReadOnly( $blReadOnly )
01416     {
01417         $this->_blReadOnly = $blReadOnly;
01418     }
01419 
01425     public function getFieldNames()
01426     {
01427         return array_keys( $this->_aFieldNames );
01428     }
01429 
01437     public function addFieldName( $sName )
01438     {
01439         //preparation
01440         $sName = strtolower( $sName );
01441         $this->_aFieldNames[$sName] = 0;
01442     }
01443 
01444 
01450     public function getLanguage()
01451     {
01452         return -1;
01453     }
01454 }