eZ Publish  [trunk]
ezmultioptiontype.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZOptionType 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 eZMultiOptionType ezmultioptiontype.php
00013   \ingroup eZDatatype
00014   \brief A datatype which works with multiple options.
00015 
00016   This allows the user to add several option choices almost as if he
00017   was adding attributes with option datatypes.
00018 
00019   This class implements the interface for a datatype but passes
00020   most of the work over to the eZMultiOption class which handles
00021   parsing, storing and manipulation of multioptions and options.
00022 
00023   This datatype supports:
00024   - fetch and validation of HTTP data
00025   - search indexing
00026   - product option information
00027   - class title
00028   - class serialization
00029 
00030 */
00031 
00032 class eZMultiOptionType extends eZDataType
00033 {
00034     const DEFAULT_NAME_VARIABLE = "_ezmultioption_default_name_";
00035     const DATA_TYPE_STRING = "ezmultioption";
00036 
00037     /*!
00038      Constructor to initialize the datatype.
00039     */
00040     function eZMultiOptionType()
00041     {
00042         $this->eZDataType( self::DATA_TYPE_STRING, ezpI18n::tr( 'kernel/classes/datatypes', "Multi-option", 'Datatype name' ),
00043                            array( 'serialize_supported' => true ) );
00044     }
00045 
00046     /*!
00047      Validates the input for this datatype.
00048      \return True if input is valid.
00049     */
00050     function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00051     {
00052         $count = 0;
00053         $classAttribute = $contentObjectAttribute->contentClassAttribute();
00054         if ( $http->hasPostVariable( $base . "_data_multioption_id_" . $contentObjectAttribute->attribute( "id" ) ) )
00055         {
00056             $classAttribute = $contentObjectAttribute->contentClassAttribute();
00057             $multioptionIDArray = $http->postVariable( $base . "_data_multioption_id_" . $contentObjectAttribute->attribute( "id" ) );
00058 
00059             foreach ( $multioptionIDArray as $id )
00060             {
00061                 $multioptionName = $http->postVariable( $base . "_data_multioption_name_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id );
00062                 $optionIDArray = $http->hasPostVariable( $base . "_data_option_id_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00063                                  ? $http->postVariable( $base . "_data_option_id_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00064                                  : array();
00065                 $optionCountArray = $http->hasPostVariable( $base . "_data_option_option_id_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00066                                     ? $http->postVariable( $base . "_data_option_option_id_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00067                                     : array();
00068                 $optionValueArray = $http->hasPostVariable( $base . "_data_option_value_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00069                                     ? $http->postVariable( $base . "_data_option_value_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00070                                     : array();
00071                 $optionAdditionalPriceArray = $http->hasPostVariable( $base . "_data_option_additional_price_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00072                                               ? $http->postVariable( $base . "_data_option_additional_price_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00073                                               : array();
00074                 for ( $i = 0; $i < count( $optionIDArray ); $i++ )
00075                 {
00076                     if ( $contentObjectAttribute->validateIsRequired() and !$classAttribute->attribute( 'is_information_collector' ) )
00077                     {
00078                         if ( trim( $optionValueArray[$i] ) == "" )
00079                         {
00080                             $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes',
00081                                                                                  'The option value must be provided.' ) );
00082                             return eZInputValidator::STATE_INVALID;
00083                         }
00084                         else
00085                             ++$count;
00086                     }
00087 
00088                     if ( trim( $optionValueArray[$i] ) != "" )
00089                     {
00090                         if ( strlen( $optionAdditionalPriceArray[$i] ) && !preg_match( "#^[-|+]?[0-9]+(\.){0,1}[0-9]{0,2}$#", $optionAdditionalPriceArray[$i] ) )
00091                         {
00092                             $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes',
00093                                                                                  'The additional price for the multioption value is not valid.' ) );
00094                             return eZInputValidator::STATE_INVALID;
00095                         }
00096                     }
00097 
00098                 }
00099             }
00100         }
00101         if ( $contentObjectAttribute->validateIsRequired() and
00102                  !$classAttribute->attribute( 'is_information_collector' ) )
00103         {
00104             if ( $count == 0 )
00105             {
00106                 $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes',
00107                                                                      'At least one option is required.' ) );
00108                 return eZInputValidator::STATE_INVALID;
00109             }
00110 
00111             $optionSetName = $http->hasPostVariable( $base . "_data_optionset_name_" . $contentObjectAttribute->attribute( "id" ) )
00112                              ? $http->postVariable( $base . "_data_optionset_name_" . $contentObjectAttribute->attribute( "id" ) )
00113                              : '';
00114             if ( trim( $optionSetName ) == '' )
00115             {
00116                 $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes',
00117                                                                      'Option set name is required.' ) );
00118                 return eZInputValidator::STATE_INVALID;
00119             }
00120         }
00121 
00122 
00123         return eZInputValidator::STATE_ACCEPTED;
00124     }
00125 
00126     /*!
00127      This function calles xmlString function to create xml string and then store the content.
00128     */
00129     function storeObjectAttribute( $contentObjectAttribute )
00130     {
00131         $multioption = $contentObjectAttribute->content();
00132         $contentObjectAttribute->setAttribute( "data_text", $multioption->xmlString() );
00133     }
00134 
00135     /*!
00136      \return An eZMultiOption object which contains all the option data
00137     */
00138     function objectAttributeContent( $contentObjectAttribute )
00139     {
00140         $multioption = new eZMultiOption( "" );
00141         $multioption->decodeXML( $contentObjectAttribute->attribute( "data_text" ) );
00142         return $multioption;
00143     }
00144 
00145     function isIndexable()
00146     {
00147         return true;
00148     }
00149 
00150     /*!
00151      \return The internal XML text.
00152     */
00153     function metaData( $contentObjectAttribute )
00154     {
00155         return $contentObjectAttribute->attribute( "data_text" );
00156     }
00157 
00158     /*!
00159      Fetches the http post var integer input and stores it in the data instance.
00160     */
00161     function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00162     {
00163         $multioptionIDArray = $http->hasPostVariable( $base . "_data_multioption_id_" . $contentObjectAttribute->attribute( "id" ) )
00164                               ? $http->postVariable( $base . "_data_multioption_id_" . $contentObjectAttribute->attribute( "id" ) )
00165                               : array();
00166         $optionSetName = $http->postVariable( $base . "_data_optionset_name_" . $contentObjectAttribute->attribute( "id" ) );
00167         $multioption = new eZMultiOption( $optionSetName );
00168         foreach ( $multioptionIDArray as $id )
00169         {
00170             $multioptionName = $http->postVariable( $base . "_data_multioption_name_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id );
00171             $optionIDArray = $http->hasPostVariable( $base . "_data_option_id_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00172                              ? $http->postVariable( $base . "_data_option_id_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00173                              : array();
00174 
00175             $optionPriority = $http->postVariable( $base . "_data_multioption_priority_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id );
00176             // check to prevent PHP warning if the default choice is specified (no radio button selected)
00177             if ( $http->hasPostVariable( $base . "_data_radio_checked_" . $contentObjectAttribute->attribute("id") . '_' . $id ) )
00178                 $optionDefaultValue = $http->postVariable( $base . "_data_radio_checked_" . $contentObjectAttribute->attribute("id") . '_' . $id );
00179             else
00180                 $optionDefaultValue = '';
00181             $newID = $multioption->addMultiOption( $multioptionName,$optionPriority, $optionDefaultValue );
00182 
00183             $optionCountArray = $http->hasPostVariable( $base . "_data_option_option_id_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00184                                 ? $http->postVariable( $base . "_data_option_option_id_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00185                                 : array();
00186             $optionValueArray = $http->hasPostVariable( $base . "_data_option_value_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00187                                 ? $http->postVariable( $base . "_data_option_value_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00188                                 : array();
00189             $optionAdditionalPriceArray = $http->hasPostVariable( $base . "_data_option_additional_price_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00190                                           ? $http->postVariable( $base . "_data_option_additional_price_" . $contentObjectAttribute->attribute( "id" ) . '_' . $id )
00191                                           : array();
00192 
00193             for ( $i = 0; $i < count( $optionIDArray ); $i++ )
00194                 $multioption->addOption( $newID, $optionCountArray[$i], $optionValueArray[$i], $optionAdditionalPriceArray[$i] );
00195         }
00196 
00197         $multioption->sortMultiOptions();
00198         $multioption->resetOptionCounter();
00199         $contentObjectAttribute->setContent( $multioption );
00200         return true;
00201     }
00202 
00203     /*!
00204      Fetches the http post variables for collected information
00205     */
00206     function fetchCollectionAttributeHTTPInput( $collection, $collectionAttribute, $http, $base, $contentObjectAttribute )
00207     {
00208         $multioptionValue = $http->postVariable( $base . "_data_multioption_value_" . $contentObjectAttribute->attribute( "id" ) );
00209         $collectionAttribute->setAttribute( 'data_int', $multioptionValue );
00210         return true;
00211     }
00212 
00213     /*!
00214      This function performs specific actions.
00215 
00216      It has some special actions with parameters which is done by exploding
00217      $action into several parts with delimeter '_'.
00218      The first element is the name of specific action to perform.
00219      The second element will contain the key value or id.
00220 
00221      The various operation's that is performed by this function are as follow.
00222      - new-option - A new option is added to a multioption.
00223      - remove-selected-option - Removes a selected option.
00224      - new_multioption - Adds a new multioption.
00225      - remove_selected_multioption - Removes all multioptions given by a selection list
00226     */
00227     function customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters )
00228     {
00229         $actionlist = explode( "_", $action );
00230         if ( $actionlist[0] == "new-option" )
00231         {
00232             $multioption = $contentObjectAttribute->content();
00233 
00234             $multioption->addOption( ( $actionlist[1] - 1 ), "", "", "");
00235             $contentObjectAttribute->setContent( $multioption );
00236             $contentObjectAttribute->store();
00237         }
00238         else if ( $actionlist[0] == "remove-selected-option" )
00239         {
00240             $multioption = $contentObjectAttribute->content();
00241             $postvarname = "ContentObjectAttribute" . "_data_option_remove_" . $contentObjectAttribute->attribute( "id" ) . "_" . $actionlist[1];
00242             $array_remove = $http->hasPostVariable( $postvarname ) ? $http->postVariable( $postvarname ) : array();
00243             $multioption->removeOptions( $array_remove, $actionlist[1] - 1 );
00244             $contentObjectAttribute->setContent( $multioption );
00245             $contentObjectAttribute->store();
00246         }
00247         else
00248         {
00249             switch ( $action )
00250             {
00251                 case "new_multioption" :
00252                 {
00253                     $multioption = $contentObjectAttribute->content();
00254                     $newID = $multioption->addMultiOption( "" ,0,false );
00255                     $multioption->addOption( $newID, "", "", "" );
00256                     $multioption->addOption( $newID, "" ,"", "" );
00257                     $contentObjectAttribute->setContent( $multioption );
00258                     $contentObjectAttribute->store();
00259                 } break;
00260 
00261                 case "remove_selected_multioption":
00262                 {
00263                     $multioption = $contentObjectAttribute->content();
00264                     $postvarname = "ContentObjectAttribute" . "_data_multioption_remove_" . $contentObjectAttribute->attribute( "id" );
00265                     $array_remove = $http->hasPostVariable( $postvarname )? $http->postVariable( $postvarname ) : array();
00266                     $multioption->removeMultiOptions( $array_remove );
00267                     $contentObjectAttribute->setContent( $multioption );
00268                     $contentObjectAttribute->store();
00269                 } break;
00270 
00271                 default:
00272                 {
00273                     eZDebug::writeError( "Unknown custom HTTP action: " . $action, "eZMultiOptionType" );
00274                 } break;
00275             }
00276         }
00277     }
00278 
00279     /*!
00280      Finds the option which has the correct ID , if found it returns an option structure.
00281 
00282      \param $optionString must contain the multioption ID an underscore (_) and a the option ID.
00283     */
00284     function productOptionInformation( $objectAttribute, $optionID, $productItem )
00285     {
00286         $multioption = $objectAttribute->attribute( 'content' );
00287 
00288         foreach ( $multioption->attribute( 'multioption_list' ) as $multioptionElement )
00289         {
00290             foreach ( $multioptionElement['optionlist'] as $option )
00291             {
00292                 if ( $option['option_id'] != $optionID )
00293                     continue;
00294 
00295                 return array( 'id' => $option['option_id'],
00296                               'name' => $multioptionElement['name'],
00297                               'value' => $option['value'],
00298                               'additional_price' => $option['additional_price'] );
00299             }
00300         }
00301     }
00302 
00303     function title( $contentObjectAttribute, $name = "name" )
00304     {
00305         $multioption = $contentObjectAttribute->content();
00306         return $multioption->attribute( $name );
00307     }
00308 
00309     /*!
00310       \return \c true if there are more than one multioption in the list.
00311     */
00312     function hasObjectAttributeContent( $contentObjectAttribute )
00313     {
00314         $multioption = $contentObjectAttribute->content();
00315         $multioptions = $multioption->attribute( 'multioption_list' );
00316         return count( $multioptions ) > 0;
00317     }
00318 
00319     /*!
00320      Sets default multioption values.
00321     */
00322     function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
00323     {
00324         if ( $currentVersion == false )
00325         {
00326             $multioption = $contentObjectAttribute->content();
00327             if ( $multioption )
00328             {
00329                 $contentClassAttribute = $contentObjectAttribute->contentClassAttribute();
00330                 $multioption->setName( $contentClassAttribute->attribute( 'data_text1' ) );
00331                 $contentObjectAttribute->setAttribute( "data_text", $multioption->xmlString() );
00332                 $contentObjectAttribute->setContent( $multioption );
00333             }
00334         }
00335         else
00336         {
00337             $dataText = $originalContentObjectAttribute->attribute( "data_text" );
00338             $contentObjectAttribute->setAttribute( "data_text", $dataText );
00339         }
00340     }
00341 
00342     function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
00343     {
00344         $defaultValueName = $base . self::DEFAULT_NAME_VARIABLE . $classAttribute->attribute( 'id' );
00345         if ( $http->hasPostVariable( $defaultValueName ) )
00346         {
00347             $defaultValueValue = $http->postVariable( $defaultValueName );
00348 
00349             if ( $defaultValueValue == "" )
00350             {
00351                 $defaultValueValue = "";
00352             }
00353             $classAttribute->setAttribute( 'data_text1', $defaultValueValue );
00354             return true;
00355         }
00356         return false;
00357     }
00358 
00359     function toString( $contentObjectAttribute )
00360     {
00361 
00362         $content = $contentObjectAttribute->attribute( 'content' );
00363 
00364         $multioptionArray = array();
00365 
00366         $setName = $content->attribute( 'name' );
00367         $multioptionArray[] = $setName;
00368 
00369         $multioptionList = $content->attribute( 'multioption_list' );
00370 
00371         foreach ( $multioptionList as $key => $option )
00372         {
00373             $optionArray = array();
00374             $optionArray[] = $option['name'];
00375             $optionArray[] = $option['default_option_id'];
00376             foreach ( $option['optionlist'] as $key => $value )
00377             {
00378                 $optionArray[] = $value['value'];
00379                 $optionArray[] = $value['additional_price'];
00380             }
00381             $multioptionArray[] = eZStringUtils::implodeStr( $optionArray, '|' );
00382         }
00383         return eZStringUtils::implodeStr( $multioptionArray, "&" );
00384     }
00385 
00386 
00387     function fromString( $contentObjectAttribute, $string )
00388     {
00389         if ( $string == '' )
00390             return true;
00391 
00392         $multioptionArray = eZStringUtils::explodeStr( $string, '&' );
00393 
00394         $multioption = new eZMultiOption( "" );
00395 
00396         $multioption->OptionCounter = 0;
00397         $multioption->Options = array();
00398         $multioption->Name = array_shift( $multioptionArray );
00399         $priority = 1;
00400         foreach ( $multioptionArray as $multioptionStr )
00401         {
00402             $optionArray = eZStringUtils::explodeStr( $multioptionStr, '|' );
00403 
00404 
00405             $newID = $multioption->addMultiOption( array_shift( $optionArray ),
00406                                             $priority,
00407                                             array_shift( $optionArray ) );
00408             $optionID = 0;
00409             $count = count( $optionArray );
00410             for ( $i = 0; $i < $count; $i +=2 )
00411             {
00412                 $multioption->addOption( $newID, $optionID, array_shift( $optionArray ), array_shift( $optionArray ) );
00413                 $optionID++;
00414             }
00415             $priority++;
00416         }
00417 
00418         $contentObjectAttribute->setAttribute( "data_text", $multioption->xmlString() );
00419 
00420         return $multioption;
00421 
00422     }
00423 
00424     function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00425     {
00426         $defaultValue = $classAttribute->attribute( 'data_text1' );
00427         $dom = $attributeParametersNode->ownerDocument;
00428         $defaultValueNode = $dom->createElement( 'default-value' );
00429         $defaultValueNode->appendChild( $dom->createTextNode( $defaultValue ) );
00430         $attributeParametersNode->appendChild( $defaultValueNode );
00431     }
00432 
00433     function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00434     {
00435         $defaultValue = $attributeParametersNode->getElementsByTagName( 'default-value' )->item( 0 )->textContent;
00436         $classAttribute->setAttribute( 'data_text1', $defaultValue );
00437     }
00438 
00439     function serializeContentObjectAttribute( $package, $objectAttribute )
00440     {
00441         $node = $this->createContentObjectAttributeDOMNode( $objectAttribute );
00442 
00443         $dom = new DOMDocument( '1.0', 'utf-8' );
00444         $success = $dom->loadXML( $objectAttribute->attribute( 'data_text' ) );
00445 
00446         $importedRoot = $node->ownerDocument->importNode( $dom->documentElement, true );
00447         $node->appendChild( $importedRoot );
00448 
00449         return $node;
00450     }
00451 
00452     function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode )
00453     {
00454         $rootNode = $attributeNode->getElementsByTagName( 'ezmultioption' )->item( 0 );
00455         $xmlString = $rootNode ? $rootNode->ownerDocument->saveXML( $rootNode ) : '';
00456         $objectAttribute->setAttribute( 'data_text', $xmlString );
00457     }
00458 }
00459 
00460 eZDataType::register( eZMultiOptionType::DATA_TYPE_STRING, "eZMultiOptionType" );
00461 
00462 ?>