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