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 
00090     protected $_blUseSkipSaveFields = true;
00091 
00096     protected $_sExistKey = 'oxid';
00097 
00104     protected $_blIsDerived = null;
00105 
00115     protected static $_blDisableFieldCaching = array();
00116 
00122     protected $_blIsSeoObject = false;
00123 
00129     protected $_blReadOnly = false;
00130 
00136     protected $_blIsInList = false;
00137 
00143     protected $_isLoaded = false;
00144 
00150     protected $_aInnerLazyCache = null;
00151 
00157     protected $_blEmployMultilanguage = false;
00158 
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         if ( $sTableName ) {
00377             $this->_sCoreTable = $sTableName;
00378         }
00379 
00380         // reset view table
00381         $this->_sViewTable = false;
00382 
00383         if ( count( $this->_aFieldNames ) <= 1 ) {
00384             $this->_initDataStructure( $blForceAllFields );
00385         }
00386     }
00387 
00395     public function assign( $dbRecord )
00396     {
00397         if ( !is_array( $dbRecord ) ) {
00398             return;
00399         }
00400 
00401 
00402         reset($dbRecord );
00403         while ( list( $sName, $sValue ) = each( $dbRecord ) ) {
00404 
00405             // patch for IIS
00406             //TODO: test it on IIS do we still need it
00407             //if( is_array($value) && count( $value) == 1)
00408             //    $value = current( $value);
00409 
00410             $this->_setFieldData( $sName, $sValue );
00411         }
00412 
00413         $sOxidField = $this->_getFieldLongName( 'oxid' );
00414         $this->_sOXID = $this->$sOxidField->value;
00415 
00416     }
00417 
00423     public function getClassName()
00424     {
00425         return $this->_sClassName;
00426     }
00427 
00433     public function getCoreTableName()
00434     {
00435         return $this->_sCoreTable;
00436     }
00437 
00443     public function getId()
00444     {
00445         return $this->_sOXID;
00446     }
00447 
00455     public function setId( $sOXID = null )
00456     {
00457         if ( $sOXID ) {
00458             $this->_sOXID = $sOXID;
00459         } else {
00460             $this->_sOXID = oxUtilsObject::getInstance()->generateUID();
00461         }
00462 
00463         $sIdVarName = $this->_sCoreTable . '__oxid';
00464         $this->$sIdVarName = new oxField($this->_sOXID, oxField::T_RAW);
00465 
00466         return $this->_sOXID;
00467     }
00468 
00476     public function setShopId( $iShopId )
00477     {
00478         $this->_iShopId = $iShopId;
00479     }
00480 
00486     public function getShopId()
00487     {
00488         return $this->_iShopId;
00489     }
00490 
00498     public function getViewName( $blForceCoreTableUsage = null )
00499     {
00500         if (!$this->_sViewTable || ( $blForceCoreTableUsage !== null )) {
00501             if ( $blForceCoreTableUsage === true ) {
00502                 return $this->_sCoreTable;
00503             }
00504 
00505 
00506             if ( ( $blForceCoreTableUsage !== null ) && $blForceCoreTableUsage ) {
00507                 $iShopId = -1;
00508             } else {
00509                 $iShopId = oxRegistry::getConfig()->getShopId();
00510             }
00511 
00512             $sViewName = getViewName( $this->_sCoreTable, $this->_blEmployMultilanguage == false ? -1 : $this->getLanguage(), $iShopId );
00513             if ( $blForceCoreTableUsage !== null ) {
00514                 return $sViewName;
00515             }
00516             $this->_sViewTable = $sViewName;
00517         }
00518         return $this->_sViewTable;
00519     }
00520 
00529     public function modifyCacheKey( $sCacheKey, $blOverride = false )
00530     {
00531         if ( $blOverride ) {
00532             $this->_sCacheKey = $sCacheKey;
00533         } else {
00534             $this->_sCacheKey .= $sCacheKey;
00535         }
00536     }
00537 
00543     public function disableLazyLoading()
00544     {
00545         $this->_blUseLazyLoading = false;
00546         $this->_initDataStructure(true);
00547     }
00548 
00549 
00555     public function isDerived()
00556     {
00557 
00558         return $this->_blIsDerived;
00559     }
00560 
00568     public function setIsDerived( $blVal )
00569     {
00570         $this->_blIsDerived = $blVal;
00571     }
00572 
00579     public function isMultilang()
00580     {
00581         return false;
00582     }
00583 
00593     public function load( $sOXID )
00594     {
00595 
00596         //getting at least one field before lazy loading the object
00597         $this->_addField( 'oxid', 0 );
00598         $sSelect = $this->buildSelectString( array( $this->getViewName() . '.oxid' => $sOXID) );
00599         $this->_isLoaded = $this->assignRecord( $sSelect );
00600 
00601 
00602         return $this->_isLoaded;
00603     }
00604 
00610     public function isLoaded()
00611     {
00612         return $this->_isLoaded;
00613     }
00614 
00622     public function buildSelectString( $aWhere = null)
00623     {
00624         $oDB = oxDb::getDb();
00625 
00626         $sGet = $this->getSelectFields();
00627         $sSelect = "select $sGet from " . $this->getViewName() . ' where 1 ';
00628 
00629         if ( $aWhere) {
00630             reset($aWhere);
00631             while (list($name, $value) = each($aWhere)) {
00632                 $sSelect .=  ' and ' . $name . ' = '.$oDB->quote($value);
00633             }
00634         }
00635 
00636         // add active shop
00637 
00638         return $sSelect;
00639     }
00640 
00648     public function assignRecord( $sSelect )
00649     {
00650         $blRet = false;
00651 
00652         $rs = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->select( $sSelect );
00653 
00654         if ($rs != false && $rs->recordCount() > 0) {
00655             $blRet = true;
00656             $this->assign( $rs->fields);
00657         }
00658 
00659         return $blRet;
00660     }
00661 
00669     public function getFieldData( $sFieldName )
00670     {
00671         $sLongFieldName = $this->_getFieldLongName( $sFieldName );
00672             return $this->$sLongFieldName->value;
00673     }
00674 
00682     public function getSelectFields( $blForceCoreTableUsage = null )
00683     {
00684         $aSelectFields = array();
00685 
00686         $sViewName = $this->getViewName( $blForceCoreTableUsage );
00687 
00688         foreach ( $this->_aFieldNames as $sKey => $sField ) {
00689             if ( $sViewName ) {
00690                 $aSelectFields[] = "`$sViewName`.`$sKey`";
00691             } else {
00692                 $aSelectFields[] = ".`$sKey`";
00693             }
00694 
00695         }
00696 
00697         $sSelectFields = join( ', ', $aSelectFields );
00698         return $sSelectFields;
00699     }
00700 
00708     public function delete( $sOXID = null)
00709     {
00710         if ( !$sOXID ) {
00711             $sOXID = $this->getId();
00712 
00713             //do not allow derived deletion
00714             if ( !$this->allowDerivedDelete() ) {
00715                 return false;
00716             }
00717         }
00718 
00719         if ( !$sOXID ) {
00720             return false;
00721         }
00722 
00723 
00724         $oDB = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00725         $sDelete = "delete from $this->_sCoreTable where oxid = " . $oDB->quote( $sOXID );
00726         $oDB->execute( $sDelete );
00727         if ( $blDelete = ( bool ) $oDB->affected_Rows() ) {
00728             $this->onChange( ACTION_DELETE, $sOXID );
00729         }
00730 
00731         return $blDelete;
00732     }
00733 
00734 
00740     public function save()
00741     {
00742         if ( !is_array( $this->_aFieldNames ) ) {
00743             return false;
00744         }
00745 
00746         // #739A - should be executed here because of date/time formatting feature
00747         if ( $this->isAdmin() && !$this->getConfig()->getConfigParam( 'blSkipFormatConversion' ) ) {
00748             foreach ($this->_aFieldNames as $sName => $sVal) {
00749                 $sLongName = $this->_getFieldLongName($sName);
00750                 if ( isset($this->$sLongName->fldtype) && $this->$sLongName->fldtype == 'datetime' ) {
00751                     oxRegistry::get('oxUtilsDate')->convertDBDateTime( $this->$sLongName, true );
00752                 } elseif ( isset($this->$sLongName->fldtype) && $this->$sLongName->fldtype == 'timestamp' ) {
00753                     oxRegistry::get('oxUtilsDate')->convertDBTimestamp( $this->$sLongName, true );
00754                 } elseif ( isset($this->$sLongName->fldtype) && $this->$sLongName->fldtype == 'date' ) {
00755                     oxRegistry::get('oxUtilsDate')->convertDBDate( $this->$sLongName, true );
00756                 }
00757             }
00758         }
00759         if ( $this->exists() ) {
00760             //do not allow derived update
00761             if ( !$this->allowDerivedUpdate() ) {
00762                 return false;
00763             }
00764 
00765             $blRet = $this->_update();
00766             $sAction = ACTION_UPDATE;
00767         } else {
00768             $blRet = $this->_insert();
00769             $sAction = ACTION_INSERT;
00770         }
00771 
00772         $this->onChange($sAction);
00773 
00774         if ( $blRet ) {
00775             return $this->getId();
00776         } else {
00777             return false;
00778         }
00779     }
00780 
00786     public function allowDerivedUpdate()
00787     {
00788         return !$this->isDerived();
00789     }
00790 
00796     public function allowDerivedDelete()
00797     {
00798         return !$this->isDerived();
00799     }
00800 
00808     public function exists( $sOXID = null)
00809     {
00810         if ( !$sOXID ) {
00811             $sOXID = $this->getId();
00812         }
00813         if ( !$sOXID ) {
00814             return false;
00815         }
00816 
00817         $sViewName = $this->getCoreTableName();
00818         $oDb = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00819         $sSelect= "select {$this->_sExistKey} from {$sViewName} where {$this->_sExistKey} = " . $oDb->quote( $sOXID );
00820 
00821         return ( bool ) $oDb->getOne( $sSelect, false, false );
00822     }
00823 
00831     public function getSqlActiveSnippet( $blForceCoreTable = null )
00832     {
00833         $sQ = '';
00834         $sTable = $this->getViewName($blForceCoreTable);
00835 
00836         // has 'active' field ?
00837         if ( isset( $this->_aFieldNames['oxactive'] ) ) {
00838             $sQ = " $sTable.oxactive = 1 ";
00839         }
00840 
00841         // has 'activefrom'/'activeto' fields ?
00842         if ( isset( $this->_aFieldNames['oxactivefrom'] ) && isset( $this->_aFieldNames['oxactiveto'] ) ) {
00843 
00844             $sDate = date( 'Y-m-d H:i:s', oxRegistry::get('oxUtilsDate')->getTime() );
00845 
00846             $sQ = $sQ ? " $sQ or " : '';
00847             $sQ = " ( $sQ ( $sTable.oxactivefrom < '$sDate' and $sTable.oxactiveto > '$sDate' ) ) ";
00848         }
00849 
00850         return $sQ;
00851     }
00852 
00861     public function beforeUpdate( $sOXID = null )
00862     {
00863     }
00864 
00875     public function onChange( $iAction = null, $sOXID = null )
00876     {
00877     }
00878 
00879 
00885     public function setInList()
00886     {
00887         $this->_blIsInList = true;
00888     }
00889 
00895     protected function _isInList()
00896     {
00897         return $this->_blIsInList;
00898     }
00899 
00908     protected function _getObjectViewName( $sTable, $sShopID = null )
00909     {
00910         return getViewName( $sTable, -1, $sShopID);
00911     }
00912 
00913 
00924     protected function _getTableFields($sTable, $blReturnSimple = false )
00925     {
00926         $myUtils = oxRegistry::getUtils();
00927 
00928         $sCacheKey   = $sTable . '_allfields_' . $blReturnSimple;
00929         $aMetaFields = $myUtils->fromFileCache( $sCacheKey );
00930 
00931         if ( $aMetaFields ) {
00932             return $aMetaFields;
00933         }
00934 
00935         $aMetaFields = oxDb::getInstance()->getTableDescription( $sTable );
00936 
00937         if ( !$blReturnSimple ) {
00938             $myUtils->toFileCache( $sCacheKey, $aMetaFields );
00939             return $aMetaFields;
00940         }
00941 
00942         //returning simple array
00943         $aRet = array();
00944         if (is_array($aMetaFields)) {
00945             foreach ( $aMetaFields as $oVal ) {
00946                 $aRet[strtolower( $oVal->name )] = 0;
00947             }
00948         }
00949 
00950         $myUtils->toFileCache( $sCacheKey, $aRet);
00951 
00952         return $aRet;
00953     }
00954 
00966     protected function _getAllFields($blReturnSimple = false )
00967     {
00968         if (!$this->_sCoreTable) {
00969             return array();
00970         }
00971         return $this->_getTableFields($this->_sCoreTable, $blReturnSimple);
00972     }
00973 
00982     protected function _initDataStructure($blForceFullStructure = false )
00983     {
00984         $myUtils = oxRegistry::getUtils();
00985 
00986         //get field names from cache
00987         $aFieldNames = null;
00988         $sFullCacheKey = 'fieldnames_' . $this->_sCoreTable . '_' . $this->_sCacheKey;
00989         if ($this->_sCacheKey && !$this->_isDisabledFieldCache()) {
00990             $aFieldNames = $myUtils->fromFileCache( $sFullCacheKey );
00991         }
00992 
00993         if (!$aFieldNames) {
00994             $aFieldNames = $this->_getNonCachedFieldNames( $blForceFullStructure );
00995             if ($this->_sCacheKey && !$this->_isDisabledFieldCache()) {
00996                 $myUtils->toFileCache( $sFullCacheKey, $aFieldNames );
00997             }
00998         }
00999 
01000         if ( $aFieldNames !== false ) {
01001             foreach ( $aFieldNames as $sField => $sStatus ) {
01002                 $this->_addField( $sField, $sStatus );
01003             }
01004         }
01005     }
01006 
01018     protected function _getNonCachedFieldNames( $blForceFullStructure = false )
01019     {
01020         //T2008-02-22
01021         //so if this method is executed on cached version we see it when profiling
01022         startProfile('!__CACHABLE__!');
01023 
01024         //case 1. (admin)
01025         if ($this->isAdmin()) {
01026             $aMetaFields = $this->_getAllFields();
01027             foreach ( $aMetaFields as $oField ) {
01028                 if ( $oField->max_length == -1 ) {
01029                     $oField->max_length = 10;      // double or float
01030                 }
01031 
01032                 if ( $oField->type == 'datetime' ) {
01033                     $oField->max_length = 20;
01034                 }
01035 
01036                 $this->_addField( $oField->name, $this->_getFieldStatus($oField->name), $oField->type, $oField->max_length );
01037             }
01038             stopProfile('!__CACHABLE__!');
01039             return false;
01040         }
01041 
01042         //case 2. (just get all fields)
01043         if ( $blForceFullStructure || !$this->_blUseLazyLoading ) {
01044             $aMetaFields = $this->_getAllFields(true);
01045             /*
01046             foreach ( $aMetaFields as $sFieldName => $sVal) {
01047                 $this->_addField( $sFieldName, $this->_getFieldStatus($sFieldName));
01048             }*/
01049             stopProfile('!__CACHABLE__!');
01050             return $aMetaFields;
01051         }
01052 
01053         //case 3. (get only oxid field, so we can fetch the rest of the fields over lazy loading mechanism)
01054         stopProfile('!__CACHABLE__!');
01055         return array('oxid' => 0);
01056     }
01057 
01066     protected function _getFieldStatus( $sFieldName )
01067     {
01068         return 0;
01069     }
01070 
01081     protected function _addField($sName, $iStatus, $sType = null, $sLength = null )
01082     {
01083         //preparation
01084         $sName = strtolower( $sName );
01085 
01086         //adding field names element
01087         $this->_aFieldNames[$sName] = $iStatus;
01088 
01089         //already set?
01090         $sLongName = $this->_getFieldLongName( $sName );
01091         if ( isset($this->$sLongName) ) {
01092             return;
01093         }
01094 
01095         //defining the field
01096         $oField = false;
01097 
01098         if ( isset( $sType ) ) {
01099             $oField = new oxField();
01100             $oField->fldtype = $sType;
01101             //T2008-01-29
01102             //can't clone as the fields are objects and are not fully cloned
01103             $this->_blIsSimplyClonable = false;
01104         }
01105 
01106         if ( isset( $sLength ) ) {
01107             if ( !$oField ) {
01108                 $oField = new oxField();
01109             }
01110             $oField->fldmax_length = $sLength;
01111             $this->_blIsSimplyClonable = false;
01112         }
01113 
01114         $this->$sLongName = $oField;
01115     }
01116 
01124     protected function _getFieldLongName( $sFieldName )
01125     {
01126         //trying to avoid strpos call as often as possible
01127         if ( $sFieldName[2] == $this->_sCoreTable[2] && strpos( $sFieldName, $this->_sCoreTable . '__' ) === 0 ) {
01128             return $sFieldName;
01129         }
01130 
01131         return $this->_sCoreTable . '__' . strtolower( $sFieldName );
01132     }
01133 
01143     protected function _setFieldData( $sFieldName, $sValue, $iDataType = oxField::T_TEXT )
01144     {
01145 
01146         $sLongFieldName = $this->_getFieldLongName( $sFieldName);
01147         //$sLongFieldName = $this->_sCoreTable . "__" . strtolower($sFieldName);
01148 
01149         //T2008-03-14
01150         //doing this because in lazy loaded lists on first load it is harmful to have initialised fields but not yet set
01151         //situation: only first article is loaded fully for "select oxid from oxarticles"
01152         /*
01153         if ($this->_blUseLazyLoading && !isset($this->$sLongFieldName))
01154             return;*/
01155 
01156         //in non lazy loading case we just add a field and do not care about it more
01157         if (!$this->_blUseLazyLoading && !isset( $this->$sLongFieldName )) {
01158             $aFields = $this->_getAllFields(true);
01159             if ( isset( $aFields[strtolower( $sFieldName )] ) ) {
01160                 $this->_addField( $sFieldName, $this->_getFieldStatus( $sFieldName ) );
01161             }
01162         }
01163         // if we have a double field we replace "," with "." in case somebody enters it in european format
01164         if (isset($this->$sLongFieldName) && isset( $this->$sLongFieldName->fldtype ) && $this->$sLongFieldName->fldtype == 'double') {
01165             $sValue = str_replace( ',', '.', $sValue );
01166         }
01167 
01168         // isset is REQUIRED here not to use getter
01169         if ( isset( $this->$sLongFieldName ) && is_object( $this->$sLongFieldName ) ) {
01170             $this->$sLongFieldName->setValue( $sValue, $iDataType );
01171         } else {
01172             $this->$sLongFieldName = new oxField( $sValue, $iDataType );
01173         }
01174 
01175     }
01176 
01184     protected function _canFieldBeNull( $sFieldName )
01185     {
01186         $aMetaData = $this->_getAllFields();
01187         foreach ( $aMetaData as $oMetaInfo ) {
01188             if ( strcasecmp( $oMetaInfo->name, $sFieldName ) == 0 ) {
01189                 return !$oMetaInfo->not_null;
01190             }
01191         }
01192         return false;
01193     }
01194 
01202     protected function _getFieldDefaultValue( $sFieldName )
01203     {
01204         $aMetaData = $this->_getAllFields();
01205         foreach ( $aMetaData as $oMetaInfo ) {
01206             if ( strcasecmp( $oMetaInfo->name, $sFieldName ) == 0 ) {
01207                 return $oMetaInfo->default_value;
01208             }
01209         }
01210         return false;
01211     }
01212 
01221     protected function _getUpdateFieldValue( $sFieldName, $oField )
01222     {
01223         $mValue = null;
01224         if ( $oField instanceof oxField ) {
01225             $mValue = $oField->getRawValue();
01226         } elseif ( isset( $oField->value ) ) {
01227             $mValue = $oField->value;
01228         }
01229 
01230         $oDb = oxDb::getDb();
01231         //Check if this field value is null AND it can be null according if not returning default value
01232         if ( ( null === $mValue ) ) {
01233             if ( $this->_canFieldBeNull( $sFieldName ) ) {
01234                 return 'null';
01235             } elseif ( $mValue = $this->_getFieldDefaultValue( $sFieldName ) ) {
01236                 return $oDb->quote( $mValue );
01237             }
01238         }
01239 
01240         return $oDb->quote( $mValue );
01241     }
01242 
01251     protected function _getUpdateFields( $blUseSkipSaveFields = true )
01252     {
01253         $sSql = '';
01254         $blSep  = false;
01255 
01256         foreach ( array_keys( $this->_aFieldNames ) as $sKey ) {
01257             $sLongName = $this->_getFieldLongName( $sKey );
01258             $oField = $this->$sLongName;
01259 
01260 
01261             if ( !$blUseSkipSaveFields || ( $blUseSkipSaveFields && !in_array( strtolower( $sKey ), $this->_aSkipSaveFields ) ) ) {
01262                 $sSql .= (( $blSep) ? ',' : '' ) . $sKey . ' = ' . $this->_getUpdateFieldValue( $sKey, $oField );
01263                 $blSep = true;
01264             }
01265         }
01266 
01267         return $sSql;
01268     }
01269 
01279     protected function _update()
01280     {
01281         //do not allow derived item update
01282         if ( !$this->allowDerivedUpdate() ) {
01283             return false;
01284         }
01285 
01286 
01287         if ( !$this->getId() ) {
01291             $oEx = oxNew( 'oxObjectException' );
01292             $oEx->setMessage( 'EXCEPTION_OBJECT_OXIDNOTSET' );
01293             $oEx->setObject($this);
01294             throw $oEx;
01295         }
01296 
01297         $sIDKey = oxRegistry::getUtils()->getArrFldName( $this->_sCoreTable . '.oxid' );
01298         $this->$sIDKey = new oxField($this->getId(), oxField::T_RAW);
01299         $oDb = oxDb::getDb();
01300 
01301         $sUpdate= "update {$this->_sCoreTable} set " . $this->_getUpdateFields()
01302                  ." where {$this->_sCoreTable}.oxid = " . $oDb->quote( $this->getId() );
01303 
01304         //trigger event
01305         $this->beforeUpdate();
01306 
01307         $blRet = (bool) $oDb->execute( $sUpdate );
01308 
01309         return $blRet;
01310     }
01311 
01319     protected function _insert()
01320     {
01321 
01322         $oDb      = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
01323         $myConfig = $this->getConfig();
01324         $myUtils  = oxRegistry::getUtils();
01325 
01326         // let's get a new ID
01327         if ( !$this->getId()) {
01328             $this->setId();
01329         }
01330 
01331         $sIDKey = $myUtils->getArrFldName( $this->_sCoreTable . '.oxid' );
01332         $this->$sIDKey = new oxField( $this->getId(), oxField::T_RAW );
01333         $sInsert = "Insert into {$this->_sCoreTable} set ";
01334 
01335         //setting oxshopid
01336         $sShopField = $myUtils->getArrFldName( $this->_sCoreTable . '.oxshopid' );
01337 
01338         if ( isset( $this->$sShopField ) && !$this->$sShopField->value ) {
01339             $this->$sShopField = new oxField( $myConfig->getShopId(), oxField::T_RAW );
01340         }
01341 
01342 
01343         $sInsert .= $this->_getUpdateFields( $this->getUseSkipSaveFields() );
01344 
01345         $blRet = (bool) $oDb->execute( $sInsert );
01346 
01347         return $blRet;
01348     }
01349 
01356     protected function _isDisabledFieldCache()
01357     {
01358         $sClass = get_class( $this );
01359         if ( isset( self::$_blDisableFieldCaching[$sClass] ) && self::$_blDisableFieldCaching[$sClass] ) {
01360             return true;
01361         }
01362 
01363         return false;
01364     }
01365 
01371     public function isOx()
01372     {
01373         $sOxId = $this->getId();
01374         if ( $sOxId[0] == 'o' && $sOxId[1] == 'x' ) {
01375             return true;
01376         }
01377         return false;
01378     }
01379 
01385     public function isReadOnly()
01386     {
01387         return $this->_blReadOnly;
01388     }
01389 
01397     public function setReadOnly( $blReadOnly )
01398     {
01399         $this->_blReadOnly = $blReadOnly;
01400     }
01401 
01407     public function getFieldNames()
01408     {
01409         return array_keys( $this->_aFieldNames );
01410     }
01411 
01419     public function addFieldName( $sName )
01420     {
01421         //preparation
01422         $sName = strtolower( $sName );
01423         $this->_aFieldNames[$sName] = 0;
01424     }
01425 
01426 
01432     public function getLanguage()
01433     {
01434         return -1;
01435     }
01436 
01437 }