mVentory_Productivity - Version 1.1.1

Version Notes

* Add setting to limit the list of fields available for editing via the frontend
* Add support for editing of configurable products
* Add tabs for quick generating of QR labels (works only when MVentory_API extesion is installed)
* Extend filtering by all image types (i.e. base image, small image and thumbnail) in the list of products with missing images
* Allow to expand categories with 'Include in Navigation Menu' set to No

Download this release

Release Info

Developer Anatoly A. Kazantsev
Extension mVentory_Productivity
Version 1.1.1
Comparing to
See all releases


Code changes from version 1.1.0 to 1.1.1

app/code/community/MVentory/Productivity/Block/Config/Buildinfo.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Creative Commons License BY-NC-ND.
7
+ * NonCommercial — You may not use the material for commercial purposes.
8
+ * NoDerivatives — If you remix, transform, or build upon the material,
9
+ * you may not distribute the modified material.
10
+ * See the full license at http://creativecommons.org/licenses/by-nc-nd/4.0/
11
+ *
12
+ * See http://mventory.com/legal/licensing/ for other licensing options.
13
+ *
14
+ * @package MVentory/Productivity
15
+ * @copyright Copyright (c) 2015 mVentory Ltd. (http://mventory.com)
16
+ * @license http://creativecommons.org/licenses/by-nc-nd/4.0/
17
+ */
18
+
19
+ /**
20
+ * Block for displaying build version in system config
21
+ *
22
+ * @package MVentory/Productivity
23
+ * @author Andrew Gilman <andrew@mventory.com>
24
+ */
25
+
26
+ class MVentory_Productivity_Block_Config_Buildinfo
27
+ extends Mage_Adminhtml_Block_Abstract
28
+ implements Varien_Data_Form_Element_Renderer_Interface
29
+ {
30
+ protected $_template = 'productivity/config/build-info.phtml';
31
+
32
+ /**
33
+ * Render fieldset html
34
+ *
35
+ * @param Varien_Data_Form_Element_Abstract $element
36
+ * @return string
37
+ */
38
+ public function render (Varien_Data_Form_Element_Abstract $element) {
39
+ return $this->toHtml();
40
+ }
41
+ }
42
+
app/code/community/MVentory/Productivity/Block/Panel.php CHANGED
@@ -92,83 +92,73 @@ class MVentory_Productivity_Block_Panel
92
  * @return Varien_Data_Form
93
  */
94
  public function getEditForm() {
 
 
95
  /* @var $product Mage_Catalog_Model_Product */
96
- $product = Mage::registry('product');
97
- $form = new Varien_Data_Form();
98
- $form->setUseContainer(true)
99
- ->setMethod('post')
100
- // see MVentory_Productivity_ProductController::saveAction()
101
- ->setAction(Mage::getUrl('catalog/product/save', array('id' => $product->getId())));
102
- $attributes = Mage::helper('productivity')->getVisibleAttributes($product);
103
- $allowedInputs = array('text', 'textarea', 'date', 'select', 'multiselect');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
106
- foreach ($attributes as $attribute) {
107
- $label = trim($attribute->getStoreLabel());
108
-
109
- //Support for features of MVentory extension
110
- //Hide attributes which are disabled in the current store
111
- if ($label == '~')
112
- continue;
113
-
114
- $values = $attribute->usesSource()
115
- ? $attribute->getSource()->getAllOptions()
116
- : null;
117
-
118
- //Support for features of MVentory extension
119
- //Hide attribute's values which are disabled in the current store
120
- if ($values) {
121
- foreach ($values as $i => $value)
122
- if (strpos($value['label'], '~') === 0)
123
- unset($values[$i]);
124
-
125
- //Also hide attribute if it doesn't have allowed values
126
- if (count($values) < 2)
127
- continue;
128
- }
129
-
130
- $field = array(
131
- 'name' => $attribute->getAttributeCode(),
132
- 'label' => $label,
133
- 'values' => $values
134
  );
135
- $input = in_array($attribute->getFrontendInput(), $allowedInputs)
136
- ? $attribute->getFrontendInput()
137
- : 'text';
138
- $form->addField($field['name'], $input, $field)
139
- ->setFormat(Mage::app()->getLocale()->getDateFormat()) // for date, time & datetime fields
140
- ->setRows(5); // in case it's a textarea, make it taller
141
  }
142
 
143
  $form->setValues($product->getData());
144
 
145
- $isConfigurable = $product->getTypeId() == 'configurable';
146
-
147
- $form
148
- ->addField(
149
- 'qty',
150
- $isConfigurable ? 'label' : 'text',
151
- array(
152
- 'name' => 'qty',
153
- 'label' => 'Qty',
154
- ),
155
- 'price'
156
- )
157
- ->setValue(
158
- $isConfigurable
159
- ? $this->__('Edit individual sub-products')
160
- : $product->getStockItem()->getQty() * 1
161
- );
162
-
163
- // add field after values so "Submit" value is not overwritten
164
  $form->addField('submit', 'submit', array(
165
  'value' => 'Save',
166
  'no_span' => true,
167
  ));
 
168
  $form->addField('cancel', 'button', array(
169
  'value' => 'Cancel',
170
  'no_span' => true,
171
  ));
 
172
  return $form;
173
  }
174
 
92
  * @return Varien_Data_Form
93
  */
94
  public function getEditForm() {
95
+ $helper = Mage::helper('productivity/attribute');
96
+
97
  /* @var $product Mage_Catalog_Model_Product */
98
+ $product = Mage::registry('product');
99
+
100
+ $dateFormat = Mage::app()->getLocale()->getDateFormat();
101
+ $isConfigurable
102
+ = $product->getTypeId()
103
+ == Mage_Catalog_Model_Product_Type_Configurable::TYPE_CODE;
104
+
105
+ $allowedInputs = array(
106
+ 'label' => true,
107
+ 'text' => true,
108
+ 'textarea' => true,
109
+ 'date' => true,
110
+ 'select' => true,
111
+ 'multiselect' => true
112
+ );
113
+
114
+ $product['qty'] = $isConfigurable
115
+ ? $this->__('Edit individual sub-products')
116
+ : (int) $product->getStockItem()->getQty();
117
+
118
+ $form = new Varien_Data_Form();
119
+
120
+ $form
121
+ ->setUseContainer(true)
122
+ ->setMethod('post')
123
+ /* @see MVentory_Productivity_ProductController::saveAction() */
124
+ ->setAction(
125
+ Mage::getUrl('catalog/product/save', array('id' => $product->getId()))
126
+ );
127
 
128
  /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
129
+ foreach ($helper->getEditables($product) as $code => $attribute) {
130
+ $input = $attribute->getFrontendInput();
131
+
132
+ $form->addField(
133
+ $code,
134
+ isset($allowedInputs[$input]) ? $input : 'text',
135
+ array(
136
+ 'name' => $code,
137
+ 'label' => trim($attribute->getStoreLabel()),
138
+ 'values' => $values = $attribute->usesSource()
139
+ ? $attribute->getSource()->getAllOptions()
140
+ : null,
141
+
142
+ //In case it's a textarea, make it taller
143
+ 'rows' => 5
144
+ ),
145
+ ($after = $attribute['_insert_after']) ? $after : false
 
 
 
 
 
 
 
 
 
 
 
146
  );
 
 
 
 
 
 
147
  }
148
 
149
  $form->setValues($product->getData());
150
 
151
+ //Add field after values so "Submit" value is not overwritten
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  $form->addField('submit', 'submit', array(
153
  'value' => 'Save',
154
  'no_span' => true,
155
  ));
156
+
157
  $form->addField('cancel', 'button', array(
158
  'value' => 'Cancel',
159
  'no_span' => true,
160
  ));
161
+
162
  return $form;
163
  }
164
 
app/code/community/MVentory/Productivity/Helper/Attribute.php ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Open Software License (OSL 3.0)
7
+ * that is bundled with this package in the file LICENSE-OSL.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ *
11
+ * @package MVentory/Productivity
12
+ * @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
13
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
14
+ */
15
+
16
+ /**
17
+ * Attribute helper
18
+ *
19
+ * @package MVentory/Productivity
20
+ * @author Anatoly A. Kazantsev <anatoly@mventory.com>
21
+ */
22
+ class MVentory_Productivity_Helper_Attribute
23
+ extends MVentory_Productivity_Helper_Data
24
+ {
25
+ protected $_whitelist = array(
26
+ //Selecting category is not implemented on frontend
27
+ //'category_ids' => true,
28
+
29
+ 'name' => true,
30
+ 'description' => true,
31
+ 'short_description' => true,
32
+ 'sku' => true,
33
+ 'price' => true,
34
+ 'special_price' => true,
35
+
36
+ //Setting date via calendar component is not implemented on frontend
37
+ //'special_from_date' => true,
38
+ //'special_to_date' => true,
39
+
40
+ 'weight' => true,
41
+ 'tax_class_id' => true
42
+ );
43
+
44
+ //!!!TODO: do we need to ignore following attributes in the front-end editor
45
+ protected $_blacklist = array('cost' => true);
46
+
47
+ protected $_configurableBlacklist = array(
48
+ );
49
+
50
+ protected $_nonReplicable = array(
51
+ 'sku' => true,
52
+ 'price' => true,
53
+ 'special_price' => true,
54
+ 'special_from_date' => true,
55
+ 'special_to_data' => true,
56
+ 'weight' => true,
57
+
58
+ //!!!TODO: do we need to process API specific attributes here or not?
59
+ //We can apply additional filters required by other exts using event
60
+ //observer
61
+ //'product_barcode_' => true,
62
+ );
63
+
64
+ /**
65
+ * Return list of attributes which can be edited
66
+ *
67
+ * @param Mage_Catalog_Model_Product $product Product
68
+ * @return array List of Mage_Catalog_Model_Resource_Eav_Attribute entities
69
+ */
70
+ public function getEditables ($product) {
71
+ $setId = $product->getAttributeSetId();
72
+ $isConfigurable = $product->isConfigurable();
73
+
74
+ $attrs = $this->_getAttrs($setId);
75
+ $allow = $this->_getAllowedAttrsByUser();
76
+ $ignore = $isConfigurable
77
+ ? $this->_configurableBlacklist
78
+ : array();
79
+
80
+ //Add QTY pseudo-attribute before filtering so filtering rules can be
81
+ //applied for it
82
+ $attrs['qty'] = $this->_getQtyPseudoAttr($isConfigurable);
83
+
84
+ //Remove attributes which are used in configurable attributes so they
85
+ //won't appear in the fronend editor
86
+ if ($isConfigurable)
87
+ $attrs = $this->_removeConfigurableAttrs($attrs, $product);
88
+
89
+ $_attrs = array();
90
+
91
+ foreach ($attrs as $attr)
92
+ if ((!$attr->getId() || $attr->isInSet($setId))
93
+ && $this->_isAllowedAttribute($attr, $allow, $ignore))
94
+ $_attrs[$attr->getAttributeCode()] = $attr;
95
+
96
+ return $_attrs;
97
+ }
98
+
99
+ /**
100
+ * Return list of attributes which can be replocated among configurable
101
+ * products and its assigned simple products
102
+ *
103
+ * @param Mage_Catalog_Model_Product $product Product
104
+ * @return array List of Mage_Catalog_Model_Resource_Eav_Attribute entities
105
+ */
106
+ public function getReplicables ($product) {
107
+ $setId = $product->getAttributeSetId();
108
+
109
+ $attrs = $this->_removeConfigurableAttrs(
110
+ $this->_getAttrs($setId),
111
+ $product
112
+ );
113
+
114
+ $allow = $this->_getReplicableAttrsByUser();
115
+
116
+ $_attrs = array();
117
+
118
+ foreach ($attrs as $attr)
119
+ if ((!$attr->getId() || $attr->isInSet($setId))
120
+ && $this->_isAllowedAttribute($attr, $allow, $this->_nonReplicable))
121
+ $_attrs[$attr->getAttributeCode()] = $attr;
122
+
123
+ return $_attrs;
124
+ }
125
+
126
+ /**
127
+ * Return sorted list of attributes for the specified attribute set
128
+ *
129
+ * @param int $setId ID of atrribute set
130
+ * @return array List of Mage_Catalog_Model_Resource_Eav_Attribute entities
131
+ */
132
+ protected function _getAttrs ($setId) {
133
+ return Mage::getModel('catalog/product')
134
+ ->getResource()
135
+ ->loadAllAttributes()
136
+ ->getSortedAttributes($setId);
137
+ }
138
+
139
+ /**
140
+ * Check if specified attribute is allowed.
141
+ * List of allowed attributes has higher priority over list of ignored and
142
+ * blacklisted attributes.
143
+ *
144
+ * @param Mage_Catalog_Model_Resource_Eav_Attribute $attr Atrribute
145
+ * @param array $allow Key based list of allowed attributes
146
+ * @param array $ignore Key based list of attributes to ignore
147
+ */
148
+ protected function _isAllowedAttribute ($attr,
149
+ $allow = array(),
150
+ $ignore = array()) {
151
+
152
+ $code = $attr->getAttributeCode();
153
+
154
+ if (($allow && !isset($allow[$code]))
155
+ || isset($ignore[$code])
156
+ || isset($this->_blacklist[$code]))
157
+ return false;
158
+
159
+ return ($attr->getIsVisible() && $attr->getIsUserDefined())
160
+ || isset($this->_whitelist[$code]);
161
+ }
162
+
163
+ /**
164
+ * Get list of allowed attributes by user
165
+ *
166
+ * @return array Key based list of codes of allowed attributes
167
+ */
168
+ protected function _getAllowedAttrsByUser () {
169
+ $attrs = trim(
170
+ Mage::getStoreConfig(MVentory_Productivity_Model_Config::_EDITABLE_ATTRS)
171
+ );
172
+
173
+ return $attrs ? $this->_parseListOfAttrs($attrs) : array();
174
+ }
175
+
176
+ /**
177
+ * Get list of replicable attributes by user
178
+ *
179
+ * @return array Key based list of codes of replicable attributes
180
+ */
181
+ public function _getReplicableAttrsByUser () {
182
+ $attrs = strtolower(trim(
183
+ Mage::getStoreConfig(MVentory_Productivity_Model_Config::_COPY_ATTRS)
184
+ ));
185
+
186
+ return $attrs
187
+ ? $this->_parseListOfAttrs($attrs)
188
+ : $this->_getAllowedAttrsByUser();
189
+ }
190
+
191
+ /**
192
+ * Parse user-defined list of attribute codes and return it as key-based array
193
+ *
194
+ * @param string $attrs
195
+ * List of attribute coes. One attribute code per line
196
+ *
197
+ * @return array
198
+ * Key-based list of attribute codes
199
+ */
200
+ protected function _parseListOfAttrs ($attrs) {
201
+ return array_flip(array_map(
202
+ 'trim',
203
+ explode("\n", str_replace(array("\r\n", "\r"), "\n", trim($attrs)))
204
+ ));
205
+ }
206
+
207
+ /**
208
+ * Return model for QTY pseudo-attribute with prefilled required fields
209
+ *
210
+ * @param bool $isConfigurable Show if current product is configurable one
211
+ * @return Catalog_Model_Resource_Eav_Attribute
212
+ */
213
+ protected function _getQtyPseudoAttr ($isConfigurable) {
214
+ return Mage::getModel(
215
+ 'catalog/resource_eav_attribute',
216
+ array(
217
+ 'attribute_code' => 'qty',
218
+ 'store_label' => 'Qty',
219
+ 'frontend_input' => $isConfigurable ? 'label' : 'text',
220
+ 'uses_sources' => false,
221
+ 'is_visible' => true,
222
+ 'is_user_defined' => true,
223
+ '_insert_after' => 'price'
224
+ )
225
+ );
226
+ }
227
+
228
+ /**
229
+ * Filter out attributes which are used in configurable product
230
+ *
231
+ * @param array $attrs List of attributes to filter
232
+ * @param Mage_Catalog_Model_Product $product Configurable product
233
+ * @return array List of attributes
234
+ */
235
+ protected function _removeConfigurableAttrs ($attrs, $product) {
236
+ $_attrs = (($_attrs = $product->getConfigurableAttributesData()) !== null)
237
+ ? $_attrs
238
+ : $product
239
+ ->getTypeInstance()
240
+ ->getConfigurableAttributesAsArray();
241
+
242
+ foreach ($_attrs as $_attr)
243
+ unset($attrs[$_attr['attribute_code']]);
244
+
245
+ return $attrs;
246
+ }
247
+ }
app/code/community/MVentory/Productivity/Helper/Data.php CHANGED
@@ -219,30 +219,7 @@ class MVentory_Productivity_Helper_Data
219
  ->send();
220
  }
