1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
43: class Mage_Widget_Model_Widget_Instance extends Mage_Core_Model_Abstract
44: {
45: const SPECIFIC_ENTITIES = 'specific';
46: const ALL_ENTITIES = 'all';
47:
48: const DEFAULT_LAYOUT_HANDLE = 'default';
49: const PRODUCT_LAYOUT_HANDLE = 'catalog_product_view';
50: const SINGLE_PRODUCT_LAYOUT_HANLDE = 'PRODUCT_{{ID}}';
51: const PRODUCT_TYPE_LAYOUT_HANDLE = 'PRODUCT_TYPE_{{TYPE}}';
52: const ANCHOR_CATEGORY_LAYOUT_HANDLE = 'catalog_category_layered';
53: const NOTANCHOR_CATEGORY_LAYOUT_HANDLE = 'catalog_category_default';
54: const SINGLE_CATEGORY_LAYOUT_HANDLE = 'CATEGORY_{{ID}}';
55:
56: const XML_NODE_RELATED_CACHE = 'global/widget/related_cache_types';
57:
58: protected $_layoutHandles = array();
59:
60: protected $_specificEntitiesLayoutHandles = array();
61:
62: 63: 64:
65: protected $_widgetConfigXml = null;
66:
67: 68: 69: 70: 71:
72: protected $_eventPrefix = 'widget_widget_instance';
73:
74: 75: 76:
77: protected function _construct()
78: {
79: parent::_construct();
80: $this->_init('widget/widget_instance');
81: $this->_layoutHandles = array(
82: 'anchor_categories' => self::ANCHOR_CATEGORY_LAYOUT_HANDLE,
83: 'notanchor_categories' => self::NOTANCHOR_CATEGORY_LAYOUT_HANDLE,
84: 'all_products' => self::PRODUCT_LAYOUT_HANDLE,
85: 'all_pages' => self::DEFAULT_LAYOUT_HANDLE
86: );
87: $this->_specificEntitiesLayoutHandles = array(
88: 'anchor_categories' => self::SINGLE_CATEGORY_LAYOUT_HANDLE,
89: 'notanchor_categories' => self::SINGLE_CATEGORY_LAYOUT_HANDLE,
90: 'all_products' => self::SINGLE_PRODUCT_LAYOUT_HANLDE,
91: );
92: foreach (Mage_Catalog_Model_Product_Type::getTypes() as $typeId => $type) {
93: $layoutHandle = str_replace('{{TYPE}}', $typeId, self::PRODUCT_TYPE_LAYOUT_HANDLE);
94: $this->_layoutHandles[$typeId . '_products'] = $layoutHandle;
95: $this->_specificEntitiesLayoutHandles[$typeId . '_products'] = self::SINGLE_PRODUCT_LAYOUT_HANLDE;
96: }
97: }
98:
99: 100: 101: 102: 103: 104:
105: protected function _initOldFieldsMap()
106: {
107: $this->_oldFieldsMap = array(
108: 'type' => 'instance_type',
109: );
110: return $this;
111: }
112:
113: 114: 115: 116: 117:
118: protected function _beforeSave()
119: {
120: $pageGroupIds = array();
121: $tmpPageGroups = array();
122: $pageGroups = $this->getData('page_groups');
123: if ($pageGroups) {
124: foreach ($pageGroups as $pageGroup) {
125: $tmpPageGroup = array();
126: if (isset($pageGroup[$pageGroup['page_group']])) {
127: $pageGroupData = $pageGroup[$pageGroup['page_group']];
128: if ($pageGroupData['page_id']) {
129: $pageGroupIds[] = $pageGroupData['page_id'];
130: }
131: if ($pageGroup['page_group'] == 'pages') {
132: $layoutHandle = $pageGroupData['layout_handle'];
133: } else {
134: $layoutHandle = $this->_layoutHandles[$pageGroup['page_group']];
135: }
136: if (!isset($pageGroupData['template'])) {
137: $pageGroupData['template'] = '';
138: }
139: $tmpPageGroup = array(
140: 'page_id' => $pageGroupData['page_id'],
141: 'group' => $pageGroup['page_group'],
142: 'layout_handle' => $layoutHandle,
143: 'for' => $pageGroupData['for'],
144: 'block_reference' => $pageGroupData['block'],
145: 'entities' => '',
146: 'layout_handle_updates' => array($layoutHandle),
147: 'template' => $pageGroupData['template']?$pageGroupData['template']:''
148: );
149: if ($pageGroupData['for'] == self::SPECIFIC_ENTITIES) {
150: $layoutHandleUpdates = array();
151: foreach (explode(',', $pageGroupData['entities']) as $entity) {
152: $layoutHandleUpdates[] = str_replace('{{ID}}', $entity,
153: $this->_specificEntitiesLayoutHandles[$pageGroup['page_group']]);
154: }
155: $tmpPageGroup['entities'] = $pageGroupData['entities'];
156: $tmpPageGroup['layout_handle_updates'] = $layoutHandleUpdates;
157: }
158: $tmpPageGroups[] = $tmpPageGroup;
159: }
160: }
161: }
162: if (is_array($this->getData('store_ids'))) {
163: $this->setData('store_ids', implode(',', $this->getData('store_ids')));
164: }
165: if (is_array($this->getData('widget_parameters'))) {
166: $this->setData('widget_parameters', serialize($this->getData('widget_parameters')));
167: }
168: $this->setData('page_groups', $tmpPageGroups);
169: $this->setData('page_group_ids', $pageGroupIds);
170:
171: return parent::_beforeSave();
172: }
173:
174: 175: 176: 177: 178:
179: public function validate()
180: {
181: if ($this->isCompleteToCreate()) {
182: return true;
183: }
184: return Mage::helper('widget')->__('Widget instance is not full complete to create.');
185: }
186:
187: 188: 189: 190: 191:
192: public function isCompleteToCreate()
193: {
194: return (bool)($this->getType() && $this->getPackageTheme());
195: }
196:
197: 198: 199: 200: 201: 202: 203:
204: public function setType($type)
205: {
206: $this->setData('type', $type);
207: $this->_prepareType();
208: return $this;
209: }
210:
211: 212: 213: 214: 215: 216:
217: public function getType()
218: {
219: $this->_prepareType();
220: return $this->_getData('type');
221: }
222:
223: 224: 225: 226: 227:
228: protected function _prepareType()
229: {
230: if (strpos($this->_getData('type'), '-') >= 0) {
231: $this->setData('type', str_replace('-', '/', $this->_getData('type')));
232: }
233: return $this;
234: }
235:
236: 237: 238: 239: 240: 241: 242:
243: public function setPackageTheme($packageTheme)
244: {
245: $this->setData('package_theme', $packageTheme);
246: return $this;
247: }
248:
249: 250: 251: 252: 253: 254:
255: public function getPackageTheme()
256: {
257: return $this->_getData('package_theme');
258: }
259:
260: 261: 262: 263: 264: 265: 266:
267: protected function _preparePackageTheme()
268: {
269: return $this;
270: }
271:
272: 273: 274: 275: 276: 277:
278: public function getArea()
279: {
280: if (!$this->_getData('area')) {
281: return Mage_Core_Model_Design_Package::DEFAULT_AREA;
282: }
283: return $this->_getData('area');
284: }
285:
286: 287: 288: 289: 290:
291: public function getPackage()
292: {
293: if (!$this->_getData('package')) {
294: $this->_parsePackageTheme();
295: }
296: return $this->_getData('package');
297: }
298:
299: 300: 301: 302: 303:
304: public function getTheme()
305: {
306: if (!$this->_getData('theme')) {
307: $this->_parsePackageTheme();
308: }
309: return $this->_getData('theme');
310: }
311:
312: 313: 314: 315: 316:
317: protected function _parsePackageTheme()
318: {
319: if ($this->getPackageTheme() && strpos($this->getPackageTheme(), '/')) {
320: list($package, $theme) = explode('/', $this->getPackageTheme());
321: $this->setData('package', $package);
322: $this->setData('theme', $theme);
323: }
324: return $this;
325: }
326:
327: 328: 329: 330: 331: 332:
333: public function getStoreIds()
334: {
335: if (is_string($this->getData('store_ids'))) {
336: return explode(',', $this->getData('store_ids'));
337: }
338: return $this->getData('store_ids');
339: }
340:
341: 342: 343: 344: 345: 346:
347: public function getWidgetParameters()
348: {
349: if (is_string($this->getData('widget_parameters'))) {
350: return unserialize($this->getData('widget_parameters'));
351: }
352: return (is_array($this->getData('widget_parameters'))) ? $this->getData('widget_parameters') : array();
353: }
354:
355: 356: 357: 358: 359:
360: public function getWidgetsOptionArray()
361: {
362: $widgets = array();
363: $widgetsArr = Mage::getSingleton('widget/widget')->getWidgetsArray();
364: foreach ($widgetsArr as $widget) {
365: $widgets[] = array(
366: 'value' => $widget['type'],
367: 'label' => $widget['name']
368: );
369: }
370: return $widgets;
371: }
372:
373: 374: 375: 376: 377:
378: public function getWidgetConfig()
379: {
380: if ($this->_widgetConfigXml === null) {
381: $this->_widgetConfigXml = Mage::getSingleton('widget/widget')
382: ->getXmlElementByType($this->getType());
383: if ($this->_widgetConfigXml) {
384: $configFile = Mage::getSingleton('core/design_package')->getBaseDir(array(
385: '_area' => $this->getArea(),
386: '_package' => $this->getPackage(),
387: '_theme' => $this->getTheme(),
388: '_type' => 'etc'
389: )) . DS . 'widget.xml';
390: if (is_readable($configFile)) {
391: $themeWidgetsConfig = new Varien_Simplexml_Config();
392: $themeWidgetsConfig->loadFile($configFile);
393: if ($themeWidgetTypeConfig = $themeWidgetsConfig->getNode($this->_widgetConfigXml->getName())) {
394: $this->_widgetConfigXml->extend($themeWidgetTypeConfig);
395: }
396: }
397: }
398: }
399: return $this->_widgetConfigXml;
400: }
401:
402: 403: 404: 405: 406:
407: public function getWidgetTemplates()
408: {
409: $templates = array();
410: if ($this->getWidgetConfig() && ($configTemplates = $this->getWidgetConfig()->parameters->template)) {
411: if ($configTemplates->values && $configTemplates->values->children()) {
412: foreach ($configTemplates->values->children() as $name => $template) {
413: $helper = $template->getAttribute('module') ? $template->getAttribute('module') : 'widget';
414: $templates[(string)$name] = array(
415: 'value' => (string)$template->value,
416: 'label' => Mage::helper($helper)->__((string)$template->label)
417: );
418: }
419: } elseif ($configTemplates->value) {
420: $templates['default'] = array(
421: 'value' => (string)$configTemplates->value,
422: 'label' => Mage::helper('widget')->__('Default Template')
423: );
424: }
425: }
426: return $templates;
427: }
428:
429: 430: 431: 432: 433:
434: public function getWidgetSupportedBlocks()
435: {
436: $blocks = array();
437: if ($this->getWidgetConfig() && ($supportedBlocks = $this->getWidgetConfig()->supported_blocks)) {
438: foreach ($supportedBlocks->children() as $block) {
439: $blocks[] = (string)$block->block_name;
440: }
441: }
442: return $blocks;
443: }
444:
445: 446: 447: 448: 449: 450:
451: public function getWidgetSupportedTemplatesByBlock($blockReference)
452: {
453: $templates = array();
454: $widgetTemplates = $this->getWidgetTemplates();
455: if ($this->getWidgetConfig()) {
456: if (!($supportedBlocks = $this->getWidgetConfig()->supported_blocks)) {
457: return $widgetTemplates;
458: }
459: foreach ($supportedBlocks->children() as $block) {
460: if ((string)$block->block_name == $blockReference) {
461: if ($block->template && $block->template->children()) {
462: foreach ($block->template->children() as $template) {
463: if (isset($widgetTemplates[(string)$template])) {
464: $templates[] = $widgetTemplates[(string)$template];
465: }
466: }
467: } else {
468: $templates[] = $widgetTemplates[(string)$template];
469: }
470: }
471: }
472: } else {
473: return $widgetTemplates;
474: }
475: return $templates;
476: }
477:
478: 479: 480: 481: 482: 483: 484:
485: public function generateLayoutUpdateXml($blockReference, $templatePath = '')
486: {
487: $templateFilename = Mage::getSingleton('core/design_package')->getTemplateFilename($templatePath, array(
488: '_area' => $this->getArea(),
489: '_package' => $this->getPackage(),
490: '_theme' => $this->getTheme()
491: ));
492: if (!$this->getId() && !$this->isCompleteToCreate()
493: || ($templatePath && !is_readable($templateFilename)))
494: {
495: return '';
496: }
497: $parameters = $this->getWidgetParameters();
498: $xml = '<reference name="' . $blockReference . '">';
499: $template = '';
500: if (isset($parameters['template'])) {
501: unset($parameters['template']);
502: }
503: if ($templatePath) {
504: $template = ' template="' . $templatePath . '"';
505: }
506:
507: $hash = Mage::helper('core')->uniqHash();
508: $xml .= '<block type="' . $this->getType() . '" name="' . $hash . '"' . $template . '>';
509: foreach ($parameters as $name => $value) {
510: if (is_array($value)) {
511: $value = implode(',', $value);
512: }
513: if ($name && strlen((string)$value)) {
514: $xml .= '<action method="setData">'
515: . '<name>' . $name . '</name>'
516: . '<value>' . Mage::helper('widget')->htmlEscape($value) . '</value>'
517: . '</action>';
518: }
519: }
520: $xml .= '</block></reference>';
521:
522: return $xml;
523: }
524:
525: 526: 527: 528: 529:
530: protected function _invalidateCache()
531: {
532: $types = Mage::getConfig()->getNode(self::XML_NODE_RELATED_CACHE);
533: if ($types) {
534: $types = $types->asArray();
535: Mage::app()->getCacheInstance()->invalidateType(array_keys($types));
536: }
537: return $this;
538: }
539:
540: 541: 542:
543: protected function _afterSave()
544: {
545: if ($this->dataHasChangedFor('page_groups') || $this->dataHasChangedFor('widget_parameters')) {
546: $this->_invalidateCache();
547: }
548: return parent::_afterSave();
549: }
550:
551: 552: 553:
554: protected function _beforeDelete()
555: {
556: if ($this->getPageGroups()) {
557: $this->_invalidateCache();
558: }
559: return parent::_beforeDelete();
560: }
561: }
562: