PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/chrisroseuk/magento19_dev
PHP | 594 lines | 266 code | 59 blank | 269 comment | 29 complexity | a343b8a7a68f6725f732eb815d3ad48a MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  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) 2014 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. * Catalog product option model
  28. *
  29. * @method Mage_Catalog_Model_Resource_Product_Option _getResource()
  30. * @method Mage_Catalog_Model_Resource_Product_Option getResource()
  31. * @method int getProductId()
  32. * @method Mage_Catalog_Model_Product_Option setProductId(int $value)
  33. * @method string getType()
  34. * @method Mage_Catalog_Model_Product_Option setType(string $value)
  35. * @method int getIsRequire()
  36. * @method Mage_Catalog_Model_Product_Option setIsRequire(int $value)
  37. * @method string getSku()
  38. * @method Mage_Catalog_Model_Product_Option setSku(string $value)
  39. * @method int getMaxCharacters()
  40. * @method Mage_Catalog_Model_Product_Option setMaxCharacters(int $value)
  41. * @method string getFileExtension()
  42. * @method Mage_Catalog_Model_Product_Option setFileExtension(string $value)
  43. * @method int getImageSizeX()
  44. * @method Mage_Catalog_Model_Product_Option setImageSizeX(int $value)
  45. * @method int getImageSizeY()
  46. * @method Mage_Catalog_Model_Product_Option setImageSizeY(int $value)
  47. * @method int getSortOrder()
  48. * @method Mage_Catalog_Model_Product_Option setSortOrder(int $value)
  49. *
  50. * @category Mage
  51. * @package Mage_Catalog
  52. * @author Magento Core Team <core@magentocommerce.com>
  53. */
  54. class Mage_Catalog_Model_Product_Option extends Mage_Core_Model_Abstract
  55. {
  56. /**
  57. * Option group text
  58. */
  59. const OPTION_GROUP_TEXT = 'text';
  60. /**
  61. * Option group file
  62. */
  63. const OPTION_GROUP_FILE = 'file';
  64. /**
  65. * Option group select
  66. */
  67. const OPTION_GROUP_SELECT = 'select';
  68. /**
  69. * Option group date
  70. */
  71. const OPTION_GROUP_DATE = 'date';
  72. /**
  73. * Option type field
  74. */
  75. const OPTION_TYPE_FIELD = 'field';
  76. /**
  77. * Option type area
  78. */
  79. const OPTION_TYPE_AREA = 'area';
  80. /**
  81. * Option group file
  82. */
  83. const OPTION_TYPE_FILE = 'file';
  84. /**
  85. * Option type drop down
  86. */
  87. const OPTION_TYPE_DROP_DOWN = 'drop_down';
  88. /**
  89. * Option type radio
  90. */
  91. const OPTION_TYPE_RADIO = 'radio';
  92. /**
  93. * Option type checkbox
  94. */
  95. const OPTION_TYPE_CHECKBOX = 'checkbox';
  96. /**
  97. * Option type multiple
  98. */
  99. const OPTION_TYPE_MULTIPLE = 'multiple';
  100. /**
  101. * Option type date
  102. */
  103. const OPTION_TYPE_DATE = 'date';
  104. /**
  105. * Option type date/time
  106. */
  107. const OPTION_TYPE_DATE_TIME = 'date_time';
  108. /**
  109. * Option type time
  110. */
  111. const OPTION_TYPE_TIME = 'time';
  112. /**
  113. * Product instance
  114. *
  115. * @var Mage_Catalog_Model_Product
  116. */
  117. protected $_product;
  118. /**
  119. * Options
  120. *
  121. * @var array
  122. */
  123. protected $_options = array();
  124. /**
  125. * Value instance
  126. *
  127. * @var Mage_Catalog_Model_Product_Option_Value
  128. */
  129. protected $_valueInstance;
  130. /**
  131. * Values
  132. *
  133. * @var array
  134. */
  135. protected $_values = array();
  136. /**
  137. * Constructor
  138. */
  139. protected function _construct()
  140. {
  141. $this->_init('catalog/product_option');
  142. }
  143. /**
  144. * Add value of option to values array
  145. *
  146. * @param Mage_Catalog_Model_Product_Option_Value $value
  147. * @return Mage_Catalog_Model_Product_Option
  148. */
  149. public function addValue(Mage_Catalog_Model_Product_Option_Value $value)
  150. {
  151. $this->_values[$value->getId()] = $value;
  152. return $this;
  153. }
  154. /**
  155. * Get value by given id
  156. *
  157. * @param int $valueId
  158. * @return Mage_Catalog_Model_Product_Option_Value
  159. */
  160. public function getValueById($valueId)
  161. {
  162. if (isset($this->_values[$valueId])) {
  163. return $this->_values[$valueId];
  164. }
  165. return null;
  166. }
  167. /**
  168. * Get values
  169. *
  170. * @return array
  171. */
  172. public function getValues()
  173. {
  174. return $this->_values;
  175. }
  176. /**
  177. * Retrieve value instance
  178. *
  179. * @return Mage_Catalog_Model_Product_Option_Value
  180. */
  181. public function getValueInstance()
  182. {
  183. if (!$this->_valueInstance) {
  184. $this->_valueInstance = Mage::getSingleton('catalog/product_option_value');
  185. }
  186. return $this->_valueInstance;
  187. }
  188. /**
  189. * Add option for save it
  190. *
  191. * @param array $option
  192. * @return Mage_Catalog_Model_Product_Option
  193. */
  194. public function addOption($option)
  195. {
  196. $this->_options[] = $option;
  197. return $this;
  198. }
  199. /**
  200. * Get all options
  201. *
  202. * @return array
  203. */
  204. public function getOptions()
  205. {
  206. return $this->_options;
  207. }
  208. /**
  209. * Set options for array
  210. *
  211. * @param array $options
  212. * @return Mage_Catalog_Model_Product_Option
  213. */
  214. public function setOptions($options)
  215. {
  216. $this->_options = $options;
  217. return $this;
  218. }
  219. /**
  220. * Set options to empty array
  221. *
  222. * @return Mage_Catalog_Model_Product_Option
  223. */
  224. public function unsetOptions()
  225. {
  226. $this->_options = array();
  227. return $this;
  228. }
  229. /**
  230. * Retrieve product instance
  231. *
  232. * @return Mage_Catalog_Model_Product
  233. */
  234. public function getProduct()
  235. {
  236. return $this->_product;
  237. }
  238. /**
  239. * Set product instance
  240. *
  241. * @param Mage_Catalog_Model_Product $product
  242. * @return Mage_Catalog_Model_Product_Option
  243. */
  244. public function setProduct(Mage_Catalog_Model_Product $product = null)
  245. {
  246. $this->_product = $product;
  247. return $this;
  248. }
  249. /**
  250. * Get group name of option by given option type
  251. *
  252. * @param string $type
  253. * @return string
  254. */
  255. public function getGroupByType($type = null)
  256. {
  257. if (is_null($type)) {
  258. $type = $this->getType();
  259. }
  260. $optionGroupsToTypes = array(
  261. self::OPTION_TYPE_FIELD => self::OPTION_GROUP_TEXT,
  262. self::OPTION_TYPE_AREA => self::OPTION_GROUP_TEXT,
  263. self::OPTION_TYPE_FILE => self::OPTION_GROUP_FILE,
  264. self::OPTION_TYPE_DROP_DOWN => self::OPTION_GROUP_SELECT,
  265. self::OPTION_TYPE_RADIO => self::OPTION_GROUP_SELECT,
  266. self::OPTION_TYPE_CHECKBOX => self::OPTION_GROUP_SELECT,
  267. self::OPTION_TYPE_MULTIPLE => self::OPTION_GROUP_SELECT,
  268. self::OPTION_TYPE_DATE => self::OPTION_GROUP_DATE,
  269. self::OPTION_TYPE_DATE_TIME => self::OPTION_GROUP_DATE,
  270. self::OPTION_TYPE_TIME => self::OPTION_GROUP_DATE,
  271. );
  272. return isset($optionGroupsToTypes[$type])?$optionGroupsToTypes[$type]:'';
  273. }
  274. /**
  275. * Group model factory
  276. *
  277. * @param string $type Option type
  278. * @return Mage_Catalog_Model_Product_Option_Group_Abstract
  279. */
  280. public function groupFactory($type)
  281. {
  282. $group = $this->getGroupByType($type);
  283. if (!empty($group)) {
  284. return Mage::getModel('catalog/product_option_type_' . $group);
  285. }
  286. Mage::throwException(Mage::helper('catalog')->__('Wrong option type to get group instance.'));
  287. }
  288. /**
  289. * Save options.
  290. *
  291. * @return Mage_Catalog_Model_Product_Option
  292. */
  293. public function saveOptions()
  294. {
  295. foreach ($this->getOptions() as $option) {
  296. $this->setData($option)
  297. ->setData('product_id', $this->getProduct()->getId())
  298. ->setData('store_id', $this->getProduct()->getStoreId());
  299. if ($this->getData('option_id') == '0') {
  300. $this->unsetData('option_id');
  301. } else {
  302. $this->setId($this->getData('option_id'));
  303. }
  304. $isEdit = (bool)$this->getId()? true:false;
  305. if ($this->getData('is_delete') == '1') {
  306. if ($isEdit) {
  307. $this->getValueInstance()->deleteValue($this->getId());
  308. $this->deletePrices($this->getId());
  309. $this->deleteTitles($this->getId());
  310. $this->delete();
  311. }
  312. } else {
  313. if ($this->getData('previous_type') != '') {
  314. $previousType = $this->getData('previous_type');
  315. /**
  316. * if previous option has different group from one is came now
  317. * need to remove all data of previous group
  318. */
  319. if ($this->getGroupByType($previousType) != $this->getGroupByType($this->getData('type'))) {
  320. switch ($this->getGroupByType($previousType)) {
  321. case self::OPTION_GROUP_SELECT:
  322. $this->unsetData('values');
  323. if ($isEdit) {
  324. $this->getValueInstance()->deleteValue($this->getId());
  325. }
  326. break;
  327. case self::OPTION_GROUP_FILE:
  328. $this->setData('file_extension', '');
  329. $this->setData('image_size_x', '0');
  330. $this->setData('image_size_y', '0');
  331. break;
  332. case self::OPTION_GROUP_TEXT:
  333. $this->setData('max_characters', '0');
  334. break;
  335. case self::OPTION_GROUP_DATE:
  336. break;
  337. }
  338. if ($this->getGroupByType($this->getData('type')) == self::OPTION_GROUP_SELECT) {
  339. $this->setData('sku', '');
  340. $this->unsetData('price');
  341. $this->unsetData('price_type');
  342. if ($isEdit) {
  343. $this->deletePrices($this->getId());
  344. }
  345. }
  346. }
  347. }
  348. $this->save(); }
  349. }//eof foreach()
  350. return $this;
  351. }
  352. /**
  353. * After save
  354. *
  355. * @return Mage_Core_Model_Abstract
  356. */
  357. protected function _afterSave()
  358. {
  359. $this->getValueInstance()->unsetValues();
  360. if (is_array($this->getData('values'))) {
  361. foreach ($this->getData('values') as $value) {
  362. $this->getValueInstance()->addValue($value);
  363. }
  364. $this->getValueInstance()->setOption($this)
  365. ->saveValues();
  366. } elseif ($this->getGroupByType($this->getType()) == self::OPTION_GROUP_SELECT) {
  367. Mage::throwException(Mage::helper('catalog')->__('Select type options required values rows.'));
  368. }
  369. return parent::_afterSave();
  370. }
  371. /**
  372. * Return price. If $flag is true and price is percent
  373. * return converted percent to price
  374. *
  375. * @param bool $flag
  376. * @return decimal
  377. */
  378. public function getPrice($flag = false)
  379. {
  380. if ($flag && $this->getPriceType() == 'percent') {
  381. $basePrice = $this->getProduct()->getFinalPrice();
  382. $price = $basePrice * ($this->_getData('price')/100);
  383. return $price;
  384. }
  385. return $this->_getData('price');
  386. }
  387. /**
  388. * Delete prices of option
  389. *
  390. * @param int $option_id
  391. * @return Mage_Catalog_Model_Product_Option
  392. */
  393. public function deletePrices($option_id)
  394. {
  395. $this->getResource()->deletePrices($option_id);
  396. return $this;
  397. }
  398. /**
  399. * Delete titles of option
  400. *
  401. * @param int $option_id
  402. * @return Mage_Catalog_Model_Product_Option
  403. */
  404. public function deleteTitles($option_id)
  405. {
  406. $this->getResource()->deleteTitles($option_id);
  407. return $this;
  408. }
  409. /**
  410. * get Product Option Collection
  411. *
  412. * @param Mage_Catalog_Model_Product $product
  413. * @return Mage_Catalog_Model_Resource_Product_Option_Collection
  414. */
  415. public function getProductOptionCollection(Mage_Catalog_Model_Product $product)
  416. {
  417. $collection = $this->getCollection()
  418. ->addFieldToFilter('product_id', $product->getId())
  419. ->addTitleToResult($product->getStoreId())
  420. ->addPriceToResult($product->getStoreId())
  421. ->setOrder('sort_order', 'asc')
  422. ->setOrder('title', 'asc');
  423. if ($this->getAddRequiredFilter()) {
  424. $collection->addRequiredFilter($this->getAddRequiredFilterValue());
  425. }
  426. $collection->addValuesToResult($product->getStoreId());
  427. return $collection;
  428. }
  429. /**
  430. * Get collection of values for current option
  431. *
  432. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Option_Value_Collection
  433. */
  434. public function getValuesCollection()
  435. {
  436. $collection = $this->getValueInstance()
  437. ->getValuesCollection($this);
  438. return $collection;
  439. }
  440. /**
  441. * Get collection of values by given option ids
  442. *
  443. * @param array $optionIds
  444. * @param int $store_id
  445. * @return unknown
  446. */
  447. public function getOptionValuesByOptionId($optionIds, $store_id)
  448. {
  449. $collection = Mage::getModel('catalog/product_option_value')
  450. ->getValuesByOption($optionIds, $this->getId(), $store_id);
  451. return $collection;
  452. }
  453. /**
  454. * Prepare array of options for duplicate
  455. *
  456. * @return array
  457. */
  458. public function prepareOptionForDuplicate()
  459. {
  460. $this->setProductId(null);
  461. $this->setOptionId(null);
  462. $newOption = $this->__toArray();
  463. $_values = $this->getValues();
  464. if ($_values) {
  465. $newValuesArray = array();
  466. foreach ($_values as $_value) {
  467. $newValuesArray[] = $_value->prepareValueForDuplicate();
  468. }
  469. $newOption['values'] = $newValuesArray;
  470. }
  471. return $newOption;
  472. }
  473. /**
  474. * Duplicate options for product
  475. *
  476. * @param int $oldProductId
  477. * @param int $newProductId
  478. * @return Mage_Catalog_Model_Product_Option
  479. */
  480. public function duplicate($oldProductId, $newProductId)
  481. {
  482. $this->getResource()->duplicate($this, $oldProductId, $newProductId);
  483. return $this;
  484. }
  485. /**
  486. * Retrieve option searchable data
  487. *
  488. * @param int $productId
  489. * @param int $storeId
  490. * @return array
  491. */
  492. public function getSearchableData($productId, $storeId)
  493. {
  494. return $this->_getResource()->getSearchableData($productId, $storeId);
  495. }
  496. /**
  497. * Clearing object's data
  498. *
  499. * @return Mage_Catalog_Model_Product_Option
  500. */
  501. protected function _clearData()
  502. {
  503. $this->_data = array();
  504. $this->_values = array();
  505. return $this;
  506. }
  507. /**
  508. * Clearing cyclic references
  509. *
  510. * @return Mage_Catalog_Model_Product_Option
  511. */
  512. protected function _clearReferences()
  513. {
  514. if (!empty($this->_values)) {
  515. foreach ($this->_values as $value) {
  516. $value->unsetOption();
  517. }
  518. }
  519. return $this;
  520. }
  521. /**
  522. * Check whether custom option could have multiple values
  523. *
  524. * @return bool
  525. */
  526. public function isMultipleType()
  527. {
  528. switch ($this->getType()) {
  529. case self::OPTION_TYPE_MULTIPLE:
  530. case self::OPTION_TYPE_CHECKBOX:
  531. return true;
  532. }
  533. return false;
  534. }
  535. }