eZ Publish  [trunk]
ezmultipricetype.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZMultiPriceType class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package kernel
00009  */
00010 
00011 /*!
00012   \class eZMultiPriceType ezmultipricetype.php
00013   \ingroup eZMultiDatatype
00014   \brief Stores a price in multicurrency.
00015 
00016 */
00017 
00018 class eZMultiPriceType extends eZDataType
00019 {
00020     const DATA_TYPE_STRING = 'ezmultiprice';
00021     const DEFAULT_CURRENCY_CODE_FIELD = 'data_text1';
00022     const DEFAULT_CURRENCY_CODE_VARIABLE = '_ezmultiprice_currency_code_';
00023     const INCLUDE_VAT_FIELD = 'data_int1';
00024     const INCLUDE_VAT_VARIABLE = '_ezmultiprice_include_vat_';
00025     const VAT_ID_FIELD = 'data_float1';
00026     const VAT_ID_VARIABLE = '_ezmultiprice_vat_id_';
00027     const INCLUDED_VAT = 1;
00028     const EXCLUDED_VAT = 2;
00029 
00030     function eZMultiPriceType()
00031     {
00032         $this->eZDataType( self::DATA_TYPE_STRING, ezpI18n::tr( 'kernel/classes/datatypes', 'Multi-price', 'Datatype name' ),
00033                             array( 'serialize_supported' => true ) );
00034     }
00035 
00036     /*!
00037      Validates the input and returns true if the input was
00038      valid for this datatype.
00039     */
00040     function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00041     {
00042         // Check "price inc/ex VAT" and "VAT type" fields.
00043         $vatTypeID = $http->postVariable( $base . '_ezmultiprice_vat_id_' . $contentObjectAttribute->attribute( 'id' ) );
00044         $vatExInc = $http->postVariable( $base . '_ezmultiprice_inc_ex_vat_' . $contentObjectAttribute->attribute( 'id' ) );
00045 
00046 
00047         if ( $vatExInc == 1 && $vatTypeID == -1 )
00048         {
00049             $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes',
00050                                                                  'Dynamic VAT cannot be included.' ) );
00051             return eZInputValidator::STATE_INVALID;
00052         }
00053 
00054         // Check price.
00055         if ( $http->hasPostVariable( $base . '_price_array_' . $contentObjectAttribute->attribute( "id" ) ) )
00056         {
00057             $customPriceList = $http->postVariable( $base . '_price_array_' . $contentObjectAttribute->attribute( "id" ) );
00058             foreach ( $customPriceList as $currencyCode => $value )
00059             {
00060                 if( $contentObjectAttribute->validateIsRequired() || ( $value != '' ) )
00061                 {
00062                     if ( !preg_match( "#^[0-9]+(.){0,1}[0-9]{0,2}$#", $value ) )
00063                     {
00064                         $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes',
00065                                                                              "Invalid price for '%currencyCode' currency ",
00066                                                                              false,
00067                                                                              array( '%currencyCode' => $currencyCode ) ) );
00068                         return eZInputValidator::STATE_INVALID;
00069                     }
00070                 }
00071             }
00072         }
00073         else if ( $contentObjectAttribute->validateIsRequired() )
00074         {
00075             $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes', 'Input required' ) );
00076             return eZInputValidator::STATE_INVALID;
00077         }
00078 
00079         return eZInputValidator::STATE_ACCEPTED;
00080     }
00081 
00082     function storeObjectAttribute( $attribute )
00083     {
00084         $multiprice = $attribute->attribute( 'content' );
00085         $multiprice->store();
00086     }
00087 
00088     /*!
00089      Set default class attribute value
00090     */
00091     function initializeClassAttribute( $classAttribute )
00092     {
00093         if ( $classAttribute->attribute( self::INCLUDE_VAT_FIELD ) == 0 )
00094             $classAttribute->setAttribute( self::INCLUDE_VAT_FIELD, self::INCLUDED_VAT );
00095         $classAttribute->store();
00096     }
00097 
00098     /*!
00099      Sets the default value.
00100     */
00101     function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
00102     {
00103         if ( $currentVersion != false )
00104         {
00105             $dataText = $originalContentObjectAttribute->attribute( 'data_text' );
00106             $contentObjectAttribute->setAttribute( "data_text", $dataText );
00107         }
00108     }
00109 
00110     /*!
00111      Set default object attribute value.
00112     */
00113     function postInitializeObjectAttribute( $objectAttribute, $currentVersion, $originalContentObjectAttribute )
00114     {
00115         $contentClassAttribute = $objectAttribute->contentClassAttribute();
00116         $multiprice = new eZMultiPrice( $contentClassAttribute, $objectAttribute );
00117 
00118         if ( $currentVersion == false )
00119         {
00120             $defaultCurrency = $contentClassAttribute->attribute( self::DEFAULT_CURRENCY_CODE_FIELD );
00121             $multiprice->setCustomPrice( $defaultCurrency, '0.00' );
00122             $multiprice->updateAutoPriceList();
00123             $multiprice->store();
00124         }
00125         else
00126         {
00127             $originalMultiprice = $originalContentObjectAttribute->content();
00128             $multiprice = new eZMultiPrice( $contentClassAttribute, $objectAttribute );
00129 
00130             foreach ( $originalMultiprice->priceList() as $price )
00131             {
00132                 $multiprice->setPriceByCurrency( $price->attribute( 'currency_code' ), $price->attribute( 'value' ), $price->attribute( 'type') );
00133             }
00134 
00135             $multiprice->store();
00136         }
00137     }
00138 
00139     function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
00140     {
00141         $currencyCodeVariable = $base . self::DEFAULT_CURRENCY_CODE_VARIABLE . $classAttribute->attribute( 'id' );
00142         if ( $http->hasPostVariable( $currencyCodeVariable ) )
00143         {
00144             $currencyCode = $http->postVariable( $currencyCodeVariable );
00145             $classAttribute->setAttribute( self::DEFAULT_CURRENCY_CODE_FIELD, $currencyCode );
00146         }
00147 
00148         $isVatIncludedVariable = $base . self::INCLUDE_VAT_VARIABLE . $classAttribute->attribute( 'id' );
00149         if ( $http->hasPostVariable( $isVatIncludedVariable ) )
00150         {
00151             $isVatIncluded = $http->postVariable( $isVatIncludedVariable );
00152             $classAttribute->setAttribute( self::INCLUDE_VAT_FIELD, $isVatIncluded );
00153         }
00154         $vatIDVariable = $base . self::VAT_ID_VARIABLE . $classAttribute->attribute( 'id' );
00155         if ( $http->hasPostVariable( $vatIDVariable  ) )
00156         {
00157             $vatID = $http->postVariable( $vatIDVariable  );
00158             $classAttribute->setAttribute( self::VAT_ID_FIELD, $vatID );
00159         }
00160         return true;
00161     }
00162 
00163     /*!
00164      Fetches the http post var integer input and stores it in the data instance.
00165     */
00166     function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00167     {
00168         $multiprice = $contentObjectAttribute->attribute( 'content' );
00169 
00170         $priceArrayName = $base . "_price_array_" . $contentObjectAttribute->attribute( "id" );
00171         if ( $http->hasPostVariable( $priceArrayName ) )
00172         {
00173             $customPriceList = $http->postVariable( $priceArrayName );
00174 
00175             foreach ( $customPriceList as $currencyCode => $value )
00176                 $multiprice->setCustomPrice( $currencyCode, $value );
00177         }
00178 
00179         $multiprice->updateAutoPriceList();
00180 
00181         $vatType = $http->postVariable( $base . '_ezmultiprice_vat_id_' . $contentObjectAttribute->attribute( 'id' ) );
00182         $vatExInc = $http->postVariable( $base . '_ezmultiprice_inc_ex_vat_' . $contentObjectAttribute->attribute( 'id' ) );
00183         $multiprice->setAttribute( 'selected_vat_type', $vatType );
00184         $multiprice->setAttribute( 'is_vat_included', $vatExInc );
00185 
00186         $data_text = $vatType . ',' . $vatExInc;
00187         $contentObjectAttribute->setAttribute( 'data_text', $data_text );
00188 
00189         return true;
00190     }
00191 
00192     /*!
00193      Returns the content.
00194     */
00195     function objectAttributeContent( $contentObjectAttribute )
00196     {
00197         $classAttribute = $contentObjectAttribute->contentClassAttribute();
00198         $multiprice = new eZMultiPrice( $classAttribute, $contentObjectAttribute );
00199 
00200         if ( $contentObjectAttribute->attribute( 'data_text' ) != '' )
00201         {
00202             list( $vatType, $vatExInc ) = explode( ',', $contentObjectAttribute->attribute( 'data_text' ), 2 );
00203 
00204             $multiprice->setAttribute( 'selected_vat_type', $vatType );
00205             $multiprice->setAttribute( 'is_vat_included', $vatExInc );
00206         }
00207 
00208         return $multiprice;
00209     }
00210 
00211     /*!
00212      Returns class content.
00213     */
00214     function classAttributeContent( $classAttribute )
00215     {
00216         $contentObjectAttribute = false;
00217         $multiprice = new eZMultiPrice( $classAttribute, $contentObjectAttribute );
00218         return $multiprice;
00219     }
00220 
00221     function customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters )
00222     {
00223         switch ( $action )
00224         {
00225             case 'set_custom_price' :
00226             {
00227                 $selectedCurrencyName = 'ContentObjectAttribute' . '_selected_currency_' . $contentObjectAttribute->attribute( 'id' );
00228                 if ( $http->hasPostVariable( $selectedCurrencyName ) )
00229                 {
00230                     $selectedCurrency = $http->postVariable( $selectedCurrencyName );
00231                     $multiprice = $contentObjectAttribute->content();
00232 
00233                     // to keep right order of currency after adding we do 'remove' and 'add'
00234                     // instead of just '$multiprice->setCustomPrice( $currencyCode, false )'
00235                     $price = $multiprice->priceByCurrency( $selectedCurrency );
00236                     $multiprice->removePriceByCurrency( $selectedCurrency );
00237                     $multiprice->setCustomPrice( $selectedCurrency, $price->attribute( 'value' ) );
00238 
00239                     $multiprice->store();
00240                 }
00241             }break;
00242 
00243             case 'remove_prices' :
00244             {
00245                 $removePriceArrayName = 'ContentObjectAttribute' . '_remove_price_array_' . $contentObjectAttribute->attribute( 'id' );
00246                 if ( $http->hasPostVariable( $removePriceArrayName ) )
00247                 {
00248                     $removePriceArray = $http->postVariable( $removePriceArrayName );
00249                     $multiprice = $contentObjectAttribute->content();
00250 
00251                     foreach( $removePriceArray as $currencyCode => $value )
00252                         $multiprice->setAutoPrice( $currencyCode, false );
00253 
00254                     $multiprice->updateAutoPriceList();
00255                     $multiprice->store();
00256                 }
00257             }break;
00258 
00259             default :
00260             {
00261                 eZDebug::writeError( 'Unknown custom HTTP action: ' . $action, 'eZMultiPriceType' );
00262             }break;
00263         }
00264     }
00265 
00266     /**
00267      * Return content action(s) which can be performed on object containing
00268      * the current datatype. Return format is array of arrays with key 'name'
00269      * and 'action'. 'action' can be mapped to url in datatype.ini
00270      *
00271      * @param eZContentClassAttribute $classAttribute
00272      * @return array
00273     */
00274     function contentActionList( $classAttribute )
00275     {
00276         $actionList = parent::contentActionList( $classAttribute );
00277         $actionList[] = array( 'name' => ezpI18n::tr( 'kernel/classes/datatypes', 'Add to basket' ),
00278                                'action' => 'ActionAddToBasket'
00279         );
00280         $actionList[] = array( 'name' => ezpI18n::tr( 'kernel/classes/datatypes', 'Add to wish list' ),
00281                                'action' => 'ActionAddToWishList'
00282         );
00283         return $actionList;
00284     }
00285 
00286     /*!
00287      Clean up stored object attribute
00288     */
00289     function deleteStoredObjectAttribute( $objectAttribute, $version = null )
00290     {
00291         eZMultiPrice::removeByID( $objectAttribute->attribute( 'id' ), $version );
00292     }
00293 
00294     function title( $contentObjectAttribute, $name = null )
00295     {
00296         return '';
00297     }
00298 
00299     function hasObjectAttributeContent( $contentObjectAttribute )
00300     {
00301         return true;
00302     }
00303 
00304     function toString( $contentObjectAttribute )
00305     {
00306 
00307         $multiprice = $contentObjectAttribute->attribute( 'content' );
00308 
00309         $priceList = $multiprice->attribute( 'price_list' );
00310 
00311         $priceArray = explode( ',', $contentObjectAttribute->attribute( 'data_text' ) );
00312         foreach ( $priceList as $priceData )
00313         {
00314             $type = $priceData->attribute( 'type' );
00315             if ( $type == 1 )
00316             {
00317                 $type = 'CUSTOM';
00318             }
00319             else if ( $type == 2 )
00320             {
00321                 $type = 'AUTO';
00322             }
00323             else
00324                 $type = 'LIMIT';
00325             $priceArray = array_merge(  $priceArray, array( $priceData->attribute( 'currency_code'), $priceData->attribute( 'value' ), $type ) );
00326         }
00327         return eZStringUtils::implodeStr( $priceArray, '|' );
00328     }
00329 
00330 
00331     function fromString( $contentObjectAttribute, $string )
00332     {
00333         if ( $string == '' )
00334             return true;
00335 
00336         $multiprice = $contentObjectAttribute->attribute( 'content' );
00337 
00338         $multipriceData =  eZStringUtils::explodeSTR( $string, '|' );
00339 
00340         $vatType = array_shift( $multipriceData );
00341         $vatExInc = array_shift( $multipriceData );
00342 
00343         $contentObjectAttribute->setAttribute( 'data_text', $vatType . ',' . $vatExInc );
00344 
00345         while ( $multipriceData )
00346         {
00347             $currencyCode = array_shift( $multipriceData );
00348             $value = array_shift( $multipriceData );
00349 
00350             $type = array_shift( $multipriceData );
00351             if ( $type == 'CUSTOM' )
00352             {
00353                 $type = 1;
00354             }
00355             else if ( $type == 'AUTO' )
00356             {
00357                 $type = 2;
00358             }
00359             else
00360                 $type = 5000;
00361 
00362             $multiprice->setPriceByCurrency( $currencyCode, $value, $type );
00363 
00364         }
00365         $multiprice->store();
00366         return $multiprice;
00367 
00368     }
00369 
00370     function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00371     {
00372         $price = $classAttribute->content();
00373         if ( $price )
00374         {
00375             $vatIncluded = $price->attribute( 'is_vat_included' );
00376             $vatTypes = $price->attribute( 'vat_type' );
00377 
00378             $dom = $attributeParametersNode->ownerDocument;
00379             $vatIncludedNode = $dom->createElement( 'vat-included' );
00380             $vatIncludedNode->setAttribute( 'is-set', $vatIncluded ? 'true' : 'false' );
00381             $attributeParametersNode->appendChild( $vatIncludedNode );
00382             $vatTypeNode = $dom->createElement( 'vat-type' );
00383             $chosenVatType = $classAttribute->attribute( self::VAT_ID_FIELD );
00384             $gotVat = false;
00385             foreach ( $vatTypes as $vatType )
00386             {
00387                 $id = $vatType->attribute( 'id' );
00388                 if ( $id == $chosenVatType )
00389                 {
00390                     $vatTypeNode->setAttribute( 'name', $vatType->attribute( 'name' ) );
00391                     $vatTypeNode->setAttribute( 'percentage', $vatType->attribute( 'percentage' ) );
00392                     $gotVat = true;
00393                     break;
00394                 }
00395             }
00396             if ( $gotVat )
00397                 $attributeParametersNode->appendChild( $vatTypeNode );
00398 
00399             $defualtCurrency = $classAttribute->attribute( self::DEFAULT_CURRENCY_CODE_FIELD );
00400             $defaultCurrencyNode = $dom->createElement( 'default-currency' );
00401             $defaultCurrencyNode->setAttribute( 'code', $defualtCurrency );
00402             $attributeParametersNode->appendChild( $defaultCurrencyNode );
00403         }
00404     }
00405 
00406     function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00407     {
00408         $vatNode = $attributeParametersNode->getElementsByTagName( 'vat-included' )->item( 0 );
00409         $vatIncluded = strtolower( $vatNode->getAttribute( 'is-set' ) ) == 'true';
00410         if ( $vatIncluded )
00411             $vatIncluded = self::INCLUDED_VAT;
00412         else
00413             $vatIncluded = self::EXCLUDED_VAT;
00414 
00415         $classAttribute->setAttribute( self::INCLUDE_VAT_FIELD, $vatIncluded );
00416         $vatTypeNode = $attributeParametersNode->getElementsByTagName( 'vat-type' )->item( 0 );
00417         $vatName = $vatTypeNode->getAttribute( 'name' );
00418         $vatPercentage = $vatTypeNode->getAttribute( 'percentage' );
00419         $vatID = false;
00420         $vatTypes = eZVatType::fetchList();
00421         foreach ( $vatTypes as $vatType )
00422         {
00423             if ( $vatType->attribute( 'name' ) == $vatName and
00424                  $vatType->attribute( 'percentage' ) == $vatPercentage )
00425             {
00426                 $vatID = $vatType->attribute( 'id' );
00427                 break;
00428             }
00429         }
00430         if ( !$vatID )
00431         {
00432             $vatType = eZVatType::create();
00433             $vatType->setAttribute( 'name', $vatName );
00434             $vatType->setAttribute( 'percentage', $vatPercentage );
00435             $vatType->store();
00436             $vatID = $vatType->attribute( 'id' );
00437         }
00438         $classAttribute->setAttribute( self::VAT_ID_FIELD, $vatID );
00439 
00440         $defaultCurrency = $attributeParametersNode->getElementsByTagName( 'default-currency' )->item( 0 );
00441         $currencyCode = $defaultCurrency->getAttribute( 'code' );
00442         $classAttribute->setAttribute( self::DEFAULT_CURRENCY_CODE_FIELD, $currencyCode );
00443     }
00444 
00445 
00446     function serializeContentObjectAttribute( $package, $objectAttribute )
00447     {
00448         $node = $this->createContentObjectAttributeDOMNode( $objectAttribute );
00449 
00450         $multiprice = $objectAttribute->content();
00451         $domDocument = $multiprice->DOMDocument();
00452 
00453         $importedRoot = $node->ownerDocument->importNode( $domDocument->documentElement, true );
00454         $node->appendChild( $importedRoot );
00455 
00456         return $node;
00457     }
00458 
00459     function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode )
00460     {
00461         $rootNode = $attributeNode->getElementsByTagName( 'ezmultiprice' )->item( 0 );
00462 
00463         $multiprice = $objectAttribute->content();
00464         $multiprice->decodeDOMTree( $rootNode );
00465     }
00466 
00467     function customSorting()
00468     {
00469         return true;
00470     }
00471 
00472     function customSortingSQL( $params )
00473     {
00474         $multipriceTableAlias = "mp";
00475 
00476         if ( isset( $params['table_alias_suffix'] ) )
00477             $multipriceTableAlias .= $params['table_alias_suffix'];
00478 
00479         $sql = array( 'from' => '',
00480                       'where' => '',
00481                       'sorting_field' => '' );
00482 
00483         $sql['from'] =  "ezmultipricedata $multipriceTableAlias";
00484 
00485         $and = '';
00486         if ( isset( $params['contentobject_attr_id'] ) )
00487         {
00488             $sql['where'] = "
00489                      $multipriceTableAlias.contentobject_attr_id = {$params['contentobject_attr_id']}";
00490             $and = ' AND';
00491         }
00492 
00493         if ( isset( $params['contentobject_attr_version'] ) )
00494         {
00495             $sql['where'] .= "
00496                     $and $multipriceTableAlias.contentobject_attr_version = {$params['contentobject_attr_version']}";
00497             $and = ' AND';
00498         }
00499 
00500         if ( !isset( $params['currency_code'] ) )
00501         {
00502             $params['currency_code'] = eZShopFunctions::preferredCurrencyCode();
00503         }
00504 
00505         if ( $params['currency_code'] !== false )
00506         {
00507             $sql['where'] .= "
00508                     $and $multipriceTableAlias.currency_code = '{$params['currency_code']}'";
00509             $and = ' AND';
00510         }
00511 
00512         $sql['sorting_field'] = "$multipriceTableAlias.value";
00513 
00514         return $sql;
00515     }
00516 
00517     function diff( $old, $new, $options = false )
00518     {
00519         return null;
00520     }
00521 
00522     function supportsBatchInitializeObjectAttribute()
00523     {
00524         return true;
00525     }
00526 }
00527 
00528 eZDataType::register( eZMultiPriceType::DATA_TYPE_STRING, "eZMultiPriceType" );
00529 
00530 ?>