221
 
222
- /**
223
- * List attributes likely to be shown on product page.
224
- *
225
- * @param Mage_Catalog_Model_Product $product
226
- * @return array of Mage_Catalog_Model_Resource_Eav_Attribute
227
- */
228
- public function getVisibleAttributes($product) {
229
- $result = array();
230
- if (!$product) return $result;
231
-
232
- $attributes = $product->getAttributes();
233
- // these attrs are always shown somewhere even if not "visible on front"
234
- $result['name'] = $attributes['name'];
235
- $result['description'] = $attributes['description'];
236
- $result['price'] = $attributes['price'];
237
-
238
- foreach ($attributes as $attribute) {
239
- $code = $attribute->getAttributeCode();
240
-
241
- if ($attribute->getIsVisibleOnFront() || substr($code, -1) === '_')
242
- $result[$code] = $attribute;
243
- }
244
-
245
- return $result;
246
  }
247
-
248
  }
219
  ->send();
220
  }
221
 
222
+ public function isMVentoryModuleEnabled () {
223
+ return parent::isModuleEnabled('MVentory_API');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  }
 
225
  }
app/code/community/MVentory/Productivity/Model/Config.php CHANGED
@@ -26,9 +26,16 @@ class MVentory_Productivity_Model_Config {
26
  const _CATEGORY_HOME_URL = 'productivity/category/home_url';
27
  const _DISPLAY_PRODUCTS = 'productivity/category/display_descending_products';
28
  const _PRODUCT_SAVE_SCOPE = 'productivity/product/save_scope';
 
 
29
  const _ANALYTICS_URL = 'productivity/analytics/url';
30
 
31
  //Product save scopes
32
  const PRODUCT_SCOPE_GLOBAL = 1;
33
  const PRODUCT_SCOPE_CURRENT = 2;
 
 
 
 
 
34
  }
26
  const _CATEGORY_HOME_URL = 'productivity/category/home_url';
27
  const _DISPLAY_PRODUCTS = 'productivity/category/display_descending_products';
28
  const _PRODUCT_SAVE_SCOPE = 'productivity/product/save_scope';
29
+ const _EDITABLE_ATTRS = 'productivity/product/editable_attr';
30
+ const _COPY_ATTRS = 'productivity/product/copy_attrs';
31
  const _ANALYTICS_URL = 'productivity/analytics/url';
32
 
33
  //Product save scopes
34
  const PRODUCT_SCOPE_GLOBAL = 1;
35
  const PRODUCT_SCOPE_CURRENT = 2;
36
+
37
+ //Types of flatten category tree
38
+ const FLATTEN_NO = 0;
39
+ const FLATTEN_PATHS = 1;
40
+ const FLATTEN_EXPAND = 2;
41
  }
app/code/community/MVentory/Productivity/Model/Mage/Catalog/Category.php CHANGED
@@ -71,6 +71,19 @@ class MVentory_Productivity_Model_Mage_Catalog_Category
71
  $asCollection = false,
72
  $toLoad = true) {
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  $categories = parent::getCategories(
75
  $parent,
76
  $recursionLevel,
@@ -79,9 +92,7 @@ class MVentory_Productivity_Model_Mage_Catalog_Category
79
  $toLoad
80
  );
81
 
82
- return Mage::getStoreConfig(
83
- MVentory_Productivity_Model_Config::_CATEGORY_FLATTEN_TREE
84
- )
85
  ? $this->_removeParentCategories($categories)
86
  : $categories;
87
  }
@@ -108,4 +119,101 @@ class MVentory_Productivity_Model_Mage_Catalog_Category
108
 
109
  return $this->_removeParentCategories($children);
110
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
71
  $asCollection = false,
72
  $toLoad = true) {
73
 
74
+ $flattenType = (int) Mage::getStoreConfig(
75
+ MVentory_Productivity_Model_Config::_CATEGORY_FLATTEN_TREE
76
+ );
77
+
78
+ if ($flattenType == MVentory_Productivity_Model_Config::FLATTEN_EXPAND)
79
+ return $this->_expandCategories($this->_getCategories(
80
+ $parent,
81
+ $recursionLevel,
82
+ $sorted,
83
+ $asCollection,
84
+ $toLoad
85
+ ));
86
+
87
  $categories = parent::getCategories(
88
  $parent,
89
  $recursionLevel,
92
  $toLoad
93
  );
94
 
95
+ return $flattenType == MVentory_Productivity_Model_Config::FLATTEN_PATHS
 
 
96
  ? $this->_removeParentCategories($categories)
97
  : $categories;
98
  }
119
 
120
  return $this->_removeParentCategories($children);
121
  }
