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_Eav
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: /**
29: * EAV Entity Form Model
30: *
31: * @category Mage
32: * @package Mage_Eav
33: * @author Magento Core Team <core@magentocommerce.com>
34: */
35: abstract class Mage_Eav_Model_Form
36: {
37: /**
38: * Current module pathname
39: *
40: * @var string
41: */
42: protected $_moduleName = '';
43:
44: /**
45: * Current EAV entity type code
46: *
47: * @var string
48: */
49: protected $_entityTypeCode = '';
50:
51: /**
52: * Current store instance
53: *
54: * @var Mage_Core_Model_Store
55: */
56: protected $_store;
57:
58: /**
59: * Current entity type instance
60: *
61: * @var Mage_Eav_Model_Entity_Type
62: */
63: protected $_entityType;
64:
65: /**
66: * Current entity instance
67: *
68: * @var Mage_Core_Model_Abstract
69: */
70: protected $_entity;
71:
72: /**
73: * Current form code
74: *
75: * @var string
76: */
77: protected $_formCode;
78:
79: /**
80: * Array of form attributes
81: *
82: * @var array
83: */
84: protected $_attributes;
85:
86: /**
87: * Array of form system attributes
88: *
89: * @var array
90: */
91: protected $_systemAttributes;
92:
93: /**
94: * Array of form user defined attributes
95: *
96: * @var array
97: */
98: protected $_userAttributes;
99:
100: /**
101: * Is AJAX request flag
102: *
103: * @var boolean
104: */
105: protected $_isAjax = false;
106:
107: /**
108: * Whether the invisible form fields need to be filtered/ignored
109: *
110: * @var bool
111: */
112: protected $_ignoreInvisible = true;
113:
114: /**
115: * Checks correct module choice
116: *
117: * @throws Mage_Core_Exception
118: */
119: public function __construct()
120: {
121: if (empty($this->_moduleName)) {
122: Mage::throwException(Mage::helper('eav')->__('Current module pathname is undefined'));
123: }
124: if (empty($this->_entityTypeCode)) {
125: Mage::throwException(Mage::helper('eav')->__('Current module EAV entity is undefined'));
126: }
127: }
128:
129: /**
130: * Get EAV Entity Form Attribute Collection
131: *
132: * @return mixed
133: */
134: protected function _getFormAttributeCollection()
135: {
136: return Mage::getResourceModel($this->_moduleName . '/form_attribute_collection');
137: }
138:
139: /**
140: * Set current store
141: *
142: * @param Mage_Core_Model_Store|string|int $store
143: * @return Mage_Eav_Model_Form
144: */
145: public function setStore($store)
146: {
147: $this->_store = Mage::app()->getStore($store);
148: return $this;
149: }
150:
151: /**
152: * Set entity instance
153: *
154: * @param Mage_Core_Model_Abstract $entity
155: * @return Mage_Eav_Model_Form
156: */
157: public function setEntity(Mage_Core_Model_Abstract $entity)
158: {
159: $this->_entity = $entity;
160: if ($entity->getEntityTypeId()) {
161: $this->setEntityType($entity->getEntityTypeId());
162: }
163: return $this;
164: }
165:
166: /**
167: * Set entity type instance
168: *
169: * @param Mage_Eav_Model_Entity_Type|string|int $entityType
170: * @return Mage_Eav_Model_Form
171: */
172: public function setEntityType($entityType)
173: {
174: $this->_entityType = Mage::getSingleton('eav/config')->getEntityType($entityType);
175: return $this;
176: }
177:
178: /**
179: * Set form code
180: *
181: * @param string $formCode
182: * @return Mage_Eav_Model_Form
183: */
184: public function setFormCode($formCode)
185: {
186: $this->_formCode = $formCode;
187: return $this;
188: }
189:
190: /**
191: * Return current store instance
192: *
193: * @return Mage_Core_Model_Store
194: */
195: public function getStore()
196: {
197: if (is_null($this->_store)) {
198: $this->_store = Mage::app()->getStore();
199: }
200: return $this->_store;
201: }
202:
203: /**
204: * Return current form code
205: *
206: * @throws Mage_Core_Exception
207: * @return string
208: */
209: public function getFormCode()
210: {
211: if (empty($this->_formCode)) {
212: Mage::throwException(Mage::helper('eav')->__('Form code is not defined'));
213: }
214: return $this->_formCode;
215: }
216:
217: /**
218: * Return entity type instance
219: * Return EAV entity type if entity type is not defined
220: *
221: * @return Mage_Eav_Model_Entity_Type
222: */
223: public function getEntityType()
224: {
225: if (is_null($this->_entityType)) {
226: $this->setEntityType($this->_entityTypeCode);
227: }
228: return $this->_entityType;
229: }
230:
231: /**
232: * Return current entity instance
233: *
234: * @throws Mage_Core_Exception
235: * @return Mage_Core_Model_Abstract
236: */
237: public function getEntity()
238: {
239: if (is_null($this->_entity)) {
240: Mage::throwException(Mage::helper('eav')->__('Entity instance is not defined'));
241: }
242: return $this->_entity;
243: }
244:
245: /**
246: * Return array of form attributes
247: *
248: * @return array
249: */
250: public function getAttributes()
251: {
252: if (is_null($this->_attributes)) {
253: /* @var $collection Mage_Eav_Model_Resource_Form_Attribute_Collection */
254: $collection = $this->_getFormAttributeCollection();
255:
256: $collection->setStore($this->getStore())
257: ->setEntityType($this->getEntityType())
258: ->addFormCodeFilter($this->getFormCode())
259: ->setSortOrder();
260:
261: $this->_attributes = array();
262: $this->_userAttributes = array();
263: foreach ($collection as $attribute) {
264: /* @var $attribute Mage_Eav_Model_Entity_Attribute */
265: $this->_attributes[$attribute->getAttributeCode()] = $attribute;
266: if ($attribute->getIsUserDefined()) {
267: $this->_userAttributes[$attribute->getAttributeCode()] = $attribute;
268: } else {
269: $this->_systemAttributes[$attribute->getAttributeCode()] = $attribute;
270: }
271: }
272: }
273: return $this->_attributes;
274: }
275:
276: /**
277: * Return attribute instance by code or false
278: *
279: * @param string $attributeCode
280: * @return Mage_Eav_Model_Entity_Attribute|false
281: */
282: public function getAttribute($attributeCode)
283: {
284: $attributes = $this->getAttributes();
285: if (isset($attributes[$attributeCode])) {
286: return $attributes[$attributeCode];
287: }
288: return false;
289: }
290:
291: /**
292: * Return array of form user defined attributes
293: *
294: * @return array
295: */
296: public function getUserAttributes()
297: {
298: if (is_null($this->_userAttributes)) {
299: // load attributes
300: $this->getAttributes();
301: }
302: return $this->_userAttributes;
303: }
304:
305: /**
306: * Return array of form system attributes
307: *
308: * @return array
309: */
310: public function getSystemAttributes()
311: {
312: if (is_null($this->_systemAttributes)) {
313: // load attributes
314: $this->getAttributes();
315: }
316: return $this->_systemAttributes;
317: }
318:
319: /**
320: * Return attribute data model by attribute
321: *
322: * @param Mage_Eav_Model_Entity_Attribute $attribute
323: * @return Mage_Eav_Model_Attribute_Data_Abstract
324: */
325: protected function _getAttributeDataModel(Mage_Eav_Model_Entity_Attribute $attribute)
326: {
327: $dataModel = Mage_Eav_Model_Attribute_Data::factory($attribute, $this->getEntity());
328: $dataModel->setIsAjaxRequest($this->getIsAjaxRequest());
329:
330: return $dataModel;
331: }
332:
333: /**
334: * Prepare request with data and returns it
335: *
336: * @param array $data
337: * @return Zend_Controller_Request_Http
338: */
339: public function prepareRequest(array $data)
340: {
341: $request = clone Mage::app()->getRequest();
342: $request->setParamSources();
343: $request->clearParams();
344: $request->setParams($data);
345:
346: return $request;
347: }
348:
349: /**
350: * Extract data from request and return associative data array
351: *
352: * @param Zend_Controller_Request_Http $request
353: * @param string $scope the request scope
354: * @param boolean $scopeOnly search value only in scope or search value in global too
355: * @return array
356: */
357: public function extractData(Zend_Controller_Request_Http $request, $scope = null, $scopeOnly = true)
358: {
359: $data = array();
360: foreach ($this->getAttributes() as $attribute) {
361: if ($this->_isAttributeOmitted($attribute)) {
362: continue;
363: }
364: $dataModel = $this->_getAttributeDataModel($attribute);
365: $dataModel->setRequestScope($scope);
366: $dataModel->setRequestScopeOnly($scopeOnly);
367: $data[$attribute->getAttributeCode()] = $dataModel->extractValue($request);
368: }
369: return $data;
370: }
371:
372: /**
373: * Validate data array and return true or array of errors
374: *
375: * @param array $data
376: * @return boolean|array
377: */
378: public function validateData(array $data)
379: {
380: $errors = array();
381: foreach ($this->getAttributes() as $attribute) {
382: if ($this->_isAttributeOmitted($attribute)) {
383: continue;
384: }
385: $dataModel = $this->_getAttributeDataModel($attribute);
386: $dataModel->setExtractedData($data);
387: if (!isset($data[$attribute->getAttributeCode()])) {
388: $data[$attribute->getAttributeCode()] = null;
389: }
390: $result = $dataModel->validateValue($data[$attribute->getAttributeCode()]);
391: if ($result !== true) {
392: $errors = array_merge($errors, $result);
393: }
394: }
395:
396: if (count($errors) == 0) {
397: return true;
398: }
399:
400: return $errors;
401: }
402:
403: /**
404: * Compact data array to current entity
405: *
406: * @param array $data
407: * @return Mage_Eav_Model_Form
408: */
409: public function compactData(array $data)
410: {
411: foreach ($this->getAttributes() as $attribute) {
412: if ($this->_isAttributeOmitted($attribute)) {
413: continue;
414: }
415: $dataModel = $this->_getAttributeDataModel($attribute);
416: $dataModel->setExtractedData($data);
417: if (!isset($data[$attribute->getAttributeCode()])) {
418: $data[$attribute->getAttributeCode()] = false;
419: }
420: $dataModel->compactValue($data[$attribute->getAttributeCode()]);
421: }
422:
423: return $this;
424: }
425:
426: /**
427: * Restore data array from SESSION to current entity
428: *
429: * @param array $data
430: * @return Mage_Eav_Model_Form
431: */
432: public function restoreData(array $data)
433: {
434: foreach ($this->getAttributes() as $attribute) {
435: if ($this->_isAttributeOmitted($attribute)) {
436: continue;
437: }
438: $dataModel = $this->_getAttributeDataModel($attribute);
439: $dataModel->setExtractedData($data);
440: if (!isset($data[$attribute->getAttributeCode()])) {
441: $data[$attribute->getAttributeCode()] = false;
442: }
443: $dataModel->restoreValue($data[$attribute->getAttributeCode()]);
444: }
445: return $this;
446: }
447:
448: /**
449: * Return array of entity formated values
450: *
451: * @param string $format
452: * @return array
453: */
454: public function outputData($format = Mage_Eav_Model_Attribute_Data::OUTPUT_FORMAT_TEXT)
455: {
456: $data = array();
457: foreach ($this->getAttributes() as $attribute) {
458: if ($this->_isAttributeOmitted($attribute)) {
459: continue;
460: }
461: $dataModel = $this->_getAttributeDataModel($attribute);
462: $dataModel->setExtractedData($data);
463: $data[$attribute->getAttributeCode()] = $dataModel->outputValue($format);
464: }
465: return $data;
466: }
467:
468: /**
469: * Restore entity original data
470: *
471: * @return Mage_Eav_Model_Form
472: */
473: public function resetEntityData()
474: {
475: foreach ($this->getAttributes() as $attribute) {
476: if ($this->_isAttributeOmitted($attribute)) {
477: continue;
478: }
479: $value = $this->getEntity()->getOrigData($attribute->getAttributeCode());
480: $this->getEntity()->setData($attribute->getAttributeCode(), $value);
481: }
482: return $this;
483: }
484:
485: /**
486: * Set is AJAX Request flag
487: *
488: * @param boolean $flag
489: * @return Mage_Eav_Model_Form
490: */
491: public function setIsAjaxRequest($flag = true)
492: {
493: $this->_isAjax = (bool)$flag;
494: return $this;
495: }
496:
497: /**
498: * Return is AJAX Request
499: *
500: * @return boolean
501: */
502: public function getIsAjaxRequest()
503: {
504: return $this->_isAjax;
505: }
506:
507: /**
508: * Set default attribute values for new entity
509: *
510: * @return Mage_Eav_Model_Form
511: */
512: public function initDefaultValues()
513: {
514: if (!$this->getEntity()->getId()) {
515: foreach ($this->getAttributes() as $attribute) {
516: $default = $attribute->getDefaultValue();
517: if ($default != '') {
518: $this->getEntity()->setData($attribute->getAttributeCode(), $default);
519: }
520: }
521: }
522: return $this;
523: }
524:
525: /**
526: * Combined getter/setter whether to omit invisible attributes during rendering/validation
527: *
528: * @param mixed $setValue
529: * @return bool|Mage_Eav_Model_Form
530: */
531: public function ignoreInvisible($setValue = null)
532: {
533: if (null !== $setValue) {
534: $this->_ignoreInvisible = (bool)$setValue;
535: return $this;
536: }
537: return $this->_ignoreInvisible;
538: }
539:
540: /**
541: * Whether the specified attribute needs to skip rendering/validation
542: *
543: * @param Mage_Eav_Model_Attribute $attribute
544: * @return bool
545: */
546: protected function _isAttributeOmitted($attribute)
547: {
548: if ($this->_ignoreInvisible && !$attribute->getIsVisible()) {
549: return true;
550: }
551: return false;
552: }
553: }
554: