eZ Publish  [trunk]
ezmultioption.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZOption 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 eZMultiOption ezmultioption.php
00013   \ingroup eZDatatype
00014   \brief Encapsulates multiple options in one datatype.
00015 
00016   This class encapsulates multiple options by storing an array
00017   with multioption elements each containing a list of options.
00018   Managing multioptions is done using addMultiOption(), removeMultiOption() and changeMultiOption().
00019   For a multioption you can add and remove options with addOption() and removeOptions().
00020   For storage use the xmlString() and decodeXML() methods.
00021 
00022   A \a multioption is a list of the group of options.
00023   All multioption's name are displayed simultaneously.
00024 
00025   Multioption consists of id, name, priority and default_option_id.
00026   - id                : is a unique representation of all multioptions.
00027   - name              : name of multioption.
00028   - priority          : Priority value is is used to sort the multioption after sorting
00029                         it will change the original priority value to 1,2,3...
00030   - default_option_id : is to displaying the default option from the list.
00031   - optionlist        : list of all option elements.
00032 
00033   An \a option is a list of values in which only one value can be selected
00034   at a time from drop down combobox.
00035   In the following e.g. Model-A,Model-B, Model-C are options for Model multioption
00036   and Red and Blue are options for Color multioption.
00037 
00038   Option consists of id, option_id, value and additional_price.
00039   - id               : unique representation of options in a multioption.
00040   - option_id        : option_id is unique among all options, it is used to
00041                        retrieve values for shop or similar operations.
00042   - value            : value is a string and it is a value used as display for that option.
00043   - additional_price : This is an additional price that will add to the original price
00044                        and will display in currency format for that value.
00045                        If the price value is not given then it will will not display
00046                        anything in that place.
00047 
00048   In the following example Model and Color is known as an multioption.
00049   Examples:
00050   1. If a motor car company is having different models and colors then it will be.
00051 
00052   \code
00053         CAR
00054          Model
00055              ----------------------
00056              |                 |\/|
00057              ----------------------
00058              | Model - A <A3> 100.00 |
00059              | Model - B <A3> 200.00 |
00060              | Model - C <A3> 300.00 |
00061              ----------------------
00062 
00063              Color
00064              -------------
00065              |        |\/|
00066              -------------
00067              |  Red      |
00068              |  Blue     |
00069              -------------
00070   \endcode
00071 
00072   The xmlstring for the above eg will look like as follow
00073   \code
00074   Array( [0] => Array(
00075            [id] => 1
00076            [name] => CAR
00077            [priority] => 1
00078            [default_option_id] => 2
00079            [optionlist] => Array( [0] => Array( [id] => 1 [option_id] => 1 [value] => Model-A [additional_price] => 100 )
00080                                   [1] => Array( [id] => 2 [option_id] => 2 [value] => Model-B [additional_price] => 200 )
00081                                   [2] => Array( [id] => 3 [option_id] => 5 [value] => Model-C [additional_price] => 300 )
00082                                 )
00083                      )
00084          [1] => Array(
00085            [id] => 2
00086            [name] => Color
00087            [priority] => 2
00088            [default_option_id] => 1
00089            [optionlist] => Array( [0] => Array( [id] => 1 [option_id] => 3 [value] => Red [additional_price] => )
00090                                   [1] => Array( [id] => 2 [option_id] => 4 [value] => Blue[additional_price] => )
00091                                 )
00092                      )
00093        )
00094   \endcode
00095 
00096   Example of how to crete an option, adding multioptions and options
00097   and finally retrieving the xml structure.
00098   \code
00099    $option = new eZOption( "Car" );
00100    $newID = $option->addMultiOption("Model",$priority,false);
00101       $option->addOption( $newID, "", "Model - A", "100", false );
00102       $option->addOption( $newID, "", "Model - B", "100", false );
00103       $option->addOption( $newID, "", "Model - C", "100", false );
00104 
00105    $newID = $option->addMultiOption( "Color", $priority, false );
00106       $option->addOption( $newID, "", "Red", "", false );
00107       $option->addOption( $newID, "", "Blue", "", false );
00108   // Serialize the class to an XML document
00109   $xmlString = $option->xmlString();
00110   \endcode
00111 */
00112 
00113 class eZMultiOption
00114 {
00115     /*!
00116      Initializes with empty multioption list.
00117     */
00118     function eZMultiOption( $name )
00119     {
00120         $this->Name = $name;
00121         $this->Options = array();
00122         $this->MultiOptionCount = 0;
00123         $this->OptionCounter = 0;
00124     }
00125 
00126     /*!
00127       Adds an Multioption named \a $name
00128       \param $name contains the name of multioption.
00129       \param $multiOptionPriority is stored for displaying the array in order.
00130       \param $defaultValue is stored to display the options by default.
00131       \return The ID of the multioption that was added.
00132     */
00133     function addMultiOption( $name, $multiOptionPriority, $defaultValue )
00134     {
00135         $this->MultiOptionCount += 1;
00136         $this->Options[$this->MultiOptionCount] = array( "id" => $this->MultiOptionCount,
00137                                                          "name" => $name,
00138                                                          'priority'=> $multiOptionPriority,
00139                                                          "default_option_id" => $defaultValue,
00140                                                          'optionlist' => array() );
00141         return $this->MultiOptionCount;
00142     }
00143 
00144     /*!
00145       Adds an Option to multioption \a $name
00146       \param $newID is the element key value to which the new option will be added.
00147       \param $optionValue is the original value to display for users.
00148       \param $optionAdditionalPrice is a price value that is used to store price of the option values.
00149     */
00150     function addOption( $newID, $OptionID, $optionValue, $optionAdditionalPrice )
00151     {
00152         $key = count( $this->Options[$newID]['optionlist'] ) + 1;
00153         if ( strlen( $OptionID ) == 0 )
00154         {
00155             $this->OptionCounter += 1;
00156             $OptionID = $this->OptionCounter;
00157         }
00158         $this->Options[$newID]['optionlist'][] = array( "id" => $key,
00159                                                         "option_id" => $OptionID,
00160                                                         "value" => $optionValue,
00161                                                         'additional_price' => $optionAdditionalPrice );
00162     }
00163 
00164     /*!
00165      Sorts the current multioption on the basis of it's priority value.
00166      After softing array it calles the function changeMultiOptionID,
00167      which again rearragnes the current priority value to 1,2,3......etc.
00168     */
00169     function sortMultiOptions()
00170     {
00171         usort( $this->Options, create_function( '$a, $b', 'if ( $a["priority"] == $b["priority"] ) { return 0; } return ( $a["priority"] < $b["priority"] ) ? -1 : 1;' ) );
00172         $this->changeMultiOptionID();
00173     }
00174 
00175     /*!
00176       Finds the largest \c option_id among the options and sets it as \a $this->OptionCounter
00177     */
00178     function resetOptionCounter()
00179     {
00180         $maxValue = 0;
00181         foreach ( $this->Options as $optionList )
00182         {
00183             foreach ( $optionList['optionlist'] as $option )
00184             {
00185                 if ( $maxValue < $option['option_id'] )
00186                 {
00187                     $maxValue = $option['option_id'];
00188                 }
00189             }
00190         }
00191         $this->OptionCounter = $maxValue;
00192     }
00193 
00194     /*!
00195       Change the id of multioption in ascending order.
00196     */
00197     function changeMultiOptionId()
00198     {
00199         $i = 1 ;
00200         foreach ( $this->Options as $key => $opt )
00201         {
00202             $this->Options[$key]['id'] = $i++;
00203         }
00204         $this->MultiOptionCount = $i - 1;
00205     }
00206 
00207     /*!
00208       Remove MultiOption from the array.
00209       After calling this function all the options associated with that multioption will be removed.
00210       This function also calles to changeMultiOption to reset the key value of multioption array.
00211       \param $array_remove is the array of those multiOptions which is selected to remove.
00212       \sa removeOptions()
00213     */
00214     function removeMultiOptions( $array_remove )
00215     {
00216         foreach ( $array_remove as $id )
00217         {
00218             unset( $this->Options[ $id - 1 ] );
00219         }
00220         $this->Options = array_values( $this->Options );
00221         $this->changeMultiOptionId();
00222     }
00223 
00224     /*!
00225       Remove Options from the multioption.
00226       This function first remove selected options and then reset the key value if all options for that multioption.
00227       \param $arrayRemove is a list of all array elements which is selected to remove from the multioptions.
00228       \param $optionId is the key value if multioption from which it is required to remove the options.
00229       \sa removeMultiOptions()
00230     */
00231     function removeOptions( $arrayRemove, $optionId )
00232     {
00233         foreach ( $arrayRemove as  $id )
00234         {
00235             unset( $this->Options[$optionId]['optionlist'][$id - 1] );
00236         }
00237         $this->Options = array_values( $this->Options );
00238         $i = 1;
00239         foreach ( $this->Options[$optionId]['optionlist'] as $key => $opt )
00240         {
00241             $this->Options[$optionId]['optionlist'][$key]['id'] = $i;
00242             $i++;
00243         }
00244     }
00245 
00246     /*!
00247      \return list of supported attributes
00248     */
00249     function attributes()
00250     {
00251         return array( 'name',
00252                       'multioption_list' );
00253     }
00254 
00255     /*!
00256       Returns true if object have an attribute.
00257       The valid attributes are \c name and \c multioption_list.
00258       \param $name contains the name of attribute
00259     */
00260     function hasAttribute( $name )
00261     {
00262         return in_array( $name, $this->attributes() );
00263     }
00264 
00265     /*!
00266     Returns an attribute. The valid attributes are \c name and \c multioption_list
00267     \a name contains the name of multioption
00268     \a multioption_list contains the list of all multioptions.
00269     */
00270     function attribute( $name )
00271     {
00272         switch ( $name )
00273         {
00274             case "name" :
00275             {
00276                 return $this->Name;
00277             } break;
00278 
00279             case "multioption_list" :
00280             {
00281                 return $this->Options;
00282             } break;
00283             default:
00284             {
00285                 eZDebug::writeError( "Attribute '$name' does not exist", __METHOD__ );
00286                 return null;
00287             }break;
00288         }
00289     }
00290 
00291     /*!
00292     Will decode an xml string and initialize the eZ Multi option object.
00293     If $xmlString is on empty then it will call addMultiOption() and addOption() functions
00294     to create new multioption else it will decode the xml string.
00295     \param $xmlString contains the complete data structure for multioptions.
00296     \sa xmlString()
00297     */
00298     function decodeXML( $xmlString )
00299     {
00300         $this->OptionCounter = 0;
00301         $this->Options = array();
00302         if ( $xmlString != "" )
00303         {
00304             $dom = new DOMDocument( '1.0', 'utf-8' );
00305             $success = $dom->loadXML( $xmlString );
00306 
00307             $root = $dom->documentElement;
00308             // set the name of the node
00309             $this->Name = $root->getElementsByTagName( "name" )->item( 0 )->textContent;
00310             $this->OptionCounter = $root->getAttribute( "option_counter" );
00311             $multioptionsNode = $root->getElementsByTagName( "multioptions" )->item( 0 );
00312             $multioptionsList = $multioptionsNode->getElementsByTagName( "multioption" );
00313             //Loop for MultiOptions
00314             foreach ( $multioptionsList as $multioption )
00315             {
00316                 $newID = $this->addMultiOption( $multioption->getAttribute( "name" ),
00317                                                 $multioption->getAttribute( "priority" ),
00318                                                 $multioption->getAttribute( "default_option_id" ) );
00319                 $optionNode = $multioption->getElementsByTagName( "option" );
00320                 foreach ( $optionNode as $option )
00321                 {
00322                     $this->addOption( $newID, $option->getAttribute( "option_id" ), $option->getAttribute( "value" ), $option->getAttribute( "additional_price" ) );
00323                 }
00324             }
00325         }
00326     }
00327 
00328     /*!
00329      Will return the XML string for this MultiOption set.
00330      \sa decodeXML()
00331     */
00332     function xmlString()
00333     {
00334         $doc = new DOMDocument( '1.0', 'utf-8' );
00335         $root = $doc->createElement( "ezmultioption" );
00336         $root->setAttribute( 'option_counter', $this->OptionCounter );
00337         $doc->appendChild( $root );
00338 
00339         $nameNode = $doc->createElement( 'name' );
00340         $nameNode->appendChild( $doc->createTextNode( $this->Name ) );
00341         $root->appendChild( $nameNode );
00342 
00343         $multiOptionsNode = $doc->createElement( "multioptions" );
00344         $root->appendChild( $multiOptionsNode );
00345 
00346         foreach ( $this->Options as $multioption )
00347         {
00348             unset( $multioptionNode );
00349             $multioptionNode = $doc->createElement( "multioption" );
00350             $multioptionNode->setAttribute( "id", $multioption['id'] );
00351             $multioptionNode->setAttribute( "name", $multioption['name'] );
00352             $multioptionNode->setAttribute( "priority", $multioption['priority'] );
00353             $multioptionNode->setAttribute( 'default_option_id', $multioption['default_option_id'] );
00354             foreach ( $multioption['optionlist'] as $option )
00355             {
00356                 unset( $optionNode );
00357                 $optionNode = $doc->createElement( "option" );
00358                 $optionNode->setAttribute( "id", $option['id'] );
00359                 $optionNode->setAttribute( "option_id", $option['option_id'] );
00360                 $optionNode->setAttribute( "value", $option['value'] );
00361                 $optionNode->setAttribute( 'additional_price', $option['additional_price'] );
00362                 $multioptionNode->appendChild( $optionNode );
00363             }
00364             $multiOptionsNode->appendChild( $multioptionNode );
00365         }
00366         $xml = $doc->saveXML();
00367         return $xml;
00368     }
00369 
00370     /// \privatesection
00371     /// Contains the Option name
00372     public $Name;
00373     /// Contains the Options
00374     public $Options;
00375     /// Contains the multioption counter value
00376     public $MultiOptionCount;
00377     /// Contains the option counter value
00378     public $OptionCounter;
00379 }
00380 ?>