122
+
123
+ /**
124
+ * Expand recursively hidden (include_in_menu = 0) categories. Preserve
125
+ * order of categories. Hide empty (no subcategories) and hidden categories.
126
+ *
127
+ * @param Varien_Data_Tree_Node_Collection $categories Collection of nodes
128
+ * @return Varien_Data_Tree_Node_Collection
129
+ */
130
+ protected function _expandCategories ($categories) {
131
+ if (!$categories->count())
132
+ return $categories;
133
+
134
+ foreach ($categories as $id => $category) {
135
+ $children = $this->_expandCategories($category->getChildren());
136
+
137
+ $noChildren = !$children->count();
138
+ $notIncludeInMenu = !$category->getIncludeInMenu();
139
+
140
+ //Hide empty and not included in menu categories
141
+ if ($notIncludeInMenu && $noChildren) {
142
+ $categories->delete($category);
143
+
144
+ continue;
145
+ }
146
+
147
+ //Ignore empty categories
148
+ if ($noChildren)
149
+ continue;
150
+
151
+ //Remember hidden category to expand on next step
152
+ if ($notIncludeInMenu)
153
+ $replace[$id] = true;
154
+ }
155
+
156
+ if (isset($replace)) {
157
+
158
+ //Expand hidden categories and re-add visible categories as is to preserve
159
+ //original order
160
+ foreach ($categories as $id => $category) {
161
+ $categories->delete($category);
162
+
163
+ if (isset($replace[$id])) {
164
+
165
+ //Copy level and position values of expanded category to it's children
166
+ $level = $category->getLevel();
167
+ $position = $category->getPosition();
168
+
169
+ foreach ($category->getChildren() as $child) {
170
+ $child
171
+ ->setLevel($level)
172
+ ->setPosition($position);
173
+
174
+ $category->removeChild($child);
175
+ $categories->add($child);
176
+ }
177
+ } else
178
+ $categories->add($category);
179
+ }
180
+ }
181
+
182
+ return $categories;
183
+ }
184
+
185
+ /**
186
+ * Retrieve categories
187
+ *
188
+ * This method is copy of
189
+ * Mage_Catalog_Model_Resource_Category::getCategories(), but with changed
190
+ * category tree model for expanding hidden categories functionality.
191
+ *
192
+ * !!!TODO: move to some helper class to minimize confusion with
193
+ * getCategories() method of this class
194
+ *
195
+ * @param integer $parent
196
+ * @param integer $recursionLevel
197
+ * @param boolean|string $sorted
198
+ * @param boolean $asCollection
199
+ * @param boolean $toLoad
200
+ * @return Varien_Data_Tree_Node_Collection|Mage_Catalog_Model_Resource_Category_Collection
201
+ */
202
+ protected function _getCategories ($parent,
203
+ $recursionLevel = 0,
204
+ $sorted = false,
205
+ $asCollection = false,
206
+ $toLoad = true)
207
+ {
208
+ /* @var $tree MVentory_Productivity_Model_Resource_Category_Tree */
209
+ $tree = Mage::getResourceModel('productivity/category_tree');
210
+
211
+ $node = $tree
212
+ ->loadNode($parent)
213
+ ->loadChildren($recursionLevel);
214
+
215
+ $tree->addCollectionData(null, $sorted, $parent, $toLoad, true);
216
+
217
+ return $asCollection ? $tree->getCollection() : $node->getChildren();
218
+ }
219
  }
app/code/community/MVentory/Productivity/Model/Observer.php CHANGED
@@ -61,13 +61,29 @@ class MVentory_Productivity_Model_Observer {
61
  $wherePart = $select->getPart(Zend_Db_Select::WHERE);
62
 
63
  foreach ($wherePart as $i => $condition)
64
- if (strpos($condition, 'small_image') !== false)
 
 
65
  unset($wherePart[$i]);
66
 
67
  $select->setPart(Zend_Db_Select::WHERE, $wherePart);
68
 
69
- $collection->addAttributeToFilter('small_image',
70
- array('in' => array('no_selection', '')));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
72
 
73
  public function rememberAdminState($observer) {
61
  $wherePart = $select->getPart(Zend_Db_Select::WHERE);
62
 
63
  foreach ($wherePart as $i => $condition)
64
+ if (strpos($condition, 'image') !== false
65
+ || strpos($condition, 'small_image') !== false
66
+ || strpos($condition, 'thumbnail') !== false)
67
  unset($wherePart[$i]);
68
 
69
  $select->setPart(Zend_Db_Select::WHERE, $wherePart);
70
 
71
+ $collection->addAttributeToFilter(
72
+ array(
73
+ array(
74
+ 'attribute' => 'image',
75
+ 'in' => array('no_selection', '')
76
+ ),
77
+ array(
78
+ 'attribute' => 'small_image',
79
+ 'in' => array('no_selection', '')
80
+ ),
81
+ array(
82
+ 'attribute' => 'thumbnail',
83
+ 'in' => array('no_selection', '')
84
+ )
85
+ )
86
+ );
87
  }
88
 
89
  public function rememberAdminState($observer) {
app/code/community/MVentory/Productivity/Model/Resource/Category/Tree.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Open Software License (OSL 3.0)
7
+ * that is bundled with this package in the file LICENSE-OSL.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ *
11
+ * @package MVentory/Productivity
12
+ * @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
13
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
14
+ */
15
+
16
+ /**
17
+ * Category tree model
18
+ *
19
+ * @package MVentory/Productivity
20
+ * @author Anatoly A. Kazantsev <anatoly@mventory.com>
21
+ */
22
+
23
+ class MVentory_Productivity_Model_Resource_Category_Tree
24
+ extends Mage_Catalog_Model_Resource_Category_Tree
25
+ {
26
+ /**
27
+ * Add specified or new collection of categories to category tree. Filter
28
+ * out disabled and non-active categories (if $onlyActive parameter is True)
29
+ * and categories with IDs from $exclude parameter. Load category data and
30
+ * add it to tree nodes if $toLoad parameter is True
31
+ *
32
+ * NOTE: this method is redefined to remove filtering out categories
33
+ * by 'include_in_menu' field for expanding hidden categories in menu
34
+ *
35
+ * !!!IMPORTANT: this method should stay synchronized with original one.
36
+ * Changes on original method should be inspected and applied
37
+ * on every Magento release.
38
+ *
39
+ * @param Mage_Catalog_Model_Resource_Category_Collection $collection
40
+ * @param boolean|string $sorted Sort collection of categories by specified
41
+ * field or by 'name' field if is True
42
+ * @param array $exclude List of category IDs to exclude
43
+ * @param boolean $toLoad Load or not category data
44
+ * @param boolean $onlyActive Load only active categories
45
+ * @return Mage_Catalog_Model_Resource_Category_Tree
46
+ */
47
+ public function addCollectionData ($collection = null,
48
+ $sorted = false,
49
+ $exclude = array(),
50
+ $toLoad = true,
51
+ $onlyActive = false)
52
+ {
53
+ if (is_null($collection))
54
+ $collection = $this->getCollection($sorted);
55
+ else
56
+ $this->setCollection($collection);
57
+
58
+ if (!is_array($exclude))
59
+ $exclude = array($exclude);
60
+
61
+ //!!!TODO: This can be combined with filtering $disabledIds.
62
+ //Just merge $exclude with $disabledIds and use it for filtering by
63
+ //'entity_id' field with 'nin' condition.
64
+ $nodeIds = array();
65
+
66
+ foreach ($this->getNodes() as $node)
67
+ if (!in_array($node->getId(), $exclude))
68
+ $nodeIds[] = $node->getId();
69
+
70
+ $collection->addIdFilter($nodeIds);
71
+
72
+ if ($onlyActive) {
73
+ $disabledIds = $this->_getDisabledIds($collection);
74
+
75
+ if ($disabledIds)
76
+ $collection->addFieldToFilter(
77
+ 'entity_id',
78
+ array('nin' => $disabledIds)
79
+ );
80
+
81
+ $collection->addAttributeToFilter('is_active', 1);
82
+
83
+ //In original method it filters out categories by 'include_in_menu'
84
+ //field, but we don't need it for expanding hidden ('include_in_menu' = 0)
85
+ //categories. So this filter was removed and following line was added
86
+ //to load values of 'include_in_menu' field in collection's entities
87
+ $collection->addAttributeToSelect('include_in_menu');
88
+ }
89
+
90
+ if ($this->_joinUrlRewriteIntoCollection) {
91
+ $collection->joinUrlRewrite();
92
+ $this->_joinUrlRewriteIntoCollection = false;
93
+ }
94
+
95
+ if ($toLoad) {
96
+ $collection->load();
97
+
98
+ foreach ($collection as $category)
99
+ if ($node = $this->getNodeById($category->getId()))
100
+ $node->addData($category->getData());
101
+
102
+ foreach ($this->getNodes() as $node)
103
+ if (!$collection->getItemById($node->getId()) && $node->getParent())
104
+ $this->removeNode($node);
105
+ }
106
+
107
+ return $this;
108
+ }
109
+ }
app/code/community/MVentory/Productivity/Model/Setting/Source/Copyattrs.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Open Software License (OSL 3.0)
7
+ * that is bundled with this package in the file LICENSE-OSL.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ *
11
+ * @package MVentory/Productivity
12
+ * @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
13
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
14
+ */
15
+
16
+ /**
17
+ * Source model for 'Copy from configurable to simple products' option
18
+ *
19
+ * @package MVentory/Productivity
20
+ * @author Anatoly A. Kazantsev <anatoly@mventory.com>
21
+ */
22
+ class MVentory_Productivity_Model_Setting_Source_Copyattrs {
23
+
24
+ /**
25
+ * Options getter
26
+ *
27
+ * @return array
28
+ */
29
+ public function toOptionArray () {
30
+ $helper = Mage::helper('productivity');
31
+
32
+ return array(
33
+ array(
34
+ 'value' => 'name',
35
+ 'label' => $helper->__('Name')
36
+ ),
37
+ array(
38
+ 'value' => 'description',
39
+ 'label' => $helper->__('Description')
40
+ ),
41
+ array(
42
+ 'value' => 'short_description',
43
+ 'label' => $helper->__('Short Description')
44
+ )
45
+ );
46
+ }
47
+ }
app/code/community/MVentory/Productivity/Model/Setting/Source/Flattentype.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Open Software License (OSL 3.0)
7
+ * that is bundled with this package in the file LICENSE-OSL.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ *
11
+ * @package MVentory/Productivity
12
+ * @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
13
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
14
+ */
15
+
16
+ /**
17
+ * Source model for type of flatten category tree
18
+ *
19
+ * @package MVentory/Productivity
20
+ * @author Anatoly A. Kazantsev <anatoly@mventory.com>
21
+ */
22
+ class MVentory_Productivity_Model_Setting_Source_Flattentype {
23
+
24
+ /**
25
+ * Options getter
26
+ *
27
+ * @return array
28
+ */
29
+ public function toOptionArray () {
30
+ $helper = Mage::helper('productivity');
31
+
32
+ return array(
33
+ array(
34
+ 'value' => MVentory_Productivity_Model_Config::FLATTEN_NO,
35
+ 'label' => $helper->__('No')
36
+ ),
37
+ array(
38
+ 'value' => MVentory_Productivity_Model_Config::FLATTEN_PATHS,
39
+ 'label' => $helper->__('Flatten single branch paths')
40
+ ),
41
+ array(
42
+ 'value' => MVentory_Productivity_Model_Config::FLATTEN_EXPAND,
43
+ 'label' => $helper->__('Show children of hidden parents')
44
+ )
45
+ );
46
+ }
47
+ }
48
+
49
+ ?>
app/code/community/MVentory/Productivity/controllers/ProductController.php CHANGED
@@ -35,34 +35,50 @@ class MVentory_Productivity_ProductController extends Mage_Core_Controller_Front
35
  $productId = $request->getParam('id');
36
  // Useful stuff
37
  $storeId = Mage::app()->getStore()->getId();
38
- $helper = Mage::helper('productivity');
39
 
40
  if ($helper->isReviewerLogged())
41
  {
42
  //Check if save scope is set and we need to load product
43
  //with dara from current store
44
- $hasScope = (int) Mage::getStoreConfig(
45
  MVentory_Productivity_Model_Config::_PRODUCT_SAVE_SCOPE
46
  );
47
- $hasScope = MVentory_Productivity_Model_Config::PRODUCT_SCOPE_CURRENT
48
- == $hasScope;
 
 
 
 
 
 
 
 
 
 
49
 
50
  $product = Mage::getModel('catalog/product');
51
 
52
- //Set current store ID before laoding product if save scope is set,
53
  //e.g. user selected Current scope optin in admin interface
54
- if ($hasScope)
55
  $product->setStoreId($storeId);
56
 
57
- $product->load($productId);
 
 
58
 
59
  // Only allow certain attributes to be set, if missing product will not be changed.
60
  $data = array_intersect_key(
61
  $request->getPost(),
62
- $helper->getVisibleAttributes($product)
63
  );
64
- if (isset($data['description'])) {
65
- $data['short_description'] = $data['description'];
 
 
 
 
66
  }
67
 
68
  //Find all attributes which value was changed in the editor by comparing
@@ -78,8 +94,8 @@ class MVentory_Productivity_ProductController extends Mage_Core_Controller_Front
78
  if ($product->getData($code) != $value)
79
  $changeAttrs[$code] = true;
80
 
81
- if ($product->getTypeId() != 'configurable') {
82
- $qty = (float) $request->getParam('qty');
83
 
84
  $data['stock_data'] = array(
85
  'qty'
@@ -93,48 +109,109 @@ class MVentory_Productivity_ProductController extends Mage_Core_Controller_Front
93
  );
94
  }
95
 
96
- if ($data) {
97
  $product->addData($data);
98
 
99
- //Set value of not changed attributes to false to prevents from copying
100
- //attribute's values to current scope if user selected Current store
101
- //option of Save edits to setting in admin interface
102
- //
103
- //Filter out following attributes:
104
- // - Gallery attr (is a complex attr with it's own editor)
105
- // - Global (setting value of global attr to false removes it globally)
106
- // - Non-visible (non-visible attributes can't be edited directly)
107
- // - Without input field (this attributes can'be edited directly)
108
- //
109
- //Filtering rules are taken from:
110
- // - Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Attributes::_prepareForm()
111
- // - Mage_Adminhtml_Block_Widget_Form::_setFieldset()
112
- if ($hasScope) foreach ($product->getAttributes() as $code => $attr) {
113
- $allow = $code != 'gallery'
114
- && $attr->getIsGlobal()
115
- != Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL
116
- && $attr->getIsVisible()
117
- && $attr->getFrontend()->getInputType();
118
-
119
- if (!$allow || isset($changeAttrs[$code]))
120
- continue;
121
-
122
- $product->setData($code, false);
123
- }
124
-
125
- //Product saves must be made from admin store
126
- Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
127
 
128
  $product->save();
129
 
 
 
 
130
  //Reset store to be neat
131
  Mage::app()->setCurrentStore($storeId);
132
  }
133
  }
134
 
135
- // Always show same page, even if nothing has changed
136
  $this->_redirectUrl($product->setData('url', null)->getProductUrl());
137
  }
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
35
  $productId = $request->getParam('id');
36
  // Useful stuff
37
  $storeId = Mage::app()->getStore()->getId();
38
+ $helper = Mage::helper('productivity/attribute');
39
 
40
  if ($helper->isReviewerLogged())
41
  {
42
  //Check if save scope is set and we need to load product
43
  //with dara from current store
44
+ $saveScope = (int) Mage::getStoreConfig(
45
  MVentory_Productivity_Model_Config::_PRODUCT_SAVE_SCOPE
46
  );
47
+
48
+ if ($saveScope
49
+ != MVentory_Productivity_Model_Config::PRODUCT_SCOPE_CURRENT)
50
+ $storeId = false;
51
+
52
+ unset($saveScope);
53
+
54
+ //Product loads and saves must be made from admin store
55
+ //- Magento doesn't fill origData array when product is loaded from
56
+ // non admin scope, so some core comparing function (for comparing
57
+ // original and current product data) won't work as expected
58
+ Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
59
 
60
  $product = Mage::getModel('catalog/product');
61
 
62
+ //Set current store ID before loading product if save scope is set,
63
  //e.g. user selected Current scope optin in admin interface
64
+ if ($storeId !== false)
65
  $product->setStoreId($storeId);
66
 
67
+ $isConfigurable = $product
68
+ ->load($productId)
69
+ ->isConfigurable();
70
 
71
  // Only allow certain attributes to be set, if missing product will not be changed.
72
  $data = array_intersect_key(
73
  $request->getPost(),
74
+ $helper->getEditables($product)
75
  );
76
+
77
+ if (isset($data['qty'])) {
78
+ if (!$isConfigurable)
79
+ $qty = $data['qty'];
80
+
81
+ unset($data['qty']);
82
  }
83
 
84
  //Find all attributes which value was changed in the editor by comparing
94
  if ($product->getData($code) != $value)
95
  $changeAttrs[$code] = true;
96
 
97
+ if (isset($qty)) {
98
+ $qty = (float) $qty;
99
 
100
  $data['stock_data'] = array(
101
  'qty'
109
  );
110
  }
111
 
112
+ if ($changeAttrs || isset($qty)) {
113
  $product->addData($data);
114
 
115
+ if ($storeId !== false)
116
+ $this->_unsetValues($product, $changeAttrs);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
  $product->save();
119
 
120
+ if ($isConfigurable)
121
+ $this->_copyDataToSimpleProducts($product, $changeAttrs, $storeId);
122
+
123
  //Reset store to be neat
124
  Mage::app()->setCurrentStore($storeId);
125
  }
126
  }
127
 
128
+ //Always show same page, even if nothing has changed
129
  $this->_redirectUrl($product->setData('url', null)->getProductUrl());
130
  }
