PageRenderTime 1ms CodeModel.GetById 53ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/app/code/core/Mage/Catalog/Model/Product/Option/Api.php

https://bitbucket.org/tschrock52/ethodeshare
PHP | 327 lines | 207 code | 13 blank | 107 comment | 22 complexity | 94f0b60ba05920963dd13f4c2324abe5 MD5 | raw file
  1<?php
  2/**
  3 * Magento
  4 *
  5 * NOTICE OF LICENSE
  6 *
  7 * This source file is subject to the Open Software License (OSL 3.0)
  8 * that is bundled with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://opensource.org/licenses/osl-3.0.php
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@magentocommerce.com so we can send you a copy immediately.
 14 *
 15 * DISCLAIMER
 16 *
 17 * Do not edit or add to this file if you wish to upgrade Magento to newer
 18 * versions in the future. If you wish to customize Magento for your
 19 * needs please refer to http://www.magentocommerce.com for more information.
 20 *
 21 * @category    Mage
 22 * @package     Mage_Catalog
 23 * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
 24 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 25 */
 26
 27/**
 28 * Catalog product options api
 29 *
 30 * @category   Mage
 31 * @package    Mage_Catalog
 32 * @author     Magento Core Team <core@magentocommerce.com>
 33 */
 34class Mage_Catalog_Model_Product_Option_Api extends Mage_Catalog_Model_Api_Resource
 35{
 36
 37    /**
 38     * Add custom option to product
 39     *
 40     * @param string $productId
 41     * @param array $data
 42     * @param int|string|null $store
 43     * @return bool $isAdded
 44     */
 45    public function add($productId, $data, $store = null)
 46    {
 47        $product = $this->_getProduct($productId, $store, null);
 48        if (!(is_array($data['additional_fields']) and count($data['additional_fields']))) {
 49            $this->_fault('invalid_data');
 50        }
 51        if (!$this->_isTypeAllowed($data['type'])) {
 52            $this->_fault('invalid_type');
 53        }
 54        $this->_prepareAdditionalFields(
 55            $data,
 56            $product->getOptionInstance()->getGroupByType($data['type'])
 57        );
 58        $this->_saveProductCustomOption($product, $data);
 59        return true;
 60    }
 61
 62    /**
 63     * Update product custom option data
 64     *
 65     * @param string $optionId
 66     * @param array $data
 67     * @param int|string|null $store
 68     * @return bool
 69     */
 70    public function update($optionId, $data, $store = null)
 71    {
 72        /** @var $option Mage_Catalog_Model_Product_Option */
 73        $option = Mage::getModel('catalog/product_option')->load($optionId);
 74        if (!$option->getId()) {
 75            $this->_fault('option_not_exists');
 76        }
 77        $product = $this->_getProduct($option->getProductId(), $store, null);
 78        $option = $product->getOptionById($optionId);
 79        if (isset($data['type']) and !$this->_isTypeAllowed($data['type'])) {
 80            $this->_fault('invalid_type');
 81        }
 82        if (isset($data['additional_fields'])) {
 83            $this->_prepareAdditionalFields(
 84                $data,
 85                $option->getGroupByType()
 86            );
 87        }
 88        foreach ($option->getValues() as $valueId => $value) {
 89            if(isset($data['values'][$valueId])) {
 90                $data['values'][$valueId] = array_merge($value->getData(), $data['values'][$valueId]);
 91            }
 92        }
 93        $data = array_merge($option->getData(), $data);
 94        $this->_saveProductCustomOption($product, $data);
 95        return true;
 96    }
 97
 98    /**
 99     * Prepare custom option data for saving by model. Used for custom option add and update
100     *
101     * @param array $data
102     * @param string $groupType
103     * @return void
104     */
105    protected function _prepareAdditionalFields(&$data, $groupType)
106    {
107        if (is_array($data['additional_fields'])) {
108            if ($groupType != Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT) {
109                // reset can be used as there should be the only
110                // element in 'additional_fields' for options of all types except those from Select group
111                $field = reset($data['additional_fields']);
112                if (!(is_array($field) and count($field))) {
113                    $this->_fault('invalid_data');
114                } else {
115                    foreach ($field as $key => $value) {
116                        $data[$key] = $value;
117                    }
118                }
119            } else {
120                // convert Select rows array to appropriate format for saving in the model
121                foreach ($data['additional_fields'] as $row) {
122                    if (!(is_array($row) and count($row))) {
123                        $this->_fault('invalid_data');
124                    } else {
125                        foreach ($row as $key => $value) {
126                            $row[$key] = Mage::helper('catalog')->stripTags($value);
127                        }
128                        if (!empty($row['value_id'])) {
129                            // map 'value_id' to 'option_type_id'
130                            $row['option_type_id'] = $row['value_id'];
131                            unset($row['value_id']);
132                            $data['values'][$row['option_type_id']] = $row;
133                        } else {
134                            $data['values'][] = $row;
135                        }
136                    }
137                }
138            }
139        }
140        unset($data['additional_fields']);
141    }
142
143    /**
144     * Save product custom option data. Used for custom option add and update.
145     *
146     * @param Mage_Catalog_Model_Product $product
147     * @param array $data
148     * @return void
149     */
150    protected function _saveProductCustomOption($product, $data)
151    {
152        foreach ($data as $key => $value) {
153            if (is_string($value)) {
154                $data[$key] = Mage::helper('catalog')->stripTags($value);
155            }
156        }
157        // setProductOptions expects data to be an array of options arrays
158        $data = array($data);
159        if (!$product->getOptionsReadonly()) {
160            $product->setProductOptions($data);
161        }
162        $product->setCanSaveCustomOptions(!$product->getOptionsReadonly());
163        try {
164            // an empty request can be set as event parameter
165            // because it is not used for options changing in observers
166            Mage::dispatchEvent(
167                'catalog_product_prepare_save',
168                array('product' => $product, 'request' => new Mage_Core_Controller_Request_Http())
169            );
170            $product->save();
171        } catch (Exception $e) {
172            $this->_fault('save_option_error', $e->getMessage());
173        }
174    }
175
176    /**
177     * Read list of possible custom option types from module config
178     *
179     * @return array
180     */
181    public function types()
182    {
183        $path = Mage_Adminhtml_Model_System_Config_Source_Product_Options_Type::PRODUCT_OPTIONS_GROUPS_PATH;
184        $types = array();
185        foreach (Mage::getConfig()->getNode($path)->children() as $group) {
186            $groupTypes = Mage::getConfig()->getNode($path . '/' . $group->getName() . '/types')->children();
187            /** @var $type Mage_Core_Model_Config_Element */
188            foreach($groupTypes as $type){
189                $labelPath = $path . '/' . $group->getName() . '/types/' . $type->getName() . '/label';
190                $types[] = array(
191                    'label' => (string) Mage::getConfig()->getNode($labelPath),
192                    'value' => $type->getName()
193                );
194            }
195        }
196        return $types;
197    }
198
199    /**
200     * Get full information about custom option in product
201     *
202     * @param int|string $optionId
203     * @param  int|string|null $store
204     * @return array
205     */
206    public function info($optionId, $store = null)
207    {
208        /** @var $option Mage_Catalog_Model_Product_Option */
209        $option = Mage::getModel('catalog/product_option')->load($optionId);
210        if (!$option->getId()) {
211            $this->_fault('option_not_exists');
212        }
213        /** @var $product Mage_Catalog_Model_Product */
214        $product = $this->_getProduct($option->getProductId(), $store, null);
215        $option = $product->getOptionById($optionId);
216        $result = array(
217            'title' => $option->getTitle(),
218            'type' => $option->getType(),
219            'is_require' => $option->getIsRequire(),
220            'sort_order' => $option->getSortOrder(),
221            // additional_fields should be two-dimensional array for all option types
222            'additional_fields' => array(
223                array(
224                    'price' => $option->getPrice(),
225                    'price_type' => $option->getPriceType(),
226                    'sku' => $option->getSku()
227                )
228            )
229        );
230        // Set additional fields to each type group
231        switch ($option->getGroupByType()) {
232            case Mage_Catalog_Model_Product_Option::OPTION_GROUP_TEXT:
233                $result['additional_fields'][0]['max_characters'] = $option->getMaxCharacters();
234                break;
235            case Mage_Catalog_Model_Product_Option::OPTION_GROUP_FILE:
236                $result['additional_fields'][0]['file_extension'] = $option->getFileExtension();
237                $result['additional_fields'][0]['image_size_x'] = $option->getImageSizeX();
238                $result['additional_fields'][0]['image_size_y'] = $option->getImageSizeY();
239                break;
240            case Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT:
241                $result['additional_fields'] = array();
242                foreach ($option->getValuesCollection() as $value) {
243                    $result['additional_fields'][] = array(
244                        'value_id' => $value->getId(),
245                        'title' => $value->getTitle(),
246                        'price' => $value->getPrice(),
247                        'price_type' => $value->getPriceType(),
248                        'sku' => $value->getSku(),
249                        'sort_order' => $value->getSortOrder()
250                    );
251                }
252                break;
253            default:
254                break;
255        }
256
257        return $result;
258    }
259
260    /**
261     * Retrieve list of product custom options
262     *
263     * @param  string $productId
264     * @param  int|string|null $store
265     * @return array
266     */
267    public function items($productId, $store = null)
268    {
269        $result = array();
270        $product = $this->_getProduct($productId, $store, null);
271        /** @var $option Mage_Catalog_Model_Product_Option */
272        foreach ($product->getProductOptionsCollection() as $option) {
273            $result[] = array(
274                'option_id' => $option->getId(),
275                'title' => $option->getTitle(),
276                'type' => $option->getType(),
277                'is_require' => $option->getIsRequire(),
278                'sort_order' => $option->getSortOrder()
279            );
280        }
281        return $result;
282    }
283
284    /**
285     * Remove product custom option
286     *
287     * @param string $optionId
288     * @return boolean
289     */
290    public function remove($optionId)
291    {
292        /** @var $option Mage_Catalog_Model_Product_Option */
293        $option = Mage::getModel('catalog/product_option')->load($optionId);
294        if (!$option->getId()) {
295            $this->_fault('option_not_exists');
296        }
297        try {
298            $option->getValueInstance()->deleteValue($optionId);
299            $option->deletePrices($optionId);
300            $option->deleteTitles($optionId);
301            $option->delete();
302        } catch (Exception $e){
303            $this->fault('delete_option_error');
304        }
305        return true;
306    }
307
308    /**
309     * Check is type in allowed set
310     *
311     * @param string $type
312     * @return bool
313     */
314    protected function _isTypeAllowed($type)
315    {
316        $allowedTypes = array();
317        foreach($this->types() as $optionType){
318            $allowedTypes[] = $optionType['value'];
319        }
320
321        if (!in_array($type, $allowedTypes)) {
322            return false;
323        }
324        return true;
325    }
326
327}