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