131
 
132
+ /**
133
+ * Set value of not changed attributes to false to prevents from copying
134
+ * attribute's values to current scope if user selected Current store
135
+ * option of Save edits to setting in admin interface
136
+ *
137
+ * Filter out following attributes:
138
+ * - Gallery attr (is a complex attr with it's own editor)
139
+ * - Global (setting value of global attr to false removes it globally)
140
+ * - Non-visible (non-visible attributes can't be edited directly)
141
+ * - Without input field (this attributes can'be edited directly)
142
+ *
143
+ * Filtering rules are taken from:
144
+ * - Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Attributes::_prepareForm()
145
+ * - Mage_Adminhtml_Block_Widget_Form::_setFieldset()
146
+ *
147
+ * @param Mage_Catalog_Model_Product $product Product
148
+ * @param array $changed Key-based list of updated attributes
149
+ */
150
+ protected function _unsetValues ($product, $changed) {
151
+ foreach ($product->getAttributes() as $code => $attr) {
152
+ $allow = $code != 'gallery'
153
+ && $attr->getIsGlobal()
154
+ != Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL
155
+ && $attr->getIsVisible()
156
+ && $attr->getFrontend()->getInputType();
157
+
158
+ if (!$allow || isset($changed[$code]))
159
+ continue;
160
+
161
+ $product
162
+ ->setData($code, false)
163
+ ->setOrigData($code, false);
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Copy data from configurable product to it associated
169
+ * simple products
170
+ *
171
+ * @param Mage_Catalog_Model_Product $configurable Configurable product
172
+ * @param array $changed Key-based list of updated attributes
173
+ * @param int|bool $storeId Current store ID
174
+ */
175
+ protected function _copyDataToSimpleProducts ($configurable,
176
+ $changed,
177
+ $storeId = false)
178
+ {
179
+ if (!$data = $this->_getDataForCopying($configurable, $changed))
180
+ return;
181
+
182
+ $childrenIds = Mage::getModel('catalog/product_type_configurable')
183
+ ->getUsedProductIds($configurable);
184
+
185
+ if (!$childrenIds)
186
+ return;
187
+
188
+ //Merge data from parent product to children and save them
189
+ foreach ($childrenIds as $childId) {
190
+ $child = Mage::getModel('catalog/product')
191
+ ->setStoreId($storeId)
192
+ ->load($childId)
193
+ ->addData($data);
194
+
195
+ if ($storeId !== false)
196
+ $this->_unsetValues($child, $data);
197
+
198
+ $child->save();
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Get data from configurable product for updated attributes and only selected
204
+ * attributes on the extension settings
205
+ *
206
+ * @param $configurable Configurable product
207
+ * @return array|null Data for copying into associated simple products
208
+ */
209
+ protected function _getDataForCopying ($configurable, $changed) {
210
+ return array_intersect_key(
211
+ $configurable->getData(),
212
+ $changed,
213
+ Mage::helper('productivity/attribute')->getReplicables($configurable)
214
+ );
215
+ }
216
  }
217
 
app/code/community/MVentory/Productivity/etc/config.xml CHANGED
@@ -62,9 +62,13 @@
62
  <models>
63
  <productivity>
64
  <class>MVentory_Productivity_Model</class>
65
- <resourceModel>MVentory_Productivity_resources</resourceModel>
66
  </productivity>
67
 
 
 
 
 
68
  <catalog>
69
  <rewrite>
70
  <category>MVentory_Productivity_Model_Mage_Catalog_Category</category>
@@ -217,6 +221,9 @@
217
  <productivity>
218
  <product>
219
  <save_scope>2</save_scope>
 
 
 
220
  </product>
221
  </productivity>
222
  </default>
62
  <models>
63
  <productivity>
64
  <class>MVentory_Productivity_Model</class>
65
+ <resourceModel>productivity_resources</resourceModel>
66
  </productivity>
67
 
68
+ <productivity_resources>
69
+ <class>MVentory_Productivity_Model_Resource</class>
70
+ </productivity_resources>
71
+
72
  <catalog>
73
  <rewrite>
74
  <category>MVentory_Productivity_Model_Mage_Catalog_Category</category>
221
  <productivity>
222
  <product>
223
  <save_scope>2</save_scope>
224
+
225
+ <!-- '.' - Don't copy any attributes -->
226
+ <copy_attrs>.</copy_attrs>
227
  </product>
228
  </productivity>
229
  </default>
app/code/community/MVentory/Productivity/etc/system.xml CHANGED
@@ -58,10 +58,18 @@
58
  <fields>
59
  <flatten_tree translate="label comment tooltip">
60
  <label>Flatten categories tree</label>
61
- <comment>Skip tree nodes with no products and only a single sub-category.</comment>
62
- <tooltip>E.g. if category Furniture has no products assigned to it, but has a single sub-category Tables then Furniture is removed from the tree and Tables is shown in its place.</tooltip>
 
 
 
 
 
 
 
 
63
  <frontend_type>select</frontend_type>
64
- <source_model>adminhtml/system_config_source_yesno</source_model>
65
 
66
  <show_in_default>1</show_in_default>
67
  <show_in_website>1</show_in_website>
@@ -123,6 +131,36 @@
123
 
124
  <sort_order>1</sort_order>
125
  </save_scope>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  </fields>
127
  </product>
128
 
@@ -151,6 +189,17 @@
151
  </url>
152
  </fields>
153
  </analytics>
 
 
 
 
 
 
 
 
 
 
 
154
  </groups>
155
  </productivity>
156
  </sections>
58
  <fields>
59
  <flatten_tree translate="label comment tooltip">
60
  <label>Flatten categories tree</label>
61
+ <comment>Behavior of categories tree</comment>
62
+ <tooltip>
63
+ <![CDATA[
64
+ <ul class="productivity-tooltip-list">
65
+ <li>No - default Magento behavior</li>
66
+ <li>Flatten single branch paths - Do not show parents with only a single subcategory to show the subcategory in its place. E.g. Cat A only one subcategory Cat AA. Category Cat AA will show in place of Cat A</li>
67
+ <li>Show children of hidden parents - If Cat A has "Include in Navigation Menu" set to NO then exclude it, but show it's subcategories at the level of Cat A</li>
68
+ </ul>
69
+ ]]>
70
+ </tooltip>
71
  <frontend_type>select</frontend_type>
72
+ <source_model>productivity/setting_source_flattentype</source_model>
73
 
74
  <show_in_default>1</show_in_default>
75
  <show_in_website>1</show_in_website>
131
 
132
  <sort_order>1</sort_order>
133
  </save_scope>
134
+
135
+ <editable_attr translate="label comment tooltip">
136
+ <label>Editable fields</label>
137
+ <comment>One attribute code per line or leave empty to allow all.</comment>
138
+ <tooltip>Only listed attributes can be edited via the front end. Leave empty to allow all attributes to be edited. Use qty code for product quantity.</tooltip>
139
+ <frontend_type>textarea</frontend_type>
140
+
141
+ <show_in_default>1</show_in_default>
142
+ <show_in_website>1</show_in_website>
143
+ <show_in_store>1</show_in_store>
144
+
145
+ <sort_order>2</sort_order>
146
+ </editable_attr>
147
+
148
+ <copy_attrs>
149
+ <label>Copy from configurable to simple products</label>
150
+ <comment>One attribute code per line to copy into associated products, blank for all or . for none.</comment>
151
+ <tooltip><![CDATA[Changes in configurable products are always saved in the product itself, but the listed attributes can also be copied into all associated simple products.<br /><br />Leave blank to copy all attributes, except quantity.<br /><br />Use . or any other string that is not an attribute name to avoid copying any of the values.]]></tooltip>
152
+ <frontend_type>textarea</frontend_type>
153
+
154
+ <!--
155
+ <source_model>productivity/setting_source_copyattrs</source_model>
156
+ -->
157
+
158
+ <show_in_default>1</show_in_default>
159
+ <show_in_website>1</show_in_website>
160
+ <show_in_store>1</show_in_store>
161
+
162
+ <sort_order>3</sort_order>
163
+ </copy_attrs>
164
  </fields>
165
  </product>
166
 
189
  </url>
190
  </fields>
191
  </analytics>
192
+
193
+ <build_info>
194
+ <frontend_model>productivity/config_buildinfo</frontend_model>
195
+
196
+ <show_in_default>1</show_in_default>
197
+ <show_in_website>1</show_in_website>
198
+ <show_in_store>1</show_in_store>
199
+
200
+ <sort_order>5</sort_order>
201
+ </build_info>
202
+
203
  </groups>
204
  </productivity>
205
  </sections>
app/design/adminhtml/default/default/template/productivity/config/build-info.phtml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Creative Commons License BY-NC-ND.
7
+ * NonCommercial — You may not use the material for commercial purposes.
8
+ * NoDerivatives — If you remix, transform, or build upon the material,
9
+ * you may not distribute the modified material.
10
+ * See the full license at http://creativecommons.org/licenses/by-nc-nd/4.0/
11
+ *
12
+ * See http://mventory.com/legal/licensing/ for other licensing options.
13
+ *
14
+ * @package MVentory/Productivity
15
+ * @copyright Copyright (c) 2015 mVentory Ltd. (http://mventory.com)
16
+ * @license http://creativecommons.org/licenses/by-nc-nd/4.0/
17
+ */
18
+
19
+ ?>
20
+
21
+ Build version: 903ba0a
22
+ <BR/>Build date: 01/02/2015 08:22 UTC
app/design/frontend/base/default/layout/productivity.xml CHANGED
@@ -21,6 +21,8 @@
21
  </productivity_rss_product_latest>
22
 
23
  <productivity_panel>
 
 
24
  <reference name="head">
25
  <action method="addCss">
26
  <stylesheet>productivity/css/styles.css</stylesheet>
@@ -33,7 +35,7 @@
33
  </productivity_panel>
34
 
35
  <catalog_product_view>
36
- <update handle="jquery" />
37
 
38
  <reference name="head">
39
  <action method="addJs">
@@ -86,10 +88,6 @@
86
  <update handle="productivity_panel" />
87
  </catalog_category_layered>
88
 
89
- <catalog_product_view>
90
- <update handle="productivity_panel" />
91
- </catalog_product_view>
92
-
93
  <cms_page>
94
  <update handle="productivity_panel" />
95
  </cms_page>
21
  </productivity_rss_product_latest>
22
 
23
  <productivity_panel>
24
+ <update handle="jquery" />
25
+
26
  <reference name="head">
27
  <action method="addCss">
28
  <stylesheet>productivity/css/styles.css</stylesheet>
35
  </productivity_panel>
36
 
37
  <catalog_product_view>
38
+ <update handle="productivity_panel" />
39
 
40
  <reference name="head">
41
  <action method="addJs">
88
  <update handle="productivity_panel" />
89
  </catalog_category_layered>
90
 
 
 
 
 
91
  <cms_page>
92
  <update handle="productivity_panel" />
93
  </cms_page>
app/design/frontend/base/default/template/productivity/panel.phtml CHANGED
@@ -74,6 +74,10 @@ if ($_type == 'product') {
74
 
75
  <?php endif; ?>
76
 
 
 
 
 
77
  <li>
78
  <a title="<?php echo $this->__('View products with no images'); ?>" href="<?php echo $this->_getWithoutImagesLink() ?>"><?php echo $this->__('No-image products'); ?></a>
79
  </li>
@@ -99,10 +103,33 @@ if ($_type == 'product') {
99
  </ul>
100
  </div>
101
 
102
- <?php if ($_type == 'product'): ?>
103
  <div id="productivity-panel-content">
104
  <div id="productivity-panel-content-inner" class="clearer">
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  <div id="productivity-uploader">
107
  <div id="productivity-uploader-element"></div>
108
 
@@ -124,21 +151,20 @@ if ($_type == 'product') {
124
  <?php echo $this->getEditForm()->setHtmlIdPrefix('productivity_edit_form_')->toHtml() ?>
125
  </div>
126
  </div>
 
127
 
128
  </div>
129
  </div>
130
- <?php endif; ?>
131
 
132
  </div>
133
 
134
- <?php if ($_type == 'product'): ?>
135
-
136
  <script type="text/javascript">
137
  //<![CDATA[
138
 
139
  jQuery(function ($) {
140
  var $panel = $('#productivity-panel');
141
- var $content = $('#productivity-panel-content');
 
142
 
143
  var menu_height = $('#productivity-panel-menu').height();
144
 
@@ -180,6 +206,12 @@ jQuery(function ($) {
180
  return false;
181
  });
182
 
 
 
 
 
 
 
183
  $('#productivity_edit_form_cancel').on('click', function () {
184
  $panel.removeClass('productivity-task-edit-form-on');
185
 
@@ -193,5 +225,3 @@ jQuery(function ($) {
193
  </script>
194
 
195
  <?php endif; ?>
196
-
197
- <?php endif; ?>
74
 
75
  <?php endif; ?>
76
 
77
+ <li>
78
+ <a title="<?php echo $this->__('Generate and print unique product codes'); ?>" id="productivity-task-qr" class="productivity-panel-task" href="#"><?php echo $this->__('QR tags')?></a>
79
+ </li>
80
+
81
  <li>
82
  <a title="<?php echo $this->__('View products with no images'); ?>" href="<?php echo $this->_getWithoutImagesLink() ?>"><?php echo $this->__('No-image products'); ?></a>
83
  </li>
103
  </ul>
104
  </div>
105
 
 
106
  <div id="productivity-panel-content">
107
  <div id="productivity-panel-content-inner" class="clearer">
108
 
109
+ <?php //Panel for QR labels generating ?>
110
+
111
+ <div id="productivity-qr">
112
+ <?php if ($_helper->isMVentoryModuleEnabled() || true): ?>
113
+
114
+ <select id="productivity-qr-select">
115
+ <option value="labels/1" selected>Generate Labels</option>
116
+ <option value="links/1">Generate Links</option>
117
+ <option value="links/1/codes/1">Generate Links And Codes</option>
118
+ <option value="images/1">Generate Image Links</option>
119
+ <option value="images/1/codes/1">Generate Image Links And Codes</option>
120
+ </select>
121
+ <button id="productivity-qr-button">Go!</button>
122
+
123
+ <?php else: ?>
124
+
125
+ <p>Did you know you can use QR codes instead of barcodes?</p>
126
+ <p>It is much cheaper, faster and more user friendly. A barcode is just a meaningless number. A QR code can be a product SKU and a direct link to that product at the same time - scan it with our <a href="http://try.mventory.com">Admin/PoS/Inventory app</a> for Magento or any other generic scanner.</p>
127
+ <p>Using this feature requires installation of <a href="http://mventory.com/magento-extensions/">free mVentory API extension</a>.</p>
128
+
129
+ <?php endif; ?>
130
+ </div>
131
+
132
+ <?php if ($_type == 'product'): ?>
133
  <div id="productivity-uploader">
134
  <div id="productivity-uploader-element"></div>
135
 
151
  <?php echo $this->getEditForm()->setHtmlIdPrefix('productivity_edit_form_')->toHtml() ?>
152
  </div>
153
  </div>
154
+ <?php endif; ?>
155
 
156
  </div>
157
  </div>
 
158
 
159
  </div>
160
 
 
 
161
  <script type="text/javascript">
162
  //<![CDATA[
163
 
164
  jQuery(function ($) {
165
  var $panel = $('#productivity-panel');
166
+ var $content = $('#productivity-panel-content'),
167
+ $qr_select = $('#productivity-qr-select');
168
 
169
  var menu_height = $('#productivity-panel-menu').height();
170
 
206
  return false;
207
  });
208
 
209
+ $('#productivity-qr-button').on('click', function () {
210
+ window.open(
211
+ '<?php echo Mage::getUrl('mventory/qr/generate'); ?>' + $qr_select.val()
212
+ );
213
+ })
214
+
215
  $('#productivity_edit_form_cancel').on('click', function () {
216
  $panel.removeClass('productivity-task-edit-form-on');
217
 
225
  </script>
226
 
227
  <?php endif; ?>
 
 
app/etc/modules/MVentory_Productivity.xml CHANGED
@@ -20,6 +20,9 @@
20
  <MVentory_Productivity>
21
  <active>true</active>
22
  <codePool>community</codePool>
 
 
 
23
  </MVentory_Productivity>
24
 
25
  <Mage_Review>
20
  <MVentory_Productivity>
21
  <active>true</active>
22
  <codePool>community</codePool>
23
+ <depends>
24
+ <MVentory_API />
25
+ </depends>
26
  </MVentory_Productivity>
27
 
28
  <Mage_Review>
package.xml CHANGED
@@ -1,58 +1,47 @@
1
  <?xml version="1.0"?>
2
- <package>
3
- <name>mVentory_Productivity</name>
4
- <version>1.1.0</version>
5
- <stability>stable</stability>
6
- <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License version 3.0</license>
7
- <channel>community</channel>
8
- <extends/>
9
- <summary>Edit products details, upload and manage photos via front end or use shortcuts directly to admin pages.</summary>
10
- <description>A front-end toolbar for admins and nominated customers to perform site management via the front end:&#xD;
11
- &#xD;
12
- The extension provides simple admin functionality to a group of site admins or power users without them accessing the admin interface as often or not at all.&#xD;
13
- &#xD;
14
- The shortcuts allow quick navigation between front-end and admin interfaces. E.g. if you are looking at a product details page and need to make changes to it via the admin you can jump there in one click instead of searching for the product in the admin.&#xD;
15
- The same applies to category and CMS pages.&#xD;
16
- &#xD;
17
- * Edit product details, price, attributes, etc.&#xD;
18
- * Upload product images&#xD;
19
- * Set main product image&#xD;
20
- * Delete, rotate product images&#xD;
21
- * Shortcuts to the admin interface for the page&#xD;
22
- * Easily find products with missing images&#xD;
23
- * Shortcut to Google Analytics&#xD;
24
- &#xD;
25
- Theme compatibility&#xD;
26
- &#xD;
27
- Most well designed themes are compatible with the extension. You may need to make a few minor changes. See documentation on GitHub.&#xD;
28
- &#xD;
29
- Enable / Disable the Toolbar&#xD;
30
- &#xD;
31
- 1. Log in to the admin interface.&#xD;
32
- 2. Come back to the front end.&#xD;
33
- 3. You should see the toolbar at the top.&#xD;
34
- &#xD;
35
- Customers assigned to customer group called "Reviewers" can see most of the functions. They need to log in as customers via the front end.&#xD;
36
- &#xD;
37
- Source code and documentation&#xD;
38
- &#xD;
39
- https://github.com/mVentory/MVentory_Productivity&#xD;
40
- &#xD;
41
- Support&#xD;
42
- &#xD;
43
- Bug reports are welcome at support@zetaprints.com&#xD;
44
- &#xD;
45
- License&#xD;
46
- &#xD;
47
- The extension is free open source released under OSL 3 license. Please, contribute your code if you make useful changes.</description>
48
- <notes>* Better compatibility with mVentory API extension&#xD;
49
- * Allow user to set scope for product save&#xD;
50
- * Move settings into single tab&#xD;
51
- * Workaround for bug in Magento code</notes>
52
- <authors><author><name>Anatoly A. Kazantsev</name><user>anatoly</user><email>anatoly@mventory.com</email></author></authors>
53
- <date>2014-06-26</date>
54
- <time>03:25:01</time>
55
- <contents><target name="mageetc"><dir name="modules"><file name="MVentory_Productivity.xml" hash="b400b5f5c913237459121c5f34988959"/></dir></target><target name="magecommunity"><dir name="MVentory"><dir name="Productivity"><dir name="Block"><dir name="Adminhtml"><dir name="Catalog"><dir name="Category"><dir name="Edit"><file name="Button.php" hash="373fde50d4cb8b2baf3cb0a0fe10fa34"/></dir></dir><dir name="Product"><dir name="Attribute"><dir name="Set"><dir name="Edit"><file name="Script.php" hash="082af8108d6e4e04a4919577873e8a4b"/></dir></dir></dir><dir name="Edit"><file name="Button.php" hash="b468bcf3eb55742ee50ea88cee50eda8"/></dir></dir></dir><dir name="Cms"><dir name="Page"><dir name="Edit"><file name="Button.php" hash="aa52a3a5c37605b062a167871c7d0040"/></dir></dir></dir></dir><dir name="Catalog"><dir name="Product"><dir name="Attribute"><dir name="Edit"><dir name="Tab"><file name="Options.php" hash="b29713fe74e58b53dec333fb351f1dd8"/></dir></dir></dir></dir></dir><dir name="Config"><file name="Hint.php" hash="390dff64cac0eb392be19046810a60f1"/></dir><dir name="Image"><file name="Edit.php" hash="859a79c62b6ce085d770d01ca9140a6d"/></dir><dir name="Mage"><dir name="Page"><dir name="Html"><file name="Breadcrumbs.php" hash="3380b86a7fb6e427f2d2776cfff7b3d6"/></dir></dir></dir><file name="Panel.php" hash="67430164c70ef939165d8e5e755a5bd4"/><dir name="Product"><file name="Latest.php" hash="f139481ebac4b96354062afc7999188f"/><file name="Random.php" hash="ddb01f3903cdf72d1fb1b356b7e683f2"/><file name="Related.php" hash="9cc932519b8e303b8a08a88761a13ad0"/><file name="View.php" hash="94f99f7b2fa9bbf710bd10d1a3328ad7"/></dir><dir name="Rss"><file name="Import.php" hash="f8795dabbd7a0eac41969655313a2ea0"/><dir name="Product"><file name="Latest.php" hash="ace95b91bea601e481b5efa1f2cf3faa"/></dir></dir><file name="Slideshow.php" hash="135ea70800c6de483be020cbbf03fb42"/><dir name="Widget"><file name="Attribute.php" hash="729262fdc7af8cc0922d09528ac56cf9"/><file name="Latest.php" hash="ee48ecbf4dd02fff2f1449e5f30454eb"/></dir></dir><file name="Exception.php" hash="14c5537ef3ab7013c789b36683098ee9"/><dir name="Helper"><file name="Data.php" hash="29f0cecca1eff276c6342693453f7cd9"/><dir name="Mage"><dir name="Catalog"><file name="Category.php" hash="80ce1244afa3fcbce92e46c1b48a6794"/></dir></dir><file name="Rss.php" hash="9e15b418c3e36c5e65e9a4d3955c965f"/></dir><dir name="Model"><file name="Config.php" hash="d6468c75cb1260dea583d067b6015e42"/><dir name="Mage"><dir name="Catalog"><file name="Category.php" hash="e75b8a8e23d7c9659eb6fd53a6a0f530"/></dir></dir><file name="Observer.php" hash="8e30a2d92db5a99ac3fd2ddb8ccb5eea"/><dir name="Setting"><dir name="Source"><file name="Savescope.php" hash="157a051c1d897cccf5c7752613c2d433"/></dir></dir><dir name="Widget"><file name="Attribute.php" hash="f22ee6f057193a66fa94c0c61569436f"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="IndexController.php" hash="59b1e39d51d8149db9559c396c02b744"/></dir><file name="CategoryController.php" hash="96abc201272ebc19d25e5ea9f4469d8b"/><file name="FeedController.php" hash="67306629ab968a4a9420d01d331847b8"/><file name="ImageController.php" hash="0eac4482eab007a0d8ed30f99b6cf4c8"/><file name="ProductController.php" hash="142a82577d9e5556cccf9c1b8cdcc068"/><dir name="Rss"><file name="ProductController.php" hash="777ab9eaa50ff3179b45bdcca8140e39"/></dir></dir><dir name="etc"><file name="config.xml" hash="52d2576c4633d933dfeab52344e0d7b9"/><file name="jstranslator.xml" hash="b6553078458f63a4d4a68193bf75ffea"/><file name="system.xml" hash="7ef03f418b7fde17b014f8381553d77d"/><file name="widget.xml" hash="0e8e731f5b1db6c7273bc57ba2203cd1"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="productivity.xml" hash="00f0fa3327007a24ff60a5cfc724524b"/></dir><dir name="template"><dir name="productivity"><dir name="catalog"><dir name="category"><dir name="edit"><file name="button.phtml" hash="843be360ed96ceb9231d35851f965928"/></dir></dir><dir name="product"><dir name="attribute"><file name="options.phtml" hash="30c3519bfded836babbc09d158a109fd"/><dir name="set"><dir name="edit"><file name="script.js.phtml" hash="d6d948e7689f209e9b2ce3cd951701d6"/></dir></dir></dir><dir name="edit"><file name="button.phtml" hash="77383909622e733ae65e604448d73260"/></dir></dir></dir><dir name="cms"><dir name="page"><dir name="edit"><file name="button.phtml" hash="2020e28aa1f61fe8ad458625a2a7e562"/></dir></dir></dir><dir name="config"><file name="hint.phtml" hash="835d4fa6470429eec0643f0822240a49"/></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="productivity.xml" hash="5cd13638e961f15995833041f2f97f81"/></dir><dir name="template"><dir name="productivity"><dir name="catalog"><dir name="product"><file name="latest.phtml" hash="f17d98c023d1619b7d8fae616853d772"/></dir></dir><dir name="image"><file name="edit.phtml" hash="866d085cf7f564eca6f75b00a83ad8e9"/></dir><dir name="panel"><dir name="uploader"><file name="js.phtml" hash="1cf70f10f7b1a4d3d0f551a358e2fad0"/></dir></dir><file name="panel.phtml" hash="50690ba5acbe0c86810fed29ff70be1a"/><dir name="rss"><file name="import.phtml" hash="aed85a2741c9aeb394a44d7e010e1d78"/></dir></dir></dir></dir></dir></dir></target><target name="mageweb"><dir name="js"><dir name="jquery"><file name="jquery-fineuploader-min.js" hash="452dd95488a3f7a345187b779d70f987"/></dir><dir name="productivity"><dir name="adminhtml"><file name="update_grid.js" hash="241898d8bba1b0ad536a24d66aa7c57e"/></dir><dir name="image"><file name="edit.js" hash="09423c39f6c217b3a687cd930198d3b7"/></dir></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><file name="productivity.css" hash="f048b3e17dcb29463d7d632e22b04852"/></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="productivity"><dir name="css"><file name="styles.css" hash="16056a87b3fa6133932343c44204086b"/></dir><dir name="images"><file name="icon-attention.png" hash="0e954041eca8913ec6137ecb93634147"/><file name="icon-edit.png" hash="d7f2a1693b5896d6902629299351dc1b"/><file name="main-image-icon.png" hash="d2040c34ba1ffd8fa5b72ab37be11eca"/><file name="remove-icon.png" hash="757aa607cbcd1616ced5a336e56b0e6c"/><file name="rotate-left-icon.png" hash="6c35dd8068d99911e997ef493ae0d5e8"/><file name="rotate-right-icon.png" hash="70a8e355befd6b1bc7759429ecc18ef7"/><dir name="uploader"><file name="add.png" hash="10fca3834d6218d74c7c42697921e9cc"/><file name="cancel.png" hash="bd8732813a429c4f82580bc0286aed6f"/><file name="loading.gif" hash="0d2f777150e56c31a224755821511d94"/></dir></dir></dir></dir></dir></dir></target></contents>
56
- <compatible/>
57
- <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>MVentory_JQuery</name><channel>community</channel><min/><max/></package></required></dependencies>
58
- </package>
1
  <?xml version="1.0"?>
2
+ <package><name>mVentory_Productivity</name><version>1.1.1</version><stability>stable</stability><license>Open Software License version 3.0</license><channel>community</channel><extends></extends><summary>Edit products details, upload and manage photos via front end or use shortcuts directly to admin pages.</summary><description>A front-end toolbar for admins and nominated customers to perform site management via the front end:
3
+
4
+ The extension provides simple admin functionality to a group of site admins or power users without them accessing the admin interface as often or not at all.
5
+
6
+ The shortcuts allow quick navigation between front-end and admin interfaces. E.g. if you are looking at a product details page and need to make changes to it via the admin you can jump there in one click instead of searching for the product in the admin.
7
+
8
+ The same applies to category and CMS pages.
9
+
10
+ * Edit product details, price, attributes, etc.
11
+ * Upload product images
12
+ * Set main product image
13
+ * Delete, rotate product images
14
+ * Shortcuts to the admin interface for the page
15
+ * Easily find products with missing images
16
+ * Shortcut to Google Analytics
17
+
18
+ Theme compatibility
19
+
20
+ Most well designed themes are compatible with the extension. You may need to make a few minor changes. See documentation on GitHub.
21
+
22
+ Enable / Disable the Toolbar
23
+
24
+ 1. Log in to the admin interface.
25
+
26
+ 2. Come back to the front end.
27
+
28
+ 3. You should see the toolbar at the top.
29
+
30
+
31
+ Customers assigned to customer group called &amp;quot;Reviewers&amp;quot; can see most of the functions. They need to log in as customers via the front end.
32
+
33
+ Source code and documentation
34
+
35
+ https://github.com/mVentory/MVentory_Productivity
36
+
37
+ Support
38
+
39
+ Bug reports are welcome at support@zetaprints.com
40
+
41
+ License
42
+
43
+ The extension is free open source released under OSL 3 license. Please, contribute your code if you make useful changes.</description><notes>* Add setting to limit the list of fields available for editing via the frontend
44
+ * Add support for editing of configurable products
45
+ * Add tabs for quick generating of QR labels (works only when MVentory_API extesion is installed)
46
+ * Extend filtering by all image types (i.e. base image, small image and thumbnail) in the list of products with missing images
47
+ * Allow to expand categories with &amp;apos;Include in Navigation Menu&amp;apos; set to No</notes><authors><author><name>Anatoly A. Kazantsev</name><user>anatoly</user><email>anatoly@mventory.com</email></author></authors><date>2015-02-01</date><time>0:22:13</time><compatible></compatible><dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies><depends><package><name><name>MVentory_API</name></name><channel><channel>community</channel></channel><min><min></min></min><max><max></max></max></package></depends><contents><target name="mage"><dir name="js"><dir name="productivity"><dir name="adminhtml"><file name="update_grid.js" hash="241898d8bba1b0ad536a24d66aa7c57e"/></dir><dir name="image"><file name="edit.js" hash="09423c39f6c217b3a687cd930198d3b7"/></dir></dir><dir name="jquery"><file name="jquery-fineuploader-min.js" hash="452dd95488a3f7a345187b779d70f987"/></dir></dir><dir name="var"><dir name="connect"><file name="mVentory_Productivity.xml" hash="9d9c0e29a412fc95067c165822c08227"/></dir></dir><dir name="app"><dir name="design"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="productivity.xml" hash="59f66b6fad9b8806a10d1599cf5da725"/></dir><dir name="template"><dir name="productivity"><file name="panel.phtml" hash="70c7ca41a3f28d1ad13af5c00a3e1d6a"/><dir name="rss"><file name="import.phtml" hash="aed85a2741c9aeb394a44d7e010e1d78"/></dir><dir name="panel"><dir name="uploader"><file name="js.phtml" hash="1cf70f10f7b1a4d3d0f551a358e2fad0"/></dir></dir><dir name="catalog"><dir name="product"><file name="latest.phtml" hash="f17d98c023d1619b7d8fae616853d772"/></dir></dir><dir name="image"><file name="edit.phtml" hash="866d085cf7f564eca6f75b00a83ad8e9"/></dir></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="productivity.xml" hash="00f0fa3327007a24ff60a5cfc724524b"/></dir><dir name="template"><dir name="productivity"><dir name="catalog"><dir name="category"><dir name="edit"><file name="button.phtml" hash="843be360ed96ceb9231d35851f965928"/></dir></dir><dir name="product"><dir name="edit"><file name="button.phtml" hash="77383909622e733ae65e604448d73260"/></dir><dir name="attribute"><file name="options.phtml" hash="30c3519bfded836babbc09d158a109fd"/><dir name="set"><dir name="edit"><file name="script.js.phtml" hash="d6d948e7689f209e9b2ce3cd951701d6"/></dir></dir></dir></dir></dir><dir name="cms"><dir name="page"><dir name="edit"><file name="button.phtml" hash="2020e28aa1f61fe8ad458625a2a7e562"/></dir></dir></dir><dir name="config"><file name="build-info.phtml" hash="1ad31601f1dd38b4f0c51ace2094c701"/><file name="hint.phtml" hash="835d4fa6470429eec0643f0822240a49"/></dir></dir></dir></dir></dir></dir></dir><dir name="code"><dir name="community"><dir name="MVentory"><dir name="Productivity"><file name="Exception.php" hash="14c5537ef3ab7013c789b36683098ee9"/><dir name="controllers"><file name="CategoryController.php" hash="96abc201272ebc19d25e5ea9f4469d8b"/><file name="FeedController.php" hash="67306629ab968a4a9420d01d331847b8"/><file name="ImageController.php" hash="0eac4482eab007a0d8ed30f99b6cf4c8"/><file name="ProductController.php" hash="7cead3c67b22f30ff9c609828a3c7429"/><dir name="Rss"><file name="ProductController.php" hash="777ab9eaa50ff3179b45bdcca8140e39"/></dir><dir name="Adminhtml"><file name="IndexController.php" hash="59b1e39d51d8149db9559c396c02b744"/></dir></dir><dir name="Block"><file name="Panel.php" hash="b9e032da8ab531cb5d9da9d4e4a82fbd"/><file name="Slideshow.php" hash="135ea70800c6de483be020cbbf03fb42"/><dir name="Catalog"><dir name="Product"><dir name="Attribute"><dir name="Edit"><dir name="Tab"><file name="Options.php" hash="b29713fe74e58b53dec333fb351f1dd8"/></dir></dir></dir></dir></dir><dir name="Mage"><dir name="Page"><dir name="Html"><file name="Breadcrumbs.php" hash="3380b86a7fb6e427f2d2776cfff7b3d6"/></dir></dir></dir><dir name="Rss"><file name="Import.php" hash="f8795dabbd7a0eac41969655313a2ea0"/><dir name="Product"><file name="Latest.php" hash="ace95b91bea601e481b5efa1f2cf3faa"/></dir></dir><dir name="Adminhtml"><dir name="Catalog"><dir name="Category"><dir name="Edit"><file name="Button.php" hash="373fde50d4cb8b2baf3cb0a0fe10fa34"/></dir></dir><dir name="Product"><dir name="Attribute"><dir name="Set"><dir name="Edit"><file name="Script.php" hash="082af8108d6e4e04a4919577873e8a4b"/></dir></dir></dir><dir name="Edit"><file name="Button.php" hash="b468bcf3eb55742ee50ea88cee50eda8"/></dir></dir></dir><dir name="Cms"><dir name="Page"><dir name="Edit"><file name="Button.php" hash="aa52a3a5c37605b062a167871c7d0040"/></dir></dir></dir></dir><dir name="Config"><file name="Buildinfo.php" hash="6e7a72fdf44afbc85de075cdab95c199"/><file name="Hint.php" hash="390dff64cac0eb392be19046810a60f1"/></dir><dir name="Image"><file name="Edit.php" hash="859a79c62b6ce085d770d01ca9140a6d"/></dir><dir name="Product"><file name="Latest.php" hash="f139481ebac4b96354062afc7999188f"/><file name="Random.php" hash="ddb01f3903cdf72d1fb1b356b7e683f2"/><file name="Related.php" hash="9cc932519b8e303b8a08a88761a13ad0"/><file name="View.php" hash="94f99f7b2fa9bbf710bd10d1a3328ad7"/></dir><dir name="Widget"><file name="Attribute.php" hash="729262fdc7af8cc0922d09528ac56cf9"/><file name="Latest.php" hash="ee48ecbf4dd02fff2f1449e5f30454eb"/></dir></dir><dir name="Helper"><file name="Attribute.php" hash="0a2497a6d8a104e85edd4811593c8983"/><file name="Data.php" hash="ecbfb7b0c7257953bfb5d35ad8c5e1c3"/><file name="Rss.php" hash="9e15b418c3e36c5e65e9a4d3955c965f"/><dir name="Mage"><dir name="Catalog"><file name="Category.php" hash="80ce1244afa3fcbce92e46c1b48a6794"/></dir></dir></dir><dir name="Model"><file name="Config.php" hash="d21fd1545932616d3331494ee1531a44"/><file name="Observer.php" hash="308a3a6fce1e15ef16ffe1a4c98b5a23"/><dir name="Mage"><dir name="Catalog"><file name="Category.php" hash="ce819194d82e5df6cd67739159d9ca1f"/></dir></dir><dir name="Setting"><dir name="Source"><file name="Copyattrs.php" hash="8c3b90ea32bb95f4678d459eaa8c0851"/><file name="Flattentype.php" hash="99455b6a6742ec1d0498b1fbbb8eedd4"/><file name="Savescope.php" hash="157a051c1d897cccf5c7752613c2d433"/></dir></dir><dir name="Resource"><dir name="Category"><file name="Tree.php" hash="c6e602dc592bb45365f94495bfa8f1c9"/></dir></dir><dir name="Widget"><file name="Attribute.php" hash="f22ee6f057193a66fa94c0c61569436f"/></dir></dir><dir name="etc"><file name="config.xml" hash="d2a99bfd3e9c05549aa564a17ab4a449"/><file name="jstranslator.xml" hash="b6553078458f63a4d4a68193bf75ffea"/><file name="system.xml" hash="8ac529eb001d76d78dbbeeb091b27b29"/><file name="widget.xml" hash="0e8e731f5b1db6c7273bc57ba2203cd1"/></dir></dir></dir></dir></dir><dir name="etc"><dir name="modules"><file name="MVentory_Productivity.xml" hash="42732284cd7820050c22067a01c4d714"/></dir></dir></dir><dir name="skin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="productivity"><dir name="images"><file name="icon-attention.png" hash="0e954041eca8913ec6137ecb93634147"/><file name="icon-edit.png" hash="d7f2a1693b5896d6902629299351dc1b"/><file name="main-image-icon.png" hash="d2040c34ba1ffd8fa5b72ab37be11eca"/><file name="remove-icon.png" hash="757aa607cbcd1616ced5a336e56b0e6c"/><file name="rotate-left-icon.png" hash="6c35dd8068d99911e997ef493ae0d5e8"/><file name="rotate-right-icon.png" hash="70a8e355befd6b1bc7759429ecc18ef7"/><dir name="uploader"><file name="add.png" hash="10fca3834d6218d74c7c42697921e9cc"/><file name="cancel.png" hash="bd8732813a429c4f82580bc0286aed6f"/><file name="loading.gif" hash="0d2f777150e56c31a224755821511d94"/></dir></dir><dir name="css"><file name="styles.css" hash="3fe3ba3193a12a41c8eb1f56cfa58a7f"/></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><file name="productivity.css" hash="ab96369628956da3e1e6198186ae7072"/></dir></dir></dir></dir></target></contents></package>
 
 
 
 
 
 
 
 
 
 
 
skin/adminhtml/default/default/productivity.css CHANGED
@@ -15,3 +15,4 @@
15
  button.frontshop { opacity:.8; border-color:#777 #505050 #505050 #777; background:#919191 url(images/btn_bg-disabled.gif) 0 0 repeat-x }
16
 
17
  .productivity-config-hint { font-weight:bold; margin:0 0 10px }
 
15
  button.frontshop { opacity:.8; border-color:#777 #505050 #505050 #777; background:#919191 url(images/btn_bg-disabled.gif) 0 0 repeat-x }
16
 
17
  .productivity-config-hint { font-weight:bold; margin:0 0 10px }
18
+ .productivity-tooltip-list { list-style: disc inside }
skin/frontend/base/default/productivity/css/styles.css CHANGED
@@ -96,17 +96,20 @@
96
  text-decoration: none;
97
  }
98
 
 
99
  .productivity-task-upload-on #productivity-task-upload,
100
  .productivity-task-edit-form-on #productivity-task-edit-form {
101
  background: #fff;
102
  color: #333333;
103
  }
104
 
 
105
  .productivity-task-upload-on #productivity-panel-content,
106
  .productivity-task-edit-form-on #productivity-panel-content {
107
  height: auto;
108
  }
109
 
 
110
  .productivity-task-upload-on #productivity-uploader,
111
  .productivity-task-edit-form-on #productivity-edit-attributes {
112
  display: block;
@@ -245,10 +248,15 @@
245
  margin-left: -16px;
246
  }
247
 
 
248
  #productivity-uploader {
249
  display: none;
250
  }
251
 
 
 
 
 
252
  #productivity-uploader-notice {
253
  display: none;
254
  }
96
  text-decoration: none;
97
  }
98
 
99
+ .productivity-task-qr-on #productivity-task-qr,
100
  .productivity-task-upload-on #productivity-task-upload,
101
  .productivity-task-edit-form-on #productivity-task-edit-form {
102
  background: #fff;
103
  color: #333333;
104
  }
105
 
106
+ .productivity-task-qr-on #productivity-panel-content,
107
  .productivity-task-upload-on #productivity-panel-content,
108
  .productivity-task-edit-form-on #productivity-panel-content {
109
  height: auto;
110
  }
111
 
112
+ .productivity-task-qr-on #productivity-qr,
113
  .productivity-task-upload-on #productivity-uploader,
114
  .productivity-task-edit-form-on #productivity-edit-attributes {
115
  display: block;
248
  margin-left: -16px;
249
  }
250
 
251
+ #productivity-qr,
252
  #productivity-uploader {
253
  display: none;
254
  }
255
 
256
+ #productivity-qr {
257
+ margin: 0 0 10px;
258
+ }
259
+
260
  #productivity-uploader-notice {
261
  display: none;
262
  }
var/connect/mVentory_Productivity.xml ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <_>
2
+ <form_key>0wE1H58x24D0PCDr</form_key>
3
+ <name>mVentory_Productivity</name>
4
+ <channel>community</channel>
5
+ <version_ids>
6
+ <version_ids>2</version_ids>
7
+ </version_ids>
8
+ <summary>Edit products details, upload and manage photos via front end or use shortcuts directly to admin pages.</summary>
9
+ <description>A front-end toolbar for admins and nominated customers to perform site management via the front end:
10
+
11
+ The extension provides simple admin functionality to a group of site admins or power users without them accessing the admin interface as often or not at all.
12
+
13
+ The shortcuts allow quick navigation between front-end and admin interfaces. E.g. if you are looking at a product details page and need to make changes to it via the admin you can jump there in one click instead of searching for the product in the admin.
14
+ The same applies to category and CMS pages.
15
+
16
+ * Edit product details, price, attributes, etc.
17
+ * Upload product images
18
+ * Set main product image
19
+ * Delete, rotate product images
20
+ * Shortcuts to the admin interface for the page
21
+ * Easily find products with missing images
22
+ * Shortcut to Google Analytics
23
+
24
+ Theme compatibility
25
+
26
+ Most well designed themes are compatible with the extension. You may need to make a few minor changes. See documentation on GitHub.
27
+
28
+ Enable / Disable the Toolbar
29
+
30
+ 1. Log in to the admin interface.
31
+ 2. Come back to the front end.
32
+ 3. You should see the toolbar at the top.
33
+
34
+ Customers assigned to customer group called &quot;Reviewers&quot; can see most of the functions. They need to log in as customers via the front end.
35
+
36
+ Source code and documentation
37
+
38
+ https://github.com/mVentory/MVentory_Productivity
39
+
40
+ Support
41
+
42
+ Bug reports are welcome at support@zetaprints.com
43
+
44
+ License
45
+
46
+ The extension is free open source released under OSL 3 license. Please, contribute your code if you make useful changes.</description>
47
+ <license>Open Software License version 3.0</license>
48
+ <license_uri>http://opensource.org/licenses/osl-3.0.php</license_uri>
49
+ <version>1.1.0</version>
50
+ <stability>devel</stability>
51
+ <notes>* Add setting to limit the list of fields available for editing via the frontend
52
+ * Add support for editing of configurable products
53
+ * Add tabs for quick generating of QR labels (works only when MVentory_API extesion is installed)
54
+ * Extend filtering by all image types (i.e. base image, small image and thumbnail) in the list of products with missing images
55
+ * Allow to expand categories with &apos;Include in Navigation Menu&apos; set to No</notes>
56
+ <authors>
57
+ <name>
58
+ <name>Anatoly A. Kazantsev</name>
59
+ </name>
60
+ <user>
61
+ <user>anatoly</user>
62
+ </user>
63
+ <email>
64
+ <email>anatoly@mventory.com</email>
65
+ </email>
66
+ </authors>
67
+ <depends_php_min>5.2.0</depends_php_min>
68
+ <depends_php_max>6.0.0</depends_php_max>
69
+ <depends>
70
+ <package>
71
+ <name>
72
+ <name/>
73
+ <name>MVentory_API</name>
74
+ </name>
75
+ <channel>
76
+ <channel/>
77
+ <channel>community</channel>
78
+ </channel>
79
+ <min>
80
+ <min/>
81
+ <min/>
82
+ </min>
83
+ <max>
84
+ <max/>
85
+ <max/>
86
+ </max>
87
+ <files>
88
+ <files> </files>
89
+ <files> </files>
90
+ </files>
91
+ </package>
92
+ <extension>
93
+ <name>
94
+ <name>Core</name>
95
+ </name>
96
+ <min>
97
+ <min/>
98
+ </min>
99
+ <max>
100
+ <max/>
101
+ </max>
102
+ </extension>
103
+ </depends>
104
+ <contents>
105
+ <target>
106
+ <target>magelocal</target>
107
+ <target>mageetc</target>
108
+ <target>magecommunity</target>
109
+ <target>magedesign</target>
110
+ <target>magedesign</target>
111
+ <target>magedesign</target>
112
+ <target>magedesign</target>
113
+ <target>mageweb</target>
114
+ <target>mageweb</target>
115
+ <target>mageskin</target>
116
+ <target>mageskin</target>
117
+ </target>
118
+ <path>
119
+ <path/>
120
+ <path>modules/MVentory_Productivity.xml</path>
121
+ <path>MVentory/Productivity</path>
122
+ <path>adminhtml/default/default/layout/productivity.xml</path>
123
+ <path>adminhtml/default/default/template/productivity</path>
124
+ <path>frontend/base/default/layout/productivity.xml</path>
125
+ <path>frontend/base/default/template/productivity</path>
126
+ <path>js/jquery/jquery-fineuploader-min.js</path>
127
+ <path>js/productivity</path>
128
+ <path>adminhtml/default/default/productivity.css</path>
129
+ <path>frontend/base/default/productivity</path>
130
+ </path>
131
+ <type>
132
+ <type>file</type>
133
+ <type>file</type>
134
+ <type>dir</type>
135
+ <type>file</type>
136
+ <type>dir</type>
137
+ <type>file</type>
138
+ <type>dir</type>
139
+ <type>file</type>
140
+ <type>dir</type>
141
+ <type>file</type>
142
+ <type>dir</type>
143
+ </type>
144
+ <include>
145
+ <include/>
146
+ <include/>
147
+ <include/>
148
+ <include/>
149
+ <include/>
150
+ <include/>
151
+ <include/>
152
+ <include/>
153
+ <include/>
154
+ <include/>
155
+ <include/>
156
+ </include>
157
+ <ignore>
158
+ <ignore/>
159
+ <ignore/>
160
+ <ignore/>
161
+ <ignore/>
162
+ <ignore/>
163
+ <ignore/>
164
+ <ignore/>
165
+ <ignore/>
166
+ <ignore/>
167
+ <ignore/>
168
+ <ignore/>
169
+ </ignore>
170
+ </contents>
171
+ </_>