Version Notes
Initial release
Download this release
Release Info
Developer | Anatoly A. Kazantsev |
Extension | mVentory_Productivity |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- app/code/community/MVentory/Productivity/Block/Adminhtml/Catalog/Category/Edit/Button.php +36 -0
- app/code/community/MVentory/Productivity/Block/Adminhtml/Catalog/Product/Attribute/Set/Edit/Script.php +35 -0
- app/code/community/MVentory/Productivity/Block/Adminhtml/Catalog/Product/Edit/Button.php +31 -0
- app/code/community/MVentory/Productivity/Block/Adminhtml/Cms/Page/Edit/Button.php +31 -0
- app/code/community/MVentory/Productivity/Block/Catalog/Product/Attribute/Edit/Tab/Options.php +30 -0
- app/code/community/MVentory/Productivity/Block/Image/Edit.php +43 -0
- app/code/community/MVentory/Productivity/Block/Mage/Page/Html/Breadcrumbs.php +66 -0
- app/code/community/MVentory/Productivity/Block/Panel.php +175 -0
- app/code/community/MVentory/Productivity/Block/Product/Latest.php +112 -0
- app/code/community/MVentory/Productivity/Block/Product/Random.php +116 -0
- app/code/community/MVentory/Productivity/Block/Product/Related.php +86 -0
- app/code/community/MVentory/Productivity/Block/Product/View.php +36 -0
- app/code/community/MVentory/Productivity/Block/Rss/Import.php +110 -0
- app/code/community/MVentory/Productivity/Block/Rss/Product/Latest.php +67 -0
- app/code/community/MVentory/Productivity/Block/Slideshow.php +170 -0
- app/code/community/MVentory/Productivity/Block/Widget/Attribute.php +83 -0
- app/code/community/MVentory/Productivity/Block/Widget/Latest.php +64 -0
- app/code/community/MVentory/Productivity/Exception.php +24 -0
- app/code/community/MVentory/Productivity/Helper/Data.php +248 -0
- app/code/community/MVentory/Productivity/Helper/Mage/Catalog/Category.php +52 -0
- app/code/community/MVentory/Productivity/Helper/Rss.php +236 -0
- app/code/community/MVentory/Productivity/Model/Mage/Catalog/Category.php +110 -0
- app/code/community/MVentory/Productivity/Model/Observer.php +184 -0
- app/code/community/MVentory/Productivity/Model/Widget/Attribute.php +163 -0
- app/code/community/MVentory/Productivity/controllers/Adminhtml/IndexController.php +38 -0
- app/code/community/MVentory/Productivity/controllers/CategoryController.php +228 -0
- app/code/community/MVentory/Productivity/controllers/FeedController.php +38 -0
- app/code/community/MVentory/Productivity/controllers/ImageController.php +283 -0
- app/code/community/MVentory/Productivity/controllers/ProductController.php +85 -0
- app/code/community/MVentory/Productivity/controllers/Rss/ProductController.php +33 -0
- app/code/community/MVentory/Productivity/etc/config.xml +195 -0
- app/code/community/MVentory/Productivity/etc/jstranslator.xml +6 -0
- app/code/community/MVentory/Productivity/etc/system.xml +88 -0
- app/code/community/MVentory/Productivity/etc/widget.xml +101 -0
- app/design/adminhtml/default/default/layout/productivity.xml +59 -0
- app/design/adminhtml/default/default/template/productivity/catalog/category/edit/button.phtml +43 -0
- app/design/adminhtml/default/default/template/productivity/catalog/product/attribute/options.phtml +219 -0
- app/design/adminhtml/default/default/template/productivity/catalog/product/attribute/set/edit/script.js.phtml +36 -0
- app/design/adminhtml/default/default/template/productivity/catalog/product/edit/button.phtml +18 -0
- app/design/adminhtml/default/default/template/productivity/cms/page/edit/button.phtml +18 -0
- app/design/frontend/base/default/layout/productivity.xml +96 -0
- app/design/frontend/base/default/template/productivity/catalog/product/latest.phtml +97 -0
- app/design/frontend/base/default/template/productivity/image/edit.phtml +72 -0
- app/design/frontend/base/default/template/productivity/panel.phtml +197 -0
- app/design/frontend/base/default/template/productivity/panel/uploader/js.phtml +144 -0
- app/design/frontend/base/default/template/productivity/rss/import.phtml +32 -0
- app/etc/modules/MVentory_Productivity.xml +25 -0
- js/jquery/jquery-fineuploader-min.js +19 -0
- js/productivity/adminhtml/update_grid.js +31 -0
- js/productivity/image/edit.js +542 -0
- package.xml +55 -0
- skin/adminhtml/default/default/productivity.css +22 -0
- skin/frontend/base/default/productivity/css/styles.css +436 -0
- skin/frontend/base/default/productivity/images/icon-attention.png +0 -0
- skin/frontend/base/default/productivity/images/icon-edit.png +0 -0
- skin/frontend/base/default/productivity/images/main-image-icon.png +0 -0
- skin/frontend/base/default/productivity/images/remove-icon.png +0 -0
- skin/frontend/base/default/productivity/images/rotate-left-icon.png +0 -0
- skin/frontend/base/default/productivity/images/rotate-right-icon.png +0 -0
- skin/frontend/base/default/productivity/images/uploader/add.png +0 -0
- skin/frontend/base/default/productivity/images/uploader/cancel.png +0 -0
- skin/frontend/base/default/productivity/images/uploader/loading.gif +0 -0
app/code/community/MVentory/Productivity/Block/Adminhtml/Catalog/Category/Edit/Button.php
ADDED
@@ -0,0 +1,36 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for category Frontshop Preview button
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author <anemets1@gmail.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Adminhtml_Catalog_Category_Edit_Button extends Mage_Core_Block_Template
|
23 |
+
{
|
24 |
+
/**
|
25 |
+
* Get Category Id => Category Frontend Url jsoned array
|
26 |
+
*/
|
27 |
+
public function getJson()
|
28 |
+
{
|
29 |
+
$categories_urls = array();
|
30 |
+
$collection = Mage::getModel('catalog/category')->getCollection();
|
31 |
+
foreach($collection as $category) {
|
32 |
+
$categories_urls[$category->getId()] = $category->getUrl();
|
33 |
+
}
|
34 |
+
return Zend_Json::encode($categories_urls);
|
35 |
+
}
|
36 |
+
}
|
app/code/community/MVentory/Productivity/Block/Adminhtml/Catalog/Product/Attribute/Set/Edit/Script.php
ADDED
@@ -0,0 +1,35 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block Attribute Set edit template script
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author <anemets1@gmail.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Adminhtml_Catalog_Product_Attribute_Set_Edit_Script
|
23 |
+
extends Mage_Core_Block_Template {
|
24 |
+
|
25 |
+
public function getJson() {
|
26 |
+
$a = array();
|
27 |
+
$collection = Mage::getResourceModel('catalog/product_attribute_collection');
|
28 |
+
foreach($collection as $attribute) {
|
29 |
+
$a[$attribute->getData('attribute_code')] = $attribute->getData('attribute_id');;
|
30 |
+
}
|
31 |
+
|
32 |
+
return Zend_Json::encode($a);
|
33 |
+
}
|
34 |
+
|
35 |
+
}
|
app/code/community/MVentory/Productivity/Block/Adminhtml/Catalog/Product/Edit/Button.php
ADDED
@@ -0,0 +1,31 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for product Frontshop Preview button
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author <anemets1@gmail.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Adminhtml_Catalog_Product_Edit_Button extends Mage_Core_Block_Template
|
23 |
+
{
|
24 |
+
/**
|
25 |
+
* Get product frontend url
|
26 |
+
*/
|
27 |
+
public function getProductUrl()
|
28 |
+
{
|
29 |
+
return Mage::registry('product')->getProductUrl();
|
30 |
+
}
|
31 |
+
}
|
app/code/community/MVentory/Productivity/Block/Adminhtml/Cms/Page/Edit/Button.php
ADDED
@@ -0,0 +1,31 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for cms page Frontshop Preview button
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author <anemets1@gmail.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Adminhtml_Cms_Page_Edit_Button extends Mage_Core_Block_Template
|
23 |
+
{
|
24 |
+
/**
|
25 |
+
* Get cms page frontend url
|
26 |
+
*/
|
27 |
+
public function getPageUrl()
|
28 |
+
{
|
29 |
+
return Mage::getBaseUrl() . Mage::registry('cms_page')->getIdentifier();
|
30 |
+
}
|
31 |
+
}
|
app/code/community/MVentory/Productivity/Block/Catalog/Product/Attribute/Edit/Tab/Options.php
ADDED
@@ -0,0 +1,30 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Product attribute add/edit form options tab
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Catalog_Product_Attribute_Edit_Tab_Options
|
23 |
+
extends Mage_Adminhtml_Block_Catalog_Product_Attribute_Edit_Tab_Options {
|
24 |
+
|
25 |
+
public function __construct () {
|
26 |
+
parent::__construct();
|
27 |
+
|
28 |
+
$this->setTemplate('productivity/catalog/product/attribute/options.phtml');
|
29 |
+
}
|
30 |
+
}
|
app/code/community/MVentory/Productivity/Block/Image/Edit.php
ADDED
@@ -0,0 +1,43 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block image editing panel
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Image_Edit
|
23 |
+
extends Mage_Core_Block_Template {
|
24 |
+
|
25 |
+
public function setImageSize ($width = 0, $height = 0) {
|
26 |
+
$width = ($width = (int) $width) ? $width : null;
|
27 |
+
$height = ($height = (int) $height) ? $height : null;
|
28 |
+
|
29 |
+
return $this->setData('image_size', compact('width', 'height'));
|
30 |
+
}
|
31 |
+
|
32 |
+
public function setThumbSize ($width = 0, $height = 0) {
|
33 |
+
$width = ($width = (int) $width) ? $width : null;
|
34 |
+
$height = ($height = (int) $height) ? $height : null;
|
35 |
+
|
36 |
+
return $this->setData('thumb_size', compact('width', 'height'));
|
37 |
+
}
|
38 |
+
|
39 |
+
protected function _toHtml () {
|
40 |
+
if (Mage::helper('productivity')->isReviewerLogged())
|
41 |
+
return parent::_toHtml();
|
42 |
+
}
|
43 |
+
}
|
app/code/community/MVentory/Productivity/Block/Mage/Page/Html/Breadcrumbs.php
ADDED
@@ -0,0 +1,66 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Breadcrumbs block
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Mage_Page_Html_Breadcrumbs
|
23 |
+
extends Mage_Page_Block_Html_Breadcrumbs {
|
24 |
+
|
25 |
+
const PATH_HOME_URL = 'catalog/navigation/home_url';
|
26 |
+
|
27 |
+
/*
|
28 |
+
* Replaces link in 'home' crumb with external home URL if it's set
|
29 |
+
* and adds 'shop' crumb with link to Magento's home page
|
30 |
+
* after the 'home' crumb
|
31 |
+
*
|
32 |
+
* @return Mage_Core_Block_Abstract
|
33 |
+
*/
|
34 |
+
protected function _beforeToHtml () {
|
35 |
+
if (is_array($this->_crumbs)
|
36 |
+
&& isset($this->_crumbs['home'])
|
37 |
+
&& ($url = Mage::getStoreConfig(self::PATH_HOME_URL))) {
|
38 |
+
|
39 |
+
$shopUrl = $this->_crumbs['home']['link'];
|
40 |
+
|
41 |
+
$this->_crumbs['home']['link'] = $url;
|
42 |
+
$this->_crumbs['home']['first'] = null;
|
43 |
+
$this->_crumbs['home']['last'] = null;
|
44 |
+
|
45 |
+
$crumbs = array();
|
46 |
+
|
47 |
+
foreach ($this->_crumbs as $name => $crumb) {
|
48 |
+
$crumbs[$name] = $crumb;
|
49 |
+
|
50 |
+
if ($name == 'home')
|
51 |
+
$crumbs['shop'] = array(
|
52 |
+
'label' => $this->__('Products'),
|
53 |
+
'title' => null,
|
54 |
+
'link' => $shopUrl,
|
55 |
+
'first' => null,
|
56 |
+
'last' => null,
|
57 |
+
'readonly' => null
|
58 |
+
);
|
59 |
+
}
|
60 |
+
|
61 |
+
$this->_crumbs = $crumbs;
|
62 |
+
}
|
63 |
+
|
64 |
+
return parent::_beforeToHtml();
|
65 |
+
}
|
66 |
+
}
|
app/code/community/MVentory/Productivity/Block/Panel.php
ADDED
@@ -0,0 +1,175 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for productivity panel
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Panel
|
23 |
+
extends Mage_Core_Block_Template {
|
24 |
+
|
25 |
+
const CONFIG_ANALYTICS_URL = 'google/analytics/productivity_analytics_url';
|
26 |
+
|
27 |
+
protected function _getType () {
|
28 |
+
return $this->getRequest()->getControllerName();
|
29 |
+
}
|
30 |
+
|
31 |
+
protected function _getCurrentUrl () {
|
32 |
+
return $this->getUrl(
|
33 |
+
null,
|
34 |
+
array('_use_rewrite' => true, '_current' => true)
|
35 |
+
);
|
36 |
+
}
|
37 |
+
|
38 |
+
protected function _getProductLink () {
|
39 |
+
$params['id'] = Mage::registry('product')->getId();
|
40 |
+
|
41 |
+
return Mage::helper('adminhtml')
|
42 |
+
->getUrl('adminhtml/catalog_product/edit/', $params);
|
43 |
+
}
|
44 |
+
|
45 |
+
protected function _getCmsPageLink () {
|
46 |
+
$page = $this->getHelper('cms/page')->getPage();
|
47 |
+
|
48 |
+
if (!$pageId = $page->getPageId())
|
49 |
+
return false;
|
50 |
+
|
51 |
+
$params['page_id'] = $pageId;
|
52 |
+
|
53 |
+
return Mage::helper('adminhtml')
|
54 |
+
->getUrl('productivity_admin/adminhtml_index/index/', $params);
|
55 |
+
}
|
56 |
+
|
57 |
+
protected function _getCategoryLink () {
|
58 |
+
if (!$category = Mage::registry('current_category'))
|
59 |
+
return false;
|
60 |
+
|
61 |
+
$params['id'] = $category->getId();
|
62 |
+
|
63 |
+
return Mage::helper('adminhtml')
|
64 |
+
->getUrl('adminhtml/catalog_category/edit/', $params);
|
65 |
+
}
|
66 |
+
|
67 |
+
protected function _getWithoutImagesLink () {
|
68 |
+
if ($isCategoryPage = $this->_getType() == 'category') {
|
69 |
+
$params['_current'] = true;
|
70 |
+
$params['_use_rewrite'] = true;
|
71 |
+
}
|
72 |
+
|
73 |
+
$params['_query'] = array('without_images_only' => true);
|
74 |
+
|
75 |
+
return Mage::getUrl(
|
76 |
+
$isCategoryPage ? '*/*/*' : 'catalog/category/all',
|
77 |
+
$params
|
78 |
+
);
|
79 |
+
}
|
80 |
+
|
81 |
+
public function _getAnalyticsUrl () {
|
82 |
+
return Mage::getStoreConfig(self::CONFIG_ANALYTICS_URL);
|
83 |
+
}
|
84 |
+
|
85 |
+
public function _getHelpUrl () {
|
86 |
+
return 'http://mventory.com/help/toolbar/mventory-toolbar/';
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Build a form object populated with product data.
|
91 |
+
*
|
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 |
+
|
175 |
+
}
|
app/code/community/MVentory/Productivity/Block/Product/Latest.php
ADDED
@@ -0,0 +1,112 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for displaying latest added products
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Product_Latest
|
23 |
+
extends Mage_Catalog_Block_Product_Abstract {
|
24 |
+
|
25 |
+
protected $_productsCount = null;
|
26 |
+
|
27 |
+
const DEFAULT_PRODUCTS_COUNT = 6;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Initialize block's cache
|
31 |
+
*/
|
32 |
+
protected function _construct () {
|
33 |
+
parent::_construct();
|
34 |
+
|
35 |
+
$this
|
36 |
+
->addColumnCountLayoutDepend('two_columns_left', 3)
|
37 |
+
->addColumnCountLayoutDepend('two_columns_right', 3);
|
38 |
+
|
39 |
+
$this
|
40 |
+
->addData(array(
|
41 |
+
'cache_lifetime' => 86400,
|
42 |
+
'cache_tags' => array(Mage_Catalog_Model_Product::CACHE_TAG),
|
43 |
+
));
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Get Key pieces for caching block content
|
48 |
+
*
|
49 |
+
* @return array
|
50 |
+
*/
|
51 |
+
public function getCacheKeyInfo () {
|
52 |
+
return array(
|
53 |
+
'CATALOG_PRODUCT_LATEST',
|
54 |
+
Mage::app()->getStore()->getId(),
|
55 |
+
Mage::getDesign()->getPackageName(),
|
56 |
+
Mage::getDesign()->getTheme('template'),
|
57 |
+
Mage::getSingleton('customer/session')->getCustomerGroupId(),
|
58 |
+
'template' => $this->getTemplate(),
|
59 |
+
$this->getProductsCount()
|
60 |
+
);
|
61 |
+
}
|
62 |
+
public function getProductCollection () {
|
63 |
+
$collection = $this->getData('product_collection');
|
64 |
+
|
65 |
+
if ($collection)
|
66 |
+
return $collection;
|
67 |
+
|
68 |
+
$visibility = Mage::getSingleton('catalog/product_visibility')
|
69 |
+
->getVisibleInCatalogIds();
|
70 |
+
|
71 |
+
$collection = Mage::getResourceModel('catalog/product_collection')
|
72 |
+
->setVisibility($visibility);
|
73 |
+
|
74 |
+
$imageFilter = array('nin' => array('no_selection', ''));
|
75 |
+
|
76 |
+
$collection = $this
|
77 |
+
->_addProductAttributesAndPrices($collection)
|
78 |
+
->addAttributeToFilter('small_image', $imageFilter)
|
79 |
+
->addStoreFilter()
|
80 |
+
->addAttributeToSort('entity_id', 'desc')
|
81 |
+
->setPageSize($this->getProductsCount())
|
82 |
+
->setCurPage(1);
|
83 |
+
|
84 |
+
$this->setData('product_collection', $collection);
|
85 |
+
|
86 |
+
return $collection;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Set how much product should be displayed at once.
|
91 |
+
*
|
92 |
+
* @param $count
|
93 |
+
* @return Mage_Catalog_Block_Product_New
|
94 |
+
*/
|
95 |
+
public function setProductsCount ($count) {
|
96 |
+
$this->_productsCount = $count;
|
97 |
+
|
98 |
+
return $this;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Get how much products should be displayed at once.
|
103 |
+
*
|
104 |
+
* @return int
|
105 |
+
*/
|
106 |
+
public function getProductsCount () {
|
107 |
+
if (null === $this->_productsCount)
|
108 |
+
$this->_productsCount = self::DEFAULT_PRODUCTS_COUNT;
|
109 |
+
|
110 |
+
return $this->_productsCount;
|
111 |
+
}
|
112 |
+
}
|
app/code/community/MVentory/Productivity/Block/Product/Random.php
ADDED
@@ -0,0 +1,116 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for displaying random products
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Product_Random
|
23 |
+
extends Mage_Catalog_Block_Product_Abstract {
|
24 |
+
|
25 |
+
protected $_productsCount = null;
|
26 |
+
|
27 |
+
const DEFAULT_PRODUCTS_COUNT = 6;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Initialize block's cache
|
31 |
+
*/
|
32 |
+
protected function _construct () {
|
33 |
+
parent::_construct();
|
34 |
+
|
35 |
+
$this
|
36 |
+
->addColumnCountLayoutDepend('two_columns_left', 3)
|
37 |
+
->addColumnCountLayoutDepend('two_columns_right', 3);
|
38 |
+
|
39 |
+
$this
|
40 |
+
->addData(array(
|
41 |
+
'cache_lifetime' => 86400,
|
42 |
+
'cache_tags' => array(Mage_Catalog_Model_Product::CACHE_TAG),
|
43 |
+
));
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Get Key pieces for caching block content
|
48 |
+
*
|
49 |
+
* @return array
|
50 |
+
*/
|
51 |
+
public function getCacheKeyInfo () {
|
52 |
+
return array(
|
53 |
+
'CATALOG_PRODUCT_RANDOM',
|
54 |
+
Mage::app()->getStore()->getId(),
|
55 |
+
Mage::getDesign()->getPackageName(),
|
56 |
+
Mage::getDesign()->getTheme('template'),
|
57 |
+
Mage::getSingleton('customer/session')->getCustomerGroupId(),
|
58 |
+
'template' => $this->getTemplate(),
|
59 |
+
$this->getProductsCount()
|
60 |
+
);
|
61 |
+
}
|
62 |
+
|
63 |
+
public function getProductCollection () {
|
64 |
+
$collection = $this->getData('product_collection');
|
65 |
+
|
66 |
+
if ($collection)
|
67 |
+
return $collection;
|
68 |
+
|
69 |
+
$visibility = Mage::getSingleton('catalog/product_visibility')
|
70 |
+
->getVisibleInCatalogIds();
|
71 |
+
|
72 |
+
$collection = Mage::getResourceModel('catalog/product_collection')
|
73 |
+
->setVisibility($visibility);
|
74 |
+
|
75 |
+
$imageFilter = array('nin' => array('no_selection', ''));
|
76 |
+
|
77 |
+
$collection = $this
|
78 |
+
->_addProductAttributesAndPrices($collection)
|
79 |
+
->addAttributeToFilter('small_image', $imageFilter)
|
80 |
+
->addStoreFilter()
|
81 |
+
->setPageSize($this->getProductsCount())
|
82 |
+
->setCurPage(1);
|
83 |
+
|
84 |
+
$collection
|
85 |
+
->getSelect()
|
86 |
+
->order(new Zend_Db_Expr('RAND()'));
|
87 |
+
|
88 |
+
$this->setData('product_collection', $collection);
|
89 |
+
|
90 |
+
return $collection;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Set how many product should be displayed at once.
|
95 |
+
*
|
96 |
+
* @param $count
|
97 |
+
* @return Mage_Catalog_Block_Product_New
|
98 |
+
*/
|
99 |
+
public function setProductsCount ($count) {
|
100 |
+
$this->_productsCount = $count;
|
101 |
+
|
102 |
+
return $this;
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Get how many products should be displayed at once.
|
107 |
+
*
|
108 |
+
* @return int
|
109 |
+
*/
|
110 |
+
public function getProductsCount () {
|
111 |
+
if (null === $this->_productsCount)
|
112 |
+
$this->_productsCount = self::DEFAULT_PRODUCTS_COUNT;
|
113 |
+
|
114 |
+
return $this->_productsCount;
|
115 |
+
}
|
116 |
+
}
|
app/code/community/MVentory/Productivity/Block/Product/Related.php
ADDED
@@ -0,0 +1,86 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for displaying related product by specified attribute
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Product_Related
|
23 |
+
extends Mage_Catalog_Block_Product_Abstract {
|
24 |
+
|
25 |
+
public function getCacheKeyInfo () {
|
26 |
+
return array_merge(
|
27 |
+
parent::getCacheKeyInfo(),
|
28 |
+
array(
|
29 |
+
Mage::getSingleton('customer/session')->getCustomerGroupId(),
|
30 |
+
($product = $this->getProduct()) ? $product->getId() : null,
|
31 |
+
$this->getData('attribute_code'),
|
32 |
+
$this->getData('product_count')
|
33 |
+
)
|
34 |
+
);
|
35 |
+
}
|
36 |
+
|
37 |
+
public function getProductCollection () {
|
38 |
+
$collection = $this->getData('product_collection');
|
39 |
+
|
40 |
+
if ($collection)
|
41 |
+
return $collection;
|
42 |
+
|
43 |
+
$this->setData(
|
44 |
+
'product_collection',
|
45 |
+
$collection = new Varien_Data_Collection()
|
46 |
+
);
|
47 |
+
|
48 |
+
if (!(($product = $this->getProduct())
|
49 |
+
&& ($productId = $product->getId())))
|
50 |
+
return $collection;
|
51 |
+
|
52 |
+
if (!$code = trim($this->getData('attribute_code')))
|
53 |
+
return $collection;
|
54 |
+
|
55 |
+
if (($value = $product->getData($code)) === null)
|
56 |
+
return $collection;
|
57 |
+
|
58 |
+
$visibility = Mage::getSingleton('catalog/product_visibility')
|
59 |
+
->getVisibleInCatalogIds();
|
60 |
+
|
61 |
+
$imageFilter = array('nin' => array('no_selection', ''));
|
62 |
+
|
63 |
+
$collection = Mage::getResourceModel('catalog/product_collection')
|
64 |
+
->addAttributeToSelect(array(
|
65 |
+
'name',
|
66 |
+
'special_price',
|
67 |
+
'special_from_date',
|
68 |
+
'special_to_date'
|
69 |
+
))
|
70 |
+
->addPriceData()
|
71 |
+
->addUrlRewrite()
|
72 |
+
->addIdFilter($productId, true)
|
73 |
+
->addAttributeToFilter($code, $value)
|
74 |
+
->addAttributeToFilter('small_image', $imageFilter)
|
75 |
+
->setVisibility($visibility)
|
76 |
+
->addStoreFilter()
|
77 |
+
->setPageSize($this->getProductsCount())
|
78 |
+
->setCurPage(1);
|
79 |
+
|
80 |
+
$collection
|
81 |
+
->getSelect()
|
82 |
+
->order(new Zend_Db_Expr('RAND()'));
|
83 |
+
|
84 |
+
return $collection;
|
85 |
+
}
|
86 |
+
}
|
app/code/community/MVentory/Productivity/Block/Product/View.php
ADDED
@@ -0,0 +1,36 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Product view block
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
|
23 |
+
class MVentory_Productivity_Block_Product_View
|
24 |
+
extends Mage_Catalog_Block_Product_View {
|
25 |
+
|
26 |
+
public function getMinimalQty ($product) {
|
27 |
+
$minimalQty = parent::getMinimalQty($product);
|
28 |
+
|
29 |
+
if (!$minimalQty)
|
30 |
+
return $minimalQty;
|
31 |
+
|
32 |
+
$stockItem = $product->getStockItem();
|
33 |
+
|
34 |
+
return $stockItem->getIsQtyDecimal() ? $minimalQty : ceil($minimalQty);
|
35 |
+
}
|
36 |
+
}
|
app/code/community/MVentory/Productivity/Block/Rss/Import.php
ADDED
@@ -0,0 +1,110 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for displaying external feeds
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Rss_Import
|
23 |
+
extends Mage_Core_Block_Template {
|
24 |
+
|
25 |
+
public function __construct() {
|
26 |
+
parent::__construct();
|
27 |
+
|
28 |
+
//Default template
|
29 |
+
$this->setTemplate('productivity/rss/import.phtml');
|
30 |
+
|
31 |
+
//Default period
|
32 |
+
$this->setCacheLifetime(86400);
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getCacheKeyInfo () {
|
36 |
+
$design = Mage::getDesign();
|
37 |
+
|
38 |
+
return array_merge(
|
39 |
+
parent::getCacheKeyInfo(),
|
40 |
+
array(
|
41 |
+
$this->getData('uri'),
|
42 |
+
$design->getTheme('layout'),
|
43 |
+
$design->getTheme('locale')
|
44 |
+
)
|
45 |
+
);
|
46 |
+
}
|
47 |
+
|
48 |
+
public function getCacheTags () {
|
49 |
+
$tag = md5($this->getData('post_link'));
|
50 |
+
|
51 |
+
$parentBlock = $this;
|
52 |
+
|
53 |
+
//Find parent block which caches its content and add the tag
|
54 |
+
//to prevent effect of nested caching
|
55 |
+
while ($parentBlock = $parentBlock->getParentBlock())
|
56 |
+
if ($parentBlock instanceof Mage_Core_Block_Template
|
57 |
+
&& !($parentBlock instanceof Mage_Page_Block_Html)) {
|
58 |
+
|
59 |
+
$tags = (array) $parentBlock->getData('cache_tags');
|
60 |
+
|
61 |
+
$tags[] = $tag;
|
62 |
+
|
63 |
+
$parentBlock->setData('cache_tags', $tags);
|
64 |
+
|
65 |
+
break;
|
66 |
+
}
|
67 |
+
|
68 |
+
$tags = parent::getCacheTags();
|
69 |
+
|
70 |
+
$tags[] = $tag;
|
71 |
+
|
72 |
+
return $tags;
|
73 |
+
}
|
74 |
+
|
75 |
+
public function getFeed () {
|
76 |
+
$feed = $this->getData('feed');
|
77 |
+
|
78 |
+
if ($feed)
|
79 |
+
return $feed;
|
80 |
+
|
81 |
+
$uri = $this->getUri();
|
82 |
+
|
83 |
+
if (!$uri)
|
84 |
+
return null;
|
85 |
+
|
86 |
+
try {
|
87 |
+
$feed = Zend_Feed::import($uri);
|
88 |
+
} catch (Exception $e) {
|
89 |
+
return null;
|
90 |
+
}
|
91 |
+
|
92 |
+
$this->setFeed($feed);
|
93 |
+
|
94 |
+
return $feed;
|
95 |
+
}
|
96 |
+
|
97 |
+
public function getContent () {
|
98 |
+
if (!$feed = $this->getFeed())
|
99 |
+
return false;
|
100 |
+
|
101 |
+
if (!count($feed))
|
102 |
+
return false;
|
103 |
+
|
104 |
+
$post = $feed->current();
|
105 |
+
|
106 |
+
$this->setData('post_link', $post->link());
|
107 |
+
|
108 |
+
return $post->encoded();
|
109 |
+
}
|
110 |
+
}
|
app/code/community/MVentory/Productivity/Block/Rss/Product/Latest.php
ADDED
@@ -0,0 +1,67 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block for displaying latest added products in RSS format
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Rss_Product_Latest
|
23 |
+
extends Mage_Rss_Block_Abstract {
|
24 |
+
|
25 |
+
const ITEMS_NUMBER = 30;
|
26 |
+
|
27 |
+
protected function _construct () {
|
28 |
+
parent::_construct();
|
29 |
+
|
30 |
+
$this
|
31 |
+
->addData(array(
|
32 |
+
'cache_lifetime' => 1800,
|
33 |
+
'cache_tags' => array(Mage_Catalog_Model_Product::CACHE_TAG),
|
34 |
+
));
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Get Key pieces for caching block content
|
39 |
+
*
|
40 |
+
* @return array
|
41 |
+
*/
|
42 |
+
public function getCacheKeyInfo () {
|
43 |
+
return array(
|
44 |
+
'PRODUCTIVITY_RSS_PRODUCT_LATEST',
|
45 |
+
$this->_getStoreId(),
|
46 |
+
Mage::getSingleton('customer/session')->getCustomerGroupId(),
|
47 |
+
);
|
48 |
+
}
|
49 |
+
|
50 |
+
protected function _toHtml () {
|
51 |
+
$products = $this
|
52 |
+
->getLayout()
|
53 |
+
->createBlock('productivity/product_latest')
|
54 |
+
->setProductsCount(self::ITEMS_NUMBER)
|
55 |
+
->getProductCollection();
|
56 |
+
|
57 |
+
$data = array(
|
58 |
+
'title' => $this->__('Latest products'),
|
59 |
+
'link' => Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB),
|
60 |
+
'images' => array()
|
61 |
+
);
|
62 |
+
|
63 |
+
return $this
|
64 |
+
->helper('productivity/rss')
|
65 |
+
->generateFeedForProducts($products, $data);
|
66 |
+
}
|
67 |
+
}
|
app/code/community/MVentory/Productivity/Block/Slideshow.php
ADDED
@@ -0,0 +1,170 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Universal slideshow block
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Slideshow
|
23 |
+
extends Mage_Catalog_Block_Product_Abstract
|
24 |
+
implements Mage_Widget_Block_Interface {
|
25 |
+
|
26 |
+
protected function _construct () {
|
27 |
+
parent::_construct();
|
28 |
+
|
29 |
+
$this
|
30 |
+
->addData(array(
|
31 |
+
'cache_lifetime' => 86400,
|
32 |
+
'cache_tags' => array(Mage_Catalog_Model_Product::CACHE_TAG),
|
33 |
+
));
|
34 |
+
}
|
35 |
+
|
36 |
+
public function getCacheKeyInfo () {
|
37 |
+
return array(
|
38 |
+
'CATALOG_PRODUCT_RANDOM',
|
39 |
+
Mage::app()->getStore()->getId(),
|
40 |
+
Mage::getSingleton('customer/session')->getCustomerGroupId(),
|
41 |
+
'template' => $this->getData('item_template'),
|
42 |
+
'image_size' => $this->getData('image_size'),
|
43 |
+
$this->getProductsCount()
|
44 |
+
);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function getProductCollection () {
|
48 |
+
$collection = $this->getData('product_collection');
|
49 |
+
|
50 |
+
if ($collection)
|
51 |
+
return $collection;
|
52 |
+
|
53 |
+
$visibility = Mage::getSingleton('catalog/product_visibility')
|
54 |
+
->getVisibleInCatalogIds();
|
55 |
+
|
56 |
+
$imageFilter = array('nin' => array('no_selection', ''));
|
57 |
+
|
58 |
+
$collection = Mage::getResourceModel('catalog/product_collection')
|
59 |
+
->addAttributeToSelect(array(
|
60 |
+
'name',
|
61 |
+
'special_price',
|
62 |
+
'special_from_date',
|
63 |
+
'special_to_date'
|
64 |
+
))
|
65 |
+
->addPriceData()
|
66 |
+
->addUrlRewrite()
|
67 |
+
->addAttributeToFilter('small_image', $imageFilter)
|
68 |
+
->setVisibility($visibility)
|
69 |
+
->addStoreFilter()
|
70 |
+
->setPageSize($this->getProductsCount())
|
71 |
+
->setCurPage(1);
|
72 |
+
$collection
|
73 |
+
->getSelect()
|
74 |
+
->order(new Zend_Db_Expr('RAND()'));
|
75 |
+
|
76 |
+
$this->setData('product_collection', $collection);
|
77 |
+
|
78 |
+
return $collection;
|
79 |
+
}
|
80 |
+
|
81 |
+
protected function _toHtml () {
|
82 |
+
$template = $this->getData('item_template');
|
83 |
+
list($width, $height) = explode('x', $this->getData('image_size'));
|
84 |
+
|
85 |
+
($width = (int) $width) || ($width = null);
|
86 |
+
($height = (int) $height) || ($height = null);
|
87 |
+
|
88 |
+
$helper = Mage::helper('catalog/image');
|
89 |
+
$outputHelper = $this->helper('catalog/output');
|
90 |
+
$coreHelper = Mage::helper('core');
|
91 |
+
|
92 |
+
$search = array(
|
93 |
+
'%name%',
|
94 |
+
'%description%',
|
95 |
+
'%price%',
|
96 |
+
'%price-block%',
|
97 |
+
'%url%',
|
98 |
+
'%img%',
|
99 |
+
'%add-to-cart-url%'
|
100 |
+
);
|
101 |
+
|
102 |
+
$store = Mage::app()->getStore();
|
103 |
+
$locale = Mage::app()->getLocale();
|
104 |
+
|
105 |
+
$statements = array(
|
106 |
+
'sale' => function ($body, $product) use ($locale, $store) {
|
107 |
+
$specialPrice = $product->getSpecialPrice();
|
108 |
+
$hasSpecial = $specialPrice !== null
|
109 |
+
&& $specialPrice !== false
|
110 |
+
&& $locale->isStoreDateInInterval(
|
111 |
+
$store,
|
112 |
+
$product->getSpecialFromDate(),
|
113 |
+
$product->getSpecialToDate()
|
114 |
+
);
|
115 |
+
|
116 |
+
return $hasSpecial ? $body : '';
|
117 |
+
}
|
118 |
+
);
|
119 |
+
|
120 |
+
$html = '';
|
121 |
+
|
122 |
+
foreach ($this->getProductCollection() as $product) {
|
123 |
+
$replace = array(
|
124 |
+
//%name%
|
125 |
+
$product->getName(),
|
126 |
+
|
127 |
+
//%description%
|
128 |
+
$outputHelper->productAttribute(
|
129 |
+
$product,
|
130 |
+
$product->getShortDescription(),
|
131 |
+
'short_description'
|
132 |
+
),
|
133 |
+
|
134 |
+
//%price%
|
135 |
+
$coreHelper->currency($product->getPrice(), true, false),
|
136 |
+
|
137 |
+
//%price-block%
|
138 |
+
$this->getPriceHtml($product),
|
139 |
+
|
140 |
+
//%url%
|
141 |
+
$product->getProductUrl(),
|
142 |
+
|
143 |
+
//%img%
|
144 |
+
(string) $helper
|
145 |
+
->init($product, 'small_image')
|
146 |
+
->resize($width, $height),
|
147 |
+
|
148 |
+
//%add-to-cart-url%
|
149 |
+
$this->getAddToCartUrl($product)
|
150 |
+
);
|
151 |
+
|
152 |
+
$html .= preg_replace_callback(
|
153 |
+
'/%if:(?<statement>.+)%(?<body>.+)%end:\k<statement>%/is',
|
154 |
+
function ($matches) use ($statements, $product) {
|
155 |
+
$statement = trim($matches['statement']);
|
156 |
+
|
157 |
+
if (!isset($statements[$statement]))
|
158 |
+
return '';
|
159 |
+
|
160 |
+
$func = $statements[$statement];
|
161 |
+
|
162 |
+
return $func($matches['body'], $product);
|
163 |
+
},
|
164 |
+
str_replace($search, $replace, $template)
|
165 |
+
);
|
166 |
+
}
|
167 |
+
|
168 |
+
return $html;
|
169 |
+
}
|
170 |
+
}
|
app/code/community/MVentory/Productivity/Block/Widget/Attribute.php
ADDED
@@ -0,0 +1,83 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Block to output attribute values
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Widget_Attribute
|
23 |
+
extends Mage_Core_Block_Abstract implements Mage_Widget_Block_Interface {
|
24 |
+
|
25 |
+
protected function _construct () {
|
26 |
+
parent::_construct();
|
27 |
+
|
28 |
+
$this->setData('cache_lifetime', 86400);
|
29 |
+
}
|
30 |
+
|
31 |
+
public function getCacheKeyInfo () {
|
32 |
+
return array(
|
33 |
+
'EAV_ATTRIBUTE_VALUE_LIST',
|
34 |
+
Mage::app()->getStore()->getId(),
|
35 |
+
Mage::getSingleton('customer/session')->getCustomerGroupId(),
|
36 |
+
'template' => $this->getData('item_template'),
|
37 |
+
'code' => $this->getData('code'),
|
38 |
+
);
|
39 |
+
}
|
40 |
+
|
41 |
+
protected function _getAttributeSource () {
|
42 |
+
$attr = $this->getData('attribute_source');
|
43 |
+
|
44 |
+
if ($attr)
|
45 |
+
return $attr;
|
46 |
+
|
47 |
+
if (!$code = $this->getData('code'))
|
48 |
+
return null;
|
49 |
+
|
50 |
+
$attr = Mage::getModel('productivity/widget_attribute')
|
51 |
+
->loadByCode($code);
|
52 |
+
|
53 |
+
$this->setData('attribute_source', $attr);
|
54 |
+
|
55 |
+
return $attr;
|
56 |
+
}
|
57 |
+
|
58 |
+
protected function _toHtml () {
|
59 |
+
$html = '';
|
60 |
+
|
61 |
+
$attr = $this->_getAttributeSource();
|
62 |
+
|
63 |
+
if (!$attr)
|
64 |
+
return $html;
|
65 |
+
|
66 |
+
$template = $this->getData('item_template');
|
67 |
+
$code = $this->getData('code');
|
68 |
+
|
69 |
+
$search = array('%code%', '%value%', '%label%');
|
70 |
+
|
71 |
+
foreach ($attr->getOptions() as $option) {
|
72 |
+
$replace = array(
|
73 |
+
$code,
|
74 |
+
$option['value'],
|
75 |
+
$option['label'],
|
76 |
+
);
|
77 |
+
|
78 |
+
$html .= str_replace($search, $replace, $template);
|
79 |
+
}
|
80 |
+
|
81 |
+
return $html;
|
82 |
+
}
|
83 |
+
}
|
app/code/community/MVentory/Productivity/Block/Widget/Latest.php
ADDED
@@ -0,0 +1,64 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Widget to display latest products
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Block_Widget_Latest
|
23 |
+
extends MVentory_Productivity_Block_Slideshow
|
24 |
+
{
|
25 |
+
|
26 |
+
public function getCacheKeyInfo () {
|
27 |
+
return array(
|
28 |
+
'CATALOG_PRODUCT_LATEST',
|
29 |
+
Mage::app()->getStore()->getId(),
|
30 |
+
Mage::getSingleton('customer/session')->getCustomerGroupId(),
|
31 |
+
'template' => $this->getData('item_template'),
|
32 |
+
'image_size' => $this->getData('image_size'),
|
33 |
+
$this->getProductsCount()
|
34 |
+
);
|
35 |
+
}
|
36 |
+
|
37 |
+
public function getProductCollection () {
|
38 |
+
$collection = $this->getData('product_collection');
|
39 |
+
|
40 |
+
if ($collection)
|
41 |
+
return $collection;
|
42 |
+
|
43 |
+
$visibility = Mage::getSingleton('catalog/product_visibility')
|
44 |
+
->getVisibleInCatalogIds();
|
45 |
+
|
46 |
+
$collection = Mage::getResourceModel('catalog/product_collection')
|
47 |
+
->setVisibility($visibility);
|
48 |
+
|
49 |
+
$collection = $this
|
50 |
+
->_addProductAttributesAndPrices($collection)
|
51 |
+
->addAttributeToFilter(
|
52 |
+
'small_image',
|
53 |
+
array('nin' => array('no_selection', ''))
|
54 |
+
)
|
55 |
+
->addStoreFilter()
|
56 |
+
->addAttributeToSort('entity_id', 'desc')
|
57 |
+
->setPageSize($this->getProductsCount())
|
58 |
+
->setCurPage(1);
|
59 |
+
|
60 |
+
$this->setData('product_collection', $collection);
|
61 |
+
|
62 |
+
return $collection;
|
63 |
+
}
|
64 |
+
}
|
app/code/community/MVentory/Productivity/Exception.php
ADDED
@@ -0,0 +1,24 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Productivity base exception
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Exception extends Mage_Core_Exception
|
23 |
+
{
|
24 |
+
}
|
app/code/community/MVentory/Productivity/Helper/Data.php
ADDED
@@ -0,0 +1,248 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Helper
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Helper_Data
|
23 |
+
extends Mage_Core_Helper_Abstract {
|
24 |
+
|
25 |
+
const ATTRIBUTE_CODE = 'media_gallery';
|
26 |
+
const REVIEWER_GROUP_CODE = 'REVIEWER';
|
27 |
+
|
28 |
+
private $_mediaBackend = array();
|
29 |
+
|
30 |
+
public function rotate ($file, $angle) {
|
31 |
+
$image = Mage::getModel('catalog/product_image');
|
32 |
+
|
33 |
+
$image
|
34 |
+
->setBaseFile($file)
|
35 |
+
->setQuality(100)
|
36 |
+
->setKeepFrame(false)
|
37 |
+
->rotate($angle)
|
38 |
+
->saveFile();
|
39 |
+
|
40 |
+
return $image->getNewFile();
|
41 |
+
}
|
42 |
+
|
43 |
+
public function remove ($file, $product) {
|
44 |
+
$backend = $this->_getMediaBackend($product);
|
45 |
+
|
46 |
+
if (!$backend->getImage($product, $file))
|
47 |
+
throw new MVentory_Productivity_Exception('No image in the product');
|
48 |
+
|
49 |
+
$backend->removeImage($product, $file);
|
50 |
+
$product->save();
|
51 |
+
|
52 |
+
return true;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function setMainImage ($file, $product) {
|
56 |
+
$backend = $this->_getMediaBackend($product);
|
57 |
+
|
58 |
+
if (!$backend->getImage($product, $file))
|
59 |
+
throw new MVentory_Productivity_Exception('No image in the product');
|
60 |
+
|
61 |
+
$currentImage = $product->getImage();
|
62 |
+
|
63 |
+
if ($currentImage) {
|
64 |
+
$data = $backend->getImage($product, $currentImage);
|
65 |
+
$disabled = $data['disabled'];
|
66 |
+
|
67 |
+
unset($data);
|
68 |
+
|
69 |
+
$backend->updateImage($product, $currentImage, array('exclude' => false));
|
70 |
+
}
|
71 |
+
|
72 |
+
if (isset($disabled) && $disabled)
|
73 |
+
$backend->updateImage($product, $file, array('exclude' => true));
|
74 |
+
|
75 |
+
$backend->setMediaAttribute(
|
76 |
+
$product,
|
77 |
+
array('image', 'small_image', 'thumbnail'),
|
78 |
+
$file
|
79 |
+
);
|
80 |
+
|
81 |
+
$product->save();
|
82 |
+
|
83 |
+
return true;
|
84 |
+
}
|
85 |
+
|
86 |
+
public function updateImageInGallery ($oldFile, $newFile, $product,
|
87 |
+
$mediaAttributes = null, $move = true,
|
88 |
+
$exclude = false) {
|
89 |
+
|
90 |
+
$backend = $this->_getMediaBackend($product);
|
91 |
+
|
92 |
+
$backend->removeImage($product, $oldFile);
|
93 |
+
|
94 |
+
$file = $backend->addImage(
|
95 |
+
$product,
|
96 |
+
$newFile,
|
97 |
+
$mediaAttributes,
|
98 |
+
$move,
|
99 |
+
$exclude
|
100 |
+
);
|
101 |
+
|
102 |
+
$product->save();
|
103 |
+
|
104 |
+
return $file;
|
105 |
+
}
|
106 |
+
|
107 |
+
public function add ($product, $data) {
|
108 |
+
$backend = $this->_getMediaBackend($product);
|
109 |
+
|
110 |
+
$gallery = $product->getData(self::ATTRIBUTE_CODE);
|
111 |
+
|
112 |
+
$mediaAttributes = null;
|
113 |
+
|
114 |
+
if (!(isset($gallery['images']) && $gallery['images']))
|
115 |
+
$mediaAttributes = array_keys($product->getMediaAttributes());
|
116 |
+
|
117 |
+
$backend->addImage(
|
118 |
+
$product,
|
119 |
+
$data['path'] . $data['file'],
|
120 |
+
$mediaAttributes,
|
121 |
+
true,
|
122 |
+
false
|
123 |
+
);
|
124 |
+
|
125 |
+
$product->save();
|
126 |
+
|
127 |
+
$gallery = $product->getData(self::ATTRIBUTE_CODE);
|
128 |
+
|
129 |
+
if (!(isset($gallery['images']) && $gallery['images']))
|
130 |
+
throw new MVentory_Productivity_Exception('Image gallery is not loaded');
|
131 |
+
|
132 |
+
$image = end($gallery['images']);
|
133 |
+
|
134 |
+
if (!(isset($image['new_file'], $image['file'])
|
135 |
+
&& $image['new_file']
|
136 |
+
&& $image['file']))
|
137 |
+
throw new MVentory_Productivity_Exception(
|
138 |
+
'No newly added image in the product'
|
139 |
+
);
|
140 |
+
|
141 |
+
return $image['file'];
|
142 |
+
}
|
143 |
+
|
144 |
+
protected function _getMediaBackend ($product) {
|
145 |
+
if (!$id = $product->getId())
|
146 |
+
throw new MVentory_Productivity_Exception('Product is not loaded');
|
147 |
+
|
148 |
+
if (isset($this->_mediaBackend[$id]))
|
149 |
+
return $this->_mediaBackend[$id];
|
150 |
+
|
151 |
+
$attributes = $product
|
152 |
+
->getTypeInstance(true)
|
153 |
+
->getSetAttributes($product);
|
154 |
+
|
155 |
+
if (!isset($attributes[self::ATTRIBUTE_CODE]))
|
156 |
+
throw new MVentory_Productivity_Exception(
|
157 |
+
'Attribute ' . self::ATTRIBUTE_CODE . 'doesn\'t exist in product\'s '
|
158 |
+
. 'attribute set'
|
159 |
+
);
|
160 |
+
|
161 |
+
$gallery = $attributes[self::ATTRIBUTE_CODE];
|
162 |
+
$backend = $gallery->getBackend();
|
163 |
+
|
164 |
+
$this->_mediaBackend[$id] = $backend;
|
165 |
+
|
166 |
+
return $backend;
|
167 |
+
}
|
168 |
+
|
169 |
+
public function isAdminLogged () {
|
170 |
+
return Mage::registry('is_admin_logged') === true;
|
171 |
+
}
|
172 |
+
|
173 |
+
public function isReviewerLogged () {
|
174 |
+
if ($this->isAdminLogged())
|
175 |
+
return true;
|
176 |
+
|
177 |
+
$session = Mage::getSingleton('customer/session');
|
178 |
+
|
179 |
+
$groupId = $session->getCustomerGroupId();
|
180 |
+
|
181 |
+
if ($groupId == Mage_Customer_Model_Group::NOT_LOGGED_IN_ID)
|
182 |
+
return false;
|
183 |
+
|
184 |
+
if ($session->getCustomer()->getWebsiteId()
|
185 |
+
!= Mage::app()->getWebsite()->getId())
|
186 |
+
return false;
|
187 |
+
|
188 |
+
$group = Mage::getModel('customer/group')->load($groupId);
|
189 |
+
|
190 |
+
if (!$group->getId())
|
191 |
+
return false;
|
192 |
+
|
193 |
+
return strcasecmp($group->getCode(), self::REVIEWER_GROUP_CODE) == 0;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Sends email to stores's general contant address
|
198 |
+
*
|
199 |
+
* @param string $subject
|
200 |
+
* @param string $message
|
201 |
+
* @param int|string|Mage_Core_Model_Store $store Store, its ID or code
|
202 |
+
*/
|
203 |
+
public function sendEmail ($subject,
|
204 |
+
$message,
|
205 |
+
$store = Mage_Core_Model_App::ADMIN_STORE_ID) {
|
206 |
+
|
207 |
+
$store = Mage::app()->getStore($store);
|
208 |
+
|
209 |
+
$email = $store->getConfig('trans_email/ident_general/email');
|
210 |
+
$name = $store->getConfig('trans_email/ident_general/name');
|
211 |
+
|
212 |
+
Mage::getModel('core/email')
|
213 |
+
->setFromEmail($email)
|
214 |
+
->setFromName($name)
|
215 |
+
->setToName($name)
|
216 |
+
->setToEmail($email)
|
217 |
+
->setBody($message)
|
218 |
+
->setSubject($subject)
|
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 |
+
}
|
app/code/community/MVentory/Productivity/Helper/Mage/Catalog/Category.php
ADDED
@@ -0,0 +1,52 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Catalog category helper
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Helper_Mage_Catalog_Category
|
23 |
+
extends Mage_Catalog_Helper_Category {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Check if a category can be shown
|
27 |
+
*
|
28 |
+
* The method is redefined to allow access to website's root category.
|
29 |
+
* We need it for showing or filtering over all products in the store.
|
30 |
+
*
|
31 |
+
* @param Mage_Catalog_Model_Category|int $category
|
32 |
+
* @return boolean
|
33 |
+
*/
|
34 |
+
public function canShow ($category) {
|
35 |
+
if (is_int($category))
|
36 |
+
$category = Mage::getModel('catalog/category')->load($category);
|
37 |
+
|
38 |
+
if (!$categoryId = $category->getId())
|
39 |
+
return false;
|
40 |
+
|
41 |
+
if (!$category->getIsActive())
|
42 |
+
return false;
|
43 |
+
|
44 |
+
$isRootCategory
|
45 |
+
= Mage::app()->getStore()->getRootCategoryId() == $categoryId;
|
46 |
+
|
47 |
+
if (!($isRootCategory || $category->isInRootCategoryList()))
|
48 |
+
return false;
|
49 |
+
|
50 |
+
return true;
|
51 |
+
}
|
52 |
+
}
|
app/code/community/MVentory/Productivity/Helper/Rss.php
ADDED
@@ -0,0 +1,236 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* RSS helper
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Helper_Rss
|
23 |
+
extends Mage_Core_Helper_Abstract {
|
24 |
+
|
25 |
+
const MEDIA_NS = 'http://search.yahoo.com/mrss/';
|
26 |
+
const ATOM_NS = 'http://www.w3.org/2005/Atom';
|
27 |
+
|
28 |
+
const IMAGE_WIDTH = 300;
|
29 |
+
const IMAGE_HEIGHT = 300;
|
30 |
+
|
31 |
+
const THUMB_WIDTH = 75;
|
32 |
+
const THUMB_HEIGHT = 75;
|
33 |
+
|
34 |
+
public function generateFeedForProducts ($products, $params) {
|
35 |
+
$params = $this->_prepareParams($params);
|
36 |
+
|
37 |
+
$currency = Mage::app()
|
38 |
+
->getStore(null)
|
39 |
+
->getCurrentCurrency();
|
40 |
+
|
41 |
+
$formatParams = array('display'=>Zend_Currency::NO_SYMBOL);
|
42 |
+
|
43 |
+
$helper = Mage::helper('catalog/image');
|
44 |
+
|
45 |
+
$xml = new SimpleXMLElement('<rss xmlns:media="' . self::MEDIA_NS . '"'
|
46 |
+
. 'xmlns:atom="' . self::ATOM_NS . '"/>');
|
47 |
+
|
48 |
+
$xml->registerXPathNamespace('media', self::MEDIA_NS);
|
49 |
+
$xml->registerXPathNamespace('atom', self::ATOM_NS);
|
50 |
+
$xml->addAttribute('version', '2.0');
|
51 |
+
|
52 |
+
$date = date('r', time());
|
53 |
+
|
54 |
+
$channel = $xml->addChild('channel');
|
55 |
+
|
56 |
+
$channel->title = $params['title'];
|
57 |
+
$channel->link = $params['link'];
|
58 |
+
$channel->addChild('description');
|
59 |
+
$channel->pubDate = $date;
|
60 |
+
$channel->lastBuildDate = $date;
|
61 |
+
$channel->generator = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
|
62 |
+
|
63 |
+
$link = $channel->addChild('link', null, self::ATOM_NS);
|
64 |
+
$link->addAttribute('href', Mage::helper('core/url')->getCurrentUrl());
|
65 |
+
$link->addAttribute('rel', 'self');
|
66 |
+
$link->addAttribute('type', 'application/rss+xml');
|
67 |
+
|
68 |
+
$author = Mage::getStoreConfig('trans_email/ident_general/email')
|
69 |
+
. ' ('
|
70 |
+
. Mage::getStoreConfig('trans_email/ident_general/name')
|
71 |
+
. ')';
|
72 |
+
|
73 |
+
foreach($products as $product) {
|
74 |
+
$name = $product->getName();
|
75 |
+
|
76 |
+
$item = $channel->addChild('item');
|
77 |
+
|
78 |
+
$item->title = $name;
|
79 |
+
$item->link = $product->getProductUrl();
|
80 |
+
$item->description = $this->_getProductAttributes($product);
|
81 |
+
$item->pubDate = date('r', strtotime($product->getUpdatedAt()));
|
82 |
+
$item->author = $author;
|
83 |
+
$item->guid = $item->link;
|
84 |
+
|
85 |
+
$item->addChild('title', htmlspecialchars($name), self::MEDIA_NS);
|
86 |
+
|
87 |
+
foreach ($params['images'] as $tag => $data) {
|
88 |
+
$child = $item->addChild($tag, '', self::MEDIA_NS);
|
89 |
+
|
90 |
+
$url = $helper->init($product, 'small_image');
|
91 |
+
|
92 |
+
if (count($data) == 2) {
|
93 |
+
$url->resize($data['width'], $data['height']);
|
94 |
+
|
95 |
+
foreach (array('width', 'height') as $p)
|
96 |
+
if ($data[$p])
|
97 |
+
$child->addAttribute($p, $data[$p]);
|
98 |
+
}
|
99 |
+
|
100 |
+
$child->addAttribute('url', $url->__toString());
|
101 |
+
}
|
102 |
+
|
103 |
+
//We assume that current currency and base currency are same.
|
104 |
+
//I.e. no currency convertion in the store
|
105 |
+
$price = $currency->format($product->getPrice(), $formatParams, false);
|
106 |
+
|
107 |
+
$item
|
108 |
+
->addChild('price', '', self::MEDIA_NS)
|
109 |
+
->addAttribute('price', $price);
|
110 |
+
}
|
111 |
+
|
112 |
+
return $this->formatXml($xml->asXML());
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Returns RSS data in JSON format
|
117 |
+
*
|
118 |
+
* @param array|Traversable $products List of products
|
119 |
+
* @param array $params Parameters
|
120 |
+
* @return string
|
121 |
+
*/
|
122 |
+
public function asJson ($products, $params) {
|
123 |
+
$params = $this->_prepareParams($params);
|
124 |
+
|
125 |
+
$helper = Mage::helper('catalog/image');
|
126 |
+
$currency = Mage::app()
|
127 |
+
->getStore(null)
|
128 |
+
->getCurrentCurrency();
|
129 |
+
|
130 |
+
foreach($products as $product) {
|
131 |
+
$image = $helper->init($product, 'small_image');
|
132 |
+
|
133 |
+
if (count($params['images']['content']) == 2)
|
134 |
+
$image->resize(
|
135 |
+
$params['images']['content']['width'],
|
136 |
+
$params['images']['content']['height']
|
137 |
+
);
|
138 |
+
|
139 |
+
$_products[] = array(
|
140 |
+
'title' => $product->getName(),
|
141 |
+
'description' => $this->_getProductAttributes($product),
|
142 |
+
'url' => $product->getProductUrl(),
|
143 |
+
'image' => $image->__toString(),
|
144 |
+
'price' => $currency->format($product->getPrice(), array(), false)
|
145 |
+
);
|
146 |
+
}
|
147 |
+
|
148 |
+
return Mage::helper('core')->jsonEncode(
|
149 |
+
isset($_products) ? $_products : array()
|
150 |
+
);
|
151 |
+
}
|
152 |
+
|
153 |
+
public function formatXml ($xml) {
|
154 |
+
$dom = new DOMDocument('1.0');
|
155 |
+
|
156 |
+
$dom->preserveWhiteSpace = false;
|
157 |
+
$dom->formatOutput = true;
|
158 |
+
$dom->loadXML($xml);
|
159 |
+
|
160 |
+
return $dom->saveXML();
|
161 |
+
}
|
162 |
+
|
163 |
+
public function addFeedToHeader ($url, $title = null) {
|
164 |
+
$head = $this
|
165 |
+
->getLayout()
|
166 |
+
->getBlock('head');
|
167 |
+
|
168 |
+
if (!$head)
|
169 |
+
return;
|
170 |
+
|
171 |
+
if (!$title)
|
172 |
+
$title = $head->getTitle();
|
173 |
+
|
174 |
+
$head->addItem('rss', $url, 'title="' . $title . '"');
|
175 |
+
}
|
176 |
+
|
177 |
+
public function getLayout () {
|
178 |
+
$layout = parent::getLayout();
|
179 |
+
|
180 |
+
if ($layout)
|
181 |
+
return $layout;
|
182 |
+
|
183 |
+
$layout = Mage::app()
|
184 |
+
->getFrontController()
|
185 |
+
->getAction()
|
186 |
+
->getLayout();
|
187 |
+
|
188 |
+
parent::setLayout($layout);
|
189 |
+
|
190 |
+
return $layout;
|
191 |
+
}
|
192 |
+
|
193 |
+
protected function _getProductAttributes ($product) {
|
194 |
+
Mage::register('product', $product->load($product->getId()));
|
195 |
+
|
196 |
+
$_attrs = $this
|
197 |
+
->getLayout()
|
198 |
+
->createBlock('catalog/product_view_attributes')
|
199 |
+
->getAdditionalData(array(), false);
|
200 |
+
|
201 |
+
Mage::unregister('product');
|
202 |
+
|
203 |
+
$attrs = '';
|
204 |
+
|
205 |
+
foreach ($_attrs as $_attr)
|
206 |
+
$attrs .= $_attr['label'] . ': ' . $_attr['value'] . '<br />';
|
207 |
+
|
208 |
+
return substr($attrs, 0, -6);
|
209 |
+
}
|
210 |
+
|
211 |
+
protected function _prepareParams ($params) {
|
212 |
+
$defaults = array(
|
213 |
+
'images' => array(
|
214 |
+
'main' => array(
|
215 |
+
'width' => self::IMAGE_WIDTH,
|
216 |
+
'height' => self::IMAGE_HEIGHT
|
217 |
+
),
|
218 |
+
'thumb' => array(
|
219 |
+
'width' => self::THUMB_WIDTH,
|
220 |
+
'height' => self::THUMB_HEIGHT
|
221 |
+
)
|
222 |
+
)
|
223 |
+
);
|
224 |
+
|
225 |
+
$params['images'] = array_merge($defaults['images'], $params['images']);
|
226 |
+
$params = array_merge($defaults, $params);
|
227 |
+
|
228 |
+
$params['images']['content'] = $params['images']['main'];
|
229 |
+
$params['images']['thumbnail'] = $params['images']['thumb'];
|
230 |
+
|
231 |
+
unset($params['images']['main']);
|
232 |
+
unset($params['images']['thumb']);
|
233 |
+
|
234 |
+
return $params;
|
235 |
+
}
|
236 |
+
}
|
app/code/community/MVentory/Productivity/Model/Mage/Catalog/Category.php
ADDED
@@ -0,0 +1,110 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 model
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Model_Mage_Catalog_Category
|
23 |
+
extends Mage_Catalog_Model_Category {
|
24 |
+
|
25 |
+
const DISPLAY_DESCENDING_PRODUCTS
|
26 |
+
= 'catalog/frontend/display_descending_products';
|
27 |
+
|
28 |
+
const HIDE_EMPTY_CATEGORIES = 'catalog/navigation/hide_empty_categories';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Get category products collection
|
32 |
+
*
|
33 |
+
* The method is redefined to load all descending products when it's allowed
|
34 |
+
* and category is not anchor (anchor categories load descending products
|
35 |
+
* by default)
|
36 |
+
*
|
37 |
+
* @return Varien_Data_Collection_Db
|
38 |
+
*/
|
39 |
+
public function getProductCollection () {
|
40 |
+
if ($this->getIsAnchor()
|
41 |
+
|| !Mage::getStoreConfig(self::DISPLAY_DESCENDING_PRODUCTS))
|
42 |
+
return parent::getProductCollection();
|
43 |
+
|
44 |
+
return Mage::getResourceModel('catalog/product_collection')
|
45 |
+
->joinField('category_id',
|
46 |
+
'catalog/category_product',
|
47 |
+
'category_id',
|
48 |
+
'product_id = entity_id',
|
49 |
+
null,
|
50 |
+
'left')
|
51 |
+
->addAttributeToFilter('category_id',
|
52 |
+
array('in' => $this->getAllChildren(true)))
|
53 |
+
->setStoreId($this->getStoreId());
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Retrieve categories by parent
|
58 |
+
*
|
59 |
+
* The method is redefined to show categories with more
|
60 |
+
* then 1 subcategory only
|
61 |
+
*
|
62 |
+
* @param int $parent
|
63 |
+
* @param int $recursionLevel
|
64 |
+
* @param bool $sorted
|
65 |
+
* @param bool $asCollection
|
66 |
+
* @param bool $toLoad
|
67 |
+
* @return mixed
|
68 |
+
*/
|
69 |
+
public function getCategories($parent,
|
70 |
+
$recursionLevel = 0,
|
71 |
+
$sorted = false,
|
72 |
+
$asCollection = false,
|
73 |
+
$toLoad = true) {
|
74 |
+
|
75 |
+
$categories = parent::getCategories(
|
76 |
+
$parent,
|
77 |
+
$recursionLevel,
|
78 |
+
$sorted,
|
79 |
+
$asCollection,
|
80 |
+
$toLoad
|
81 |
+
);
|
82 |
+
|
83 |
+
return Mage::getStoreConfig(self::HIDE_EMPTY_CATEGORIES)
|
84 |
+
? $this->_removeParentCategories($categories)
|
85 |
+
: $categories;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Walk down categories tree and return first category with more
|
90 |
+
* than one sub-category
|
91 |
+
*
|
92 |
+
* @param int $parent
|
93 |
+
* @param int $recursionLevel
|
94 |
+
* @param bool $sorted
|
95 |
+
* @param bool $asCollection
|
96 |
+
* @param bool $toLoad
|
97 |
+
* @return mixed
|
98 |
+
*/
|
99 |
+
private function _removeParentCategories ($categories) {
|
100 |
+
if (count($nodes = $categories->getNodes()) != 1)
|
101 |
+
return $categories;
|
102 |
+
|
103 |
+
$children = end($nodes)->getChildren();
|
104 |
+
|
105 |
+
if (!count($children->getNodes()))
|
106 |
+
return $categories;
|
107 |
+
|
108 |
+
return $this->_removeParentCategories($children);
|
109 |
+
}
|
110 |
+
}
|
app/code/community/MVentory/Productivity/Model/Observer.php
ADDED
@@ -0,0 +1,184 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Event observers
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Model_Observer {
|
23 |
+
public function addCategoryFeed ($observer) {
|
24 |
+
$helper = Mage::helper('core/url');
|
25 |
+
|
26 |
+
$url = $helper->getCurrentUrl();
|
27 |
+
$url = $helper->addRequestParam($url, array('rss' => 1));
|
28 |
+
|
29 |
+
Mage::helper('productivity/rss')->addFeedToHeader($url);
|
30 |
+
}
|
31 |
+
|
32 |
+
public function addLatestProductsFeed ($observer) {
|
33 |
+
$helper = Mage::helper('productivity/rss');
|
34 |
+
|
35 |
+
$title = $helper->__('Latest products');
|
36 |
+
$url = Mage::getUrl('productivity/rss_product/latest');
|
37 |
+
|
38 |
+
$helper->addFeedToHeader($url, $title);
|
39 |
+
}
|
40 |
+
|
41 |
+
public function addTopCategoriesFeed ($observer) {
|
42 |
+
$helper = Mage::helper('productivity/rss');
|
43 |
+
|
44 |
+
$title = $helper->__('Top Categories');
|
45 |
+
$url = Mage::getUrl('catalog/category/top');
|
46 |
+
|
47 |
+
$helper->addFeedToHeader($url, $title);
|
48 |
+
}
|
49 |
+
|
50 |
+
public function showProductsWithoutSmallImagesOnly ($observer) {
|
51 |
+
$param = Mage::app()
|
52 |
+
->getRequest()
|
53 |
+
->getParam('without_images_only');
|
54 |
+
|
55 |
+
if ($param != 1)
|
56 |
+
return;
|
57 |
+
|
58 |
+
$collection = $observer->getCollection();
|
59 |
+
|
60 |
+
$select = $collection->getSelect();
|
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) {
|
74 |
+
if (Mage::registry('is_admin_logged') !== null)
|
75 |
+
return;
|
76 |
+
|
77 |
+
Mage::unregister('is_admin_logged');
|
78 |
+
Mage::register('is_admin_logged', false, true);
|
79 |
+
|
80 |
+
$session = Mage::getSingleton('core/session');
|
81 |
+
|
82 |
+
if ($session->getSessionSaveMethod() != 'files')
|
83 |
+
return;
|
84 |
+
|
85 |
+
$path = $session->getSessionSavePath()
|
86 |
+
. DS
|
87 |
+
. 'sess_'
|
88 |
+
. Mage::getSingleton('core/cookie')
|
89 |
+
->get(Mage_Adminhtml_Controller_Action::SESSION_NAMESPACE);
|
90 |
+
|
91 |
+
if (!(file_exists($path) && ($data = file_get_contents($path))))
|
92 |
+
return;
|
93 |
+
|
94 |
+
$data = $this->_parseSessionData($data);
|
95 |
+
|
96 |
+
if (!($data && isset($data['admin']['user'])))
|
97 |
+
return;
|
98 |
+
|
99 |
+
$user = $data['admin']['user'];
|
100 |
+
|
101 |
+
Mage::unregister('is_admin_logged');
|
102 |
+
Mage::register('is_admin_logged', $user->getId() > 0, true);
|
103 |
+
}
|
104 |
+
|
105 |
+
protected function _parseSessionData ($data) {
|
106 |
+
$original = $_SESSION;
|
107 |
+
|
108 |
+
if (!session_decode($data)) {
|
109 |
+
$_SESSION = $original;
|
110 |
+
|
111 |
+
return null;
|
112 |
+
}
|
113 |
+
|
114 |
+
$result = $_SESSION;
|
115 |
+
$_SESSION = $original;
|
116 |
+
|
117 |
+
return $result;
|
118 |
+
}
|
119 |
+
|
120 |
+
public function mergeAttributeOptions ($observer) {
|
121 |
+
$attr = $observer->getAttribute();
|
122 |
+
|
123 |
+
$code = $attr->getAttributeCode();
|
124 |
+
$option = $attr->getData('option');
|
125 |
+
|
126 |
+
if (!(isset($option['merge']['from']) && isset($option['merge']['to'])))
|
127 |
+
return;
|
128 |
+
|
129 |
+
$from = (int) $option['merge']['from'];
|
130 |
+
$to = (int) $option['merge']['to'];
|
131 |
+
|
132 |
+
$session = Mage::getSingleton('adminhtml/session');
|
133 |
+
$helper = Mage::helper('productivity');
|
134 |
+
|
135 |
+
if ($from == 0 || $to == 0 || $from == $to) {
|
136 |
+
$msg = 'Selecting new or similar options for merging are not allowed. '
|
137 |
+
. 'Please, select correct options';
|
138 |
+
|
139 |
+
$session->addError($helper->__($msg));
|
140 |
+
return;
|
141 |
+
}
|
142 |
+
|
143 |
+
$count = 0;
|
144 |
+
|
145 |
+
try {
|
146 |
+
$products = Mage::getResourceModel('catalog/product_collection')
|
147 |
+
->addAttributeToFilter($attr, array('finset' => $from));
|
148 |
+
|
149 |
+
foreach ($products as $product) {
|
150 |
+
$values = explode(',', $product->getData($code));
|
151 |
+
|
152 |
+
if (!$values)
|
153 |
+
continue;
|
154 |
+
|
155 |
+
$values = array_flip($values);
|
156 |
+
|
157 |
+
unset($values[$from]);
|
158 |
+
$values[$to] = '';
|
159 |
+
|
160 |
+
$product
|
161 |
+
->setData($code, implode(',', array_flip($values)))
|
162 |
+
->save();
|
163 |
+
|
164 |
+
$count++;
|
165 |
+
}
|
166 |
+
} catch (Exception $e) {
|
167 |
+
Mage::logException($e);
|
168 |
+
|
169 |
+
$msg = 'Merging of attribute options failed. Please, check logs '
|
170 |
+
. 'for additional info';
|
171 |
+
|
172 |
+
$session->addError($helper->__($msg));
|
173 |
+
|
174 |
+
return;
|
175 |
+
}
|
176 |
+
|
177 |
+
$option['delete'][$from] = true;
|
178 |
+
|
179 |
+
$attr->setData('option', $option);
|
180 |
+
|
181 |
+
$session->addSuccess($helper->__('Options were merged sucessfully.'));
|
182 |
+
$session->addSuccess($helper->__('Number of updated products: ') . $count);
|
183 |
+
}
|
184 |
+
}
|
app/code/community/MVentory/Productivity/Model/Widget/Attribute.php
ADDED
@@ -0,0 +1,163 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 source for attribute widget
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Model_Widget_Attribute {
|
23 |
+
|
24 |
+
//TODO: convert to singleton
|
25 |
+
|
26 |
+
const OPTIONS_ONLY_WITH_RESULTS
|
27 |
+
= Mage_Catalog_Model_Layer_Filter_Attribute::OPTIONS_ONLY_WITH_RESULTS;
|
28 |
+
|
29 |
+
protected $_attributeModel = null;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Load by attribute code
|
33 |
+
*
|
34 |
+
* @param string $code
|
35 |
+
*
|
36 |
+
* @return MVentory_Productivity_Model_Widget_Attribute
|
37 |
+
*/
|
38 |
+
public function loadByCode ($code) {
|
39 |
+
$attribute = Mage::getModel('eav/entity_attribute')
|
40 |
+
->loadByCode(Mage_Catalog_Model_Product::ENTITY, $code);
|
41 |
+
|
42 |
+
if ($attribute->getId() && $attribute->usesSource())
|
43 |
+
$this->_attributeModel = $attribute;
|
44 |
+
|
45 |
+
return $this;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Code is taken from
|
50 |
+
* Mage_Catalog_Model_Layer_Filter_Attribute::_getItemsData() method
|
51 |
+
*
|
52 |
+
* @return array|null
|
53 |
+
*/
|
54 |
+
public function getOptions () {
|
55 |
+
if (!$attribute = $this->_attributeModel)
|
56 |
+
return;
|
57 |
+
|
58 |
+
$store = Mage::app()->getStore();
|
59 |
+
$category = Mage::getModel('catalog/category')
|
60 |
+
->load($store->getRootCategoryId());
|
61 |
+
|
62 |
+
if (!$categoryId = $category->getId())
|
63 |
+
return;
|
64 |
+
|
65 |
+
$storeId = $store->getId();
|
66 |
+
$aggregator = Mage::getSingleton('catalogindex/aggregation');
|
67 |
+
|
68 |
+
$key = 'STORE_' . $storeId
|
69 |
+
. '_CAT_' . $categoryId
|
70 |
+
. '_CUSTGROUP_'
|
71 |
+
. Mage::getSingleton('customer/session')->getCustomerGroupId()
|
72 |
+
. '_' . $attribute->getAttributeCode();
|
73 |
+
|
74 |
+
if ($data = $aggregator->getCacheData($key))
|
75 |
+
return $data;
|
76 |
+
|
77 |
+
$options = $attribute->getFrontend()->getSelectOptions();
|
78 |
+
|
79 |
+
//Fake 'filter' model with required fields for
|
80 |
+
//Mage_Catalog_Model_Resource_Layer_Filter_Attribute::getCount() method
|
81 |
+
$object = new Varien_Object(array(
|
82 |
+
'layer' => new Varien_Object(array(
|
83 |
+
'product_collection' => $this->_getProductCollection($category)
|
84 |
+
)),
|
85 |
+
'attribute_model' => $attribute,
|
86 |
+
'store_id' => $storeId
|
87 |
+
));
|
88 |
+
|
89 |
+
$optionsCount = Mage::getResourceModel('catalog/layer_filter_attribute')
|
90 |
+
->getCount($object);
|
91 |
+
|
92 |
+
$helper = Mage::helper('core/string');
|
93 |
+
$onlyWithResult = $attribute->getIsFilterable()
|
94 |
+
== self::OPTIONS_ONLY_WITH_RESULTS;
|
95 |
+
|
96 |
+
$data = array();
|
97 |
+
|
98 |
+
foreach ($options as $option) {
|
99 |
+
if (is_array($option['value']))
|
100 |
+
continue;
|
101 |
+
|
102 |
+
if ($onlyWithResult && empty($optionsCount[$option['value']]))
|
103 |
+
continue;
|
104 |
+
|
105 |
+
if (!$helper->strlen($option['value']))
|
106 |
+
continue;
|
107 |
+
|
108 |
+
//Ignore 'n/a', 'n-a', 'n\a' and 'na' values
|
109 |
+
//Note: case insensitive comparing; delimeter can be surrounded
|
110 |
+
// with spaces
|
111 |
+
if (preg_match('#^n(\s*[/-\\\\]\s*)?a$#i', trim($option['label'])))
|
112 |
+
continue;
|
113 |
+
|
114 |
+
$data[] = $option;
|
115 |
+
}
|
116 |
+
|
117 |
+
$tags = array(
|
118 |
+
Mage_Eav_Model_Entity_Attribute::CACHE_TAG . ':' . $attribute->getId(),
|
119 |
+
Mage_Catalog_Model_Category::CACHE_TAG . $categoryId
|
120 |
+
);
|
121 |
+
|
122 |
+
$aggregator->saveCacheData($data, $key, $tags);
|
123 |
+
|
124 |
+
return $data;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Initialise product collection from the category
|
129 |
+
*
|
130 |
+
* Code is taken from Mage_Catalog_Model_Layer::prepareProductCollection()
|
131 |
+
* method
|
132 |
+
*
|
133 |
+
* @param Mage_Catalog_Model_Category $category
|
134 |
+
*
|
135 |
+
* @return Mage_Catalog_Model_Resource_Product_Collection
|
136 |
+
*/
|
137 |
+
protected function _getProductCollection ($category) {
|
138 |
+
$productAttributes = Mage::getSingleton('catalog/config')
|
139 |
+
->getProductAttributes();
|
140 |
+
|
141 |
+
$collection = $category
|
142 |
+
->getProductCollection()
|
143 |
+
->addAttributeToSelect($productAttributes)
|
144 |
+
->addMinimalPrice()
|
145 |
+
->addFinalPrice()
|
146 |
+
->addTaxPercents()
|
147 |
+
->addUrlRewrite($category->getId());
|
148 |
+
|
149 |
+
Mage::getSingleton('catalog/product_status')
|
150 |
+
->addVisibleFilterToCollection($collection);
|
151 |
+
|
152 |
+
Mage::getSingleton('catalog/product_visibility')
|
153 |
+
->addVisibleInCatalogFilterToCollection($collection);
|
154 |
+
|
155 |
+
//Dispatch the event to emul;ate loading collection of products in catalog
|
156 |
+
Mage::dispatchEvent(
|
157 |
+
'catalog_block_product_list_collection',
|
158 |
+
array('collection' => $collection)
|
159 |
+
);
|
160 |
+
|
161 |
+
return $collection;
|
162 |
+
}
|
163 |
+
}
|
app/code/community/MVentory/Productivity/controllers/Adminhtml/IndexController.php
ADDED
@@ -0,0 +1,38 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Controller to open CMS page editor from the frontend
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author <anemets1@gmail.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action
|
23 |
+
{
|
24 |
+
public function preDispatch()
|
25 |
+
{
|
26 |
+
if ($this->getRequest()->getActionName() == 'index') Mage::getSingleton('adminhtml/url')->turnOffSecretKey();
|
27 |
+
parent::preDispatch();
|
28 |
+
}
|
29 |
+
|
30 |
+
public function indexAction()
|
31 |
+
{
|
32 |
+
$page_id = $this->getRequest()->getParam('page_id');
|
33 |
+
|
34 |
+
$this->getResponse()->setRedirect(Mage::helper("adminhtml")->getUrl("adminhtml/cms_page/edit",array("page_id"=>$page_id)));
|
35 |
+
return;
|
36 |
+
}
|
37 |
+
|
38 |
+
}
|
app/code/community/MVentory/Productivity/controllers/CategoryController.php
ADDED
@@ -0,0 +1,228 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 controller
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author <anemets1@gmail.com>
|
21 |
+
*/
|
22 |
+
require_once("Mage/Catalog/controllers/CategoryController.php");
|
23 |
+
class MVentory_Productivity_CategoryController extends Mage_Catalog_CategoryController
|
24 |
+
{
|
25 |
+
protected $_mediaNamespace = 'http://search.yahoo.com/mrss/';
|
26 |
+
protected $_rssGetVariable = 'rss';
|
27 |
+
protected $_thumbnailSizeGetVariable = 'thumbnail_size';
|
28 |
+
protected $_fullImageSizeGetVariable = 'fullimage_size';
|
29 |
+
|
30 |
+
private function removeqsvar($url, $varname) {
|
31 |
+
list($urlpart, $qspart) = array_pad(explode('?', $url), 2, '');
|
32 |
+
parse_str($qspart, $qsvars);
|
33 |
+
unset($qsvars[$varname]);
|
34 |
+
$newqs = http_build_query($qsvars);
|
35 |
+
return $urlpart . (strlen($newqs)>0?('?'.$newqs):"");
|
36 |
+
}
|
37 |
+
|
38 |
+
/* Get a url pointing to the normal version of the products list page (not the rss one) */
|
39 |
+
private function getNoRssUrl()
|
40 |
+
{
|
41 |
+
$currentUrl = Mage::helper('core/url')->getCurrentUrl();
|
42 |
+
|
43 |
+
$result = $this->removeqsvar($currentUrl, $this->_rssGetVariable);
|
44 |
+
$result = $this->removeqsvar($result, $this->_thumbnailSizeGetVariable);
|
45 |
+
$result = $this->removeqsvar($result, $this->_fullImageSizeGetVariable);
|
46 |
+
|
47 |
+
return $result;
|
48 |
+
}
|
49 |
+
|
50 |
+
public function topAction()
|
51 |
+
{
|
52 |
+
$categoryModel = Mage::getModel('catalog/category');
|
53 |
+
$list = Mage::helper('catalog/category')->getStoreCategories();
|
54 |
+
|
55 |
+
$rssXml = new SimpleXMLElement('<rss/>');
|
56 |
+
$rssXml->addAttribute('version', '2.0');
|
57 |
+
|
58 |
+
$pubDate = date("D, d M o G:i:s T",time());
|
59 |
+
|
60 |
+
$channel = $rssXml->addChild('channel');
|
61 |
+
$channel->title = "Top categories per store";
|
62 |
+
$channel->addChild("description");
|
63 |
+
$channel->pubDate = $pubDate;
|
64 |
+
$channel->lastBuildDate = $pubDate;
|
65 |
+
$channel->generator = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
|
66 |
+
|
67 |
+
foreach ($list as $cat)
|
68 |
+
{
|
69 |
+
$url = $categoryModel->setData($cat->getData())->getUrl();
|
70 |
+
|
71 |
+
$item = $channel->addChild('item');
|
72 |
+
$item->title = $cat->getName();
|
73 |
+
$item->link = $url;
|
74 |
+
}
|
75 |
+
|
76 |
+
$helper = Mage::helper('productivity/rss');
|
77 |
+
|
78 |
+
$this->getResponse()->setBody($helper->formatXml($rssXml->asXML()));
|
79 |
+
|
80 |
+
$apiConfigCharset = Mage::getStoreConfig("api/config/charset");
|
81 |
+
$this->getResponse()->setHeader('Content-Type','application/rss+xml; charset='.$apiConfigCharset);
|
82 |
+
}
|
83 |
+
|
84 |
+
public function viewAction ($categoryId = null) {
|
85 |
+
$this->_viewAction($categoryId);
|
86 |
+
|
87 |
+
$request = $this->getRequest();
|
88 |
+
|
89 |
+
if ($request->getParam($this->_rssGetVariable, 0) != 1)
|
90 |
+
return;
|
91 |
+
|
92 |
+
if (($asJson = (bool) $request->getParam('json', false))
|
93 |
+
&& (!$callback = $request->getParam('callback')))
|
94 |
+
return;
|
95 |
+
|
96 |
+
$layout = $this->getLayout();
|
97 |
+
|
98 |
+
$data = array(
|
99 |
+
'title' => $layout
|
100 |
+
->getBlock('head')
|
101 |
+
->getTitle(),
|
102 |
+
'link' => $this->getNoRssUrl(),
|
103 |
+
'images' => array()
|
104 |
+
);
|
105 |
+
|
106 |
+
$map = array(
|
107 |
+
'main' => 'fullimage_size',
|
108 |
+
'thumb' => 'thumbnail_size'
|
109 |
+
);
|
110 |
+
|
111 |
+
foreach ($map as $key => $param) {
|
112 |
+
if (!$request->has($param))
|
113 |
+
continue;
|
114 |
+
|
115 |
+
$size = $request->getParam($param);
|
116 |
+
|
117 |
+
if ($size == 'full') {
|
118 |
+
$data['images'][$key] = array();
|
119 |
+
|
120 |
+
continue;
|
121 |
+
}
|
122 |
+
|
123 |
+
$wh = explode('x', $size);
|
124 |
+
|
125 |
+
if (count($wh) == 2) {
|
126 |
+
$data['images'][$key] = array(
|
127 |
+
'width' => is_numeric($wh[0]) ? (int) $wh[0] : null,
|
128 |
+
'height' => is_numeric($wh[1]) ? (int) $wh[1] : null
|
129 |
+
);
|
130 |
+
|
131 |
+
continue;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
$collection = $layout
|
136 |
+
->getBlock("product_list")
|
137 |
+
->getLoadedProductCollection();
|
138 |
+
|
139 |
+
$helper = Mage::helper('productivity/rss')->setLayout($layout);
|
140 |
+
|
141 |
+
$response = $this
|
142 |
+
->getResponse()
|
143 |
+
->setBody(
|
144 |
+
$asJson
|
145 |
+
? $callback . '(' . $helper->asJson($collection, $data) . ');'
|
146 |
+
: $helper->generateFeedForProducts($collection, $data)
|
147 |
+
);
|
148 |
+
|
149 |
+
$charset = Mage::getStoreConfig("api/config/charset");
|
150 |
+
$type = $asJson ? 'text/javascript' : 'application/rss+xml';
|
151 |
+
|
152 |
+
$response->setHeader('Content-Type', $type . '; charset=' . $charset);
|
153 |
+
}
|
154 |
+
|
155 |
+
public function allAction () {
|
156 |
+
return $this->viewAction(Mage::app()->getStore()->getRootCategoryId());
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Category view action
|
161 |
+
*
|
162 |
+
* The method is redefined to allow passing category ID
|
163 |
+
* via function parameters
|
164 |
+
*/
|
165 |
+
private function _viewAction ($categoryId = null) {
|
166 |
+
$categoryId = (int) $categoryId;
|
167 |
+
|
168 |
+
if ($categoryId)
|
169 |
+
$this->getRequest()->setParam('id', $categoryId);
|
170 |
+
|
171 |
+
if (!$category = $this->_initCatagory()) {
|
172 |
+
if (!$this->getResponse()->isRedirect())
|
173 |
+
$this->_forward('noRoute');
|
174 |
+
|
175 |
+
return;
|
176 |
+
}
|
177 |
+
|
178 |
+
$categoryId = $category->getId();
|
179 |
+
|
180 |
+
$design = Mage::getSingleton('catalog/design');
|
181 |
+
$settings = $design->getDesignSettings($category);
|
182 |
+
|
183 |
+
//Apply custom design
|
184 |
+
if ($customDesign = $settings->getCustomDesign())
|
185 |
+
$design->applyCustomDesign($customDesign);
|
186 |
+
|
187 |
+
Mage::getSingleton('catalog/session')->setLastViewedCategoryId($categoryId);
|
188 |
+
|
189 |
+
$layout = $this->getLayout();
|
190 |
+
|
191 |
+
$update = $layout->getUpdate();
|
192 |
+
$update->addHandle('default');
|
193 |
+
|
194 |
+
if (!$category->hasChildren())
|
195 |
+
$update->addHandle('catalog_category_layered_nochildren');
|
196 |
+
|
197 |
+
$this->addActionLayoutHandles();
|
198 |
+
$update->addHandle($category->getLayoutUpdateHandle());
|
199 |
+
$update->addHandle('CATEGORY_' . $categoryId);
|
200 |
+
|
201 |
+
$this->loadLayoutUpdates();
|
202 |
+
|
203 |
+
//Apply custom layout update once layout is loaded
|
204 |
+
$layoutUpdates = $settings->getLayoutUpdates();
|
205 |
+
|
206 |
+
if ($layoutUpdates && is_array($layoutUpdates))
|
207 |
+
foreach($layoutUpdates as $layoutUpdate)
|
208 |
+
$update->addUpdate($layoutUpdate);
|
209 |
+
|
210 |
+
$this->generateLayoutXml()->generateLayoutBlocks();
|
211 |
+
|
212 |
+
//Apply custom layout (page) template once the blocks are generated
|
213 |
+
if ($pageLayout = $settings->getPageLayout()) {
|
214 |
+
$layout->helper('page/layout')->applyTemplate($pageLayout);
|
215 |
+
}
|
216 |
+
|
217 |
+
if ($root = $layout->getBlock('root'))
|
218 |
+
$root
|
219 |
+
->addBodyClass('categorypath-' . $category->getUrlPath())
|
220 |
+
->addBodyClass('category-' . $category->getUrlKey());
|
221 |
+
|
222 |
+
$this->_initLayoutMessages('catalog/session');
|
223 |
+
$this->_initLayoutMessages('checkout/session');
|
224 |
+
|
225 |
+
$this->renderLayout();
|
226 |
+
}
|
227 |
+
}
|
228 |
+
|
app/code/community/MVentory/Productivity/controllers/FeedController.php
ADDED
@@ -0,0 +1,38 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Feed controller
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_FeedController
|
23 |
+
extends Mage_Core_Controller_Front_Action {
|
24 |
+
|
25 |
+
public function updateAction () {
|
26 |
+
$request = $this->getRequest();
|
27 |
+
|
28 |
+
if (!$url = $request->getParam('url'))
|
29 |
+
return;
|
30 |
+
|
31 |
+
Mage::app()->cleanCache(md5($url));
|
32 |
+
|
33 |
+
$subject = 'WP page was updated';
|
34 |
+
$body = 'URL: ' . $url;
|
35 |
+
|
36 |
+
Mage::helper('productivity')->sendEmail($subject, $body);
|
37 |
+
}
|
38 |
+
}
|
app/code/community/MVentory/Productivity/controllers/ImageController.php
ADDED
@@ -0,0 +1,283 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Image controller
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_ImageController
|
23 |
+
extends Mage_Core_Controller_Front_Action {
|
24 |
+
|
25 |
+
const ATTRIBUTE_CODE = 'media_gallery';
|
26 |
+
|
27 |
+
public function preDispatch () {
|
28 |
+
parent::preDispatch();
|
29 |
+
|
30 |
+
Mage::getModel('productivity/observer')->rememberAdminState(null);
|
31 |
+
}
|
32 |
+
|
33 |
+
public function rotateAction () {
|
34 |
+
$helper = Mage::helper('productivity');
|
35 |
+
|
36 |
+
if (!$helper->isReviewerLogged())
|
37 |
+
return $this->_error();
|
38 |
+
|
39 |
+
$request = $this->getRequest();
|
40 |
+
|
41 |
+
if (!$request->has('params'))
|
42 |
+
return $this->_error();
|
43 |
+
|
44 |
+
$params = $request->get('params');
|
45 |
+
|
46 |
+
$angels = array('left' => 90, 'right' => -90);
|
47 |
+
|
48 |
+
$hasRequiredValues = $params['file']
|
49 |
+
&& array_key_exists($params['rotate'], $angels);
|
50 |
+
|
51 |
+
if (!$hasRequiredValues)
|
52 |
+
return $this->_error();
|
53 |
+
|
54 |
+
if (!$product = $this->_getProduct($request->getParam('productId')))
|
55 |
+
return $this->_error();
|
56 |
+
|
57 |
+
//Export $file, $width, $height and $rotate variables
|
58 |
+
extract($params);
|
59 |
+
|
60 |
+
unset($params);
|
61 |
+
|
62 |
+
try {
|
63 |
+
// rotate image and get new file
|
64 |
+
$newFileAbsolute = $helper->rotate($file, $angels[$rotate]);
|
65 |
+
} catch (Exception $e) {
|
66 |
+
Mage::logException($e);
|
67 |
+
return $this->_error();
|
68 |
+
}
|
69 |
+
|
70 |
+
$type = $request->get('thumb') == 'true'?'thumbnail':'image';
|
71 |
+
|
72 |
+
$result = array();
|
73 |
+
|
74 |
+
try {
|
75 |
+
//Update product image and get new base filename
|
76 |
+
$result['file'] = $helper->updateImageInGallery(
|
77 |
+
$file,
|
78 |
+
$newFileAbsolute,
|
79 |
+
$product,
|
80 |
+
$type == 'image' ? array('image', 'small_image', 'thumbnail') : null
|
81 |
+
);
|
82 |
+
} catch (Exception $e) {
|
83 |
+
Mage::logException($e);
|
84 |
+
return $this->_error();
|
85 |
+
}
|
86 |
+
|
87 |
+
// get resized version of image
|
88 |
+
$result['url'] = $this->_getImageUrl(
|
89 |
+
$product,
|
90 |
+
$type,
|
91 |
+
$result['file'],
|
92 |
+
$width ? $width : null,
|
93 |
+
$height ? $height : null
|
94 |
+
);
|
95 |
+
|
96 |
+
$this->_success($result);
|
97 |
+
}
|
98 |
+
|
99 |
+
public function removeAction () {
|
100 |
+
$helper = Mage::helper('productivity');
|
101 |
+
|
102 |
+
if (!$helper->isReviewerLogged())
|
103 |
+
return $this->_error();
|
104 |
+
|
105 |
+
$request = $this->getRequest();
|
106 |
+
|
107 |
+
if (!$request->has('params'))
|
108 |
+
return $this->_error();
|
109 |
+
|
110 |
+
$params = $request->get('params');
|
111 |
+
|
112 |
+
if (!$params['file'])
|
113 |
+
return $this->_error();
|
114 |
+
|
115 |
+
if (!$product = $this->_getProduct($request->getParam('product')))
|
116 |
+
return $this->_error();
|
117 |
+
|
118 |
+
//Export $file, $width and $height variables
|
119 |
+
extract($params);
|
120 |
+
|
121 |
+
unset($params);
|
122 |
+
|
123 |
+
try {
|
124 |
+
$helper->remove($file, $product);
|
125 |
+
} catch (Exception $e) {
|
126 |
+
Mage::logException($e);
|
127 |
+
return $this->_error();
|
128 |
+
}
|
129 |
+
|
130 |
+
$data = array();
|
131 |
+
|
132 |
+
if($request->get('thumb') != 'true') {
|
133 |
+
$data['url'] = $this->_getImageUrl(
|
134 |
+
$product,
|
135 |
+
'image',
|
136 |
+
null,
|
137 |
+
$width ? $width : null,
|
138 |
+
$height ? $height : null
|
139 |
+
);
|
140 |
+
}
|
141 |
+
|
142 |
+
$this->_success($data);
|
143 |
+
}
|
144 |
+
|
145 |
+
public function setmainAction () {
|
146 |
+
$helper = Mage::helper('productivity');
|
147 |
+
|
148 |
+
if (!$helper->isReviewerLogged())
|
149 |
+
return $this->_error();
|
150 |
+
|
151 |
+
$request = $this->getRequest();
|
152 |
+
|
153 |
+
$hasRequiredParam = $request->has('params')
|
154 |
+
&& $request->has('main_image_params');
|
155 |
+
|
156 |
+
if (!$hasRequiredParam)
|
157 |
+
return $this->_error();
|
158 |
+
|
159 |
+
$thumb = $request->get('params');
|
160 |
+
$image = $request->get('main_image_params');
|
161 |
+
|
162 |
+
$hasRequiredValues = $thumb['file'] && $image['file'];
|
163 |
+
|
164 |
+
if (!$hasRequiredValues)
|
165 |
+
return $this->_error();
|
166 |
+
|
167 |
+
if (!$product = $this->_getProduct($request->getParam('product')))
|
168 |
+
return $this->_error();
|
169 |
+
|
170 |
+
try {
|
171 |
+
$helper->setMainImage($thumb['file'], $product);
|
172 |
+
} catch (Exception $e) {
|
173 |
+
Mage::logException($e);
|
174 |
+
return $this->_error();
|
175 |
+
}
|
176 |
+
|
177 |
+
$result = array(
|
178 |
+
'image' => array(
|
179 |
+
'file' => $thumb['file'],
|
180 |
+
'url' => $this->_getImageUrl(
|
181 |
+
$product,
|
182 |
+
'image',
|
183 |
+
$thumb['file'],
|
184 |
+
$image['width'] ? $image['width'] : null,
|
185 |
+
$image['height'] ? $image['height'] : null
|
186 |
+
)
|
187 |
+
),
|
188 |
+
'thumbnail' => array(
|
189 |
+
'file' => $image['file'],
|
190 |
+
'url' => $this->_getImageUrl(
|
191 |
+
$product,
|
192 |
+
'thumbnail',
|
193 |
+
$image['file'],
|
194 |
+
$thumb['width'] ? $thumb['width'] : null,
|
195 |
+
$thumb['height'] ? $thumb['height'] : null
|
196 |
+
)
|
197 |
+
)
|
198 |
+
);
|
199 |
+
|
200 |
+
$this->_success($result);
|
201 |
+
}
|
202 |
+
|
203 |
+
public function uploadAction () {
|
204 |
+
$helper = Mage::helper('productivity');
|
205 |
+
|
206 |
+
if (!$helper->isReviewerLogged())
|
207 |
+
return $this->_error();
|
208 |
+
|
209 |
+
if (!isset($_FILES['qqfile']))
|
210 |
+
return $this->_error();
|
211 |
+
|
212 |
+
if (!$product
|
213 |
+
= $this->_getProduct($this->getRequest()->getParam('product_id')))
|
214 |
+
return $this->_error();
|
215 |
+
|
216 |
+
$uploader = new Mage_Core_Model_File_Uploader('qqfile');
|
217 |
+
|
218 |
+
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
|
219 |
+
$uploader->addValidateCallback(
|
220 |
+
'catalog_product_image',
|
221 |
+
Mage::helper('catalog/image'),
|
222 |
+
'validateUploadFile'
|
223 |
+
);
|
224 |
+
$uploader->setAllowRenameFiles(true);
|
225 |
+
$uploader->setFilesDispersion(true);
|
226 |
+
|
227 |
+
$result = $uploader->save(
|
228 |
+
Mage::getSingleton('catalog/product_media_config')
|
229 |
+
->getBaseTmpMediaPath()
|
230 |
+
);
|
231 |
+
|
232 |
+
Mage::dispatchEvent(
|
233 |
+
'catalog_product_gallery_upload_image_after',
|
234 |
+
array(
|
235 |
+
'result' => $result,
|
236 |
+
'action' => $this
|
237 |
+
)
|
238 |
+
);
|
239 |
+
|
240 |
+
try {
|
241 |
+
$file = $helper->add($product, $result);
|
242 |
+
} catch (Exception $e) {
|
243 |
+
Mage::logException($e);
|
244 |
+
return $this->_error();
|
245 |
+
}
|
246 |
+
|
247 |
+
$this->_success(array('file' => $file));
|
248 |
+
}
|
249 |
+
|
250 |
+
private function _getProduct ($id) {
|
251 |
+
if (($id = (int) $id) < 1)
|
252 |
+
return;
|
253 |
+
|
254 |
+
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
|
255 |
+
|
256 |
+
$product = Mage::getModel('catalog/product')->load($id);
|
257 |
+
|
258 |
+
return $product->getId() ? $product : null;
|
259 |
+
}
|
260 |
+
|
261 |
+
private function _getImageUrl ($product,
|
262 |
+
$type = 'image',
|
263 |
+
$file = null,
|
264 |
+
$width = null,
|
265 |
+
$height = null) {
|
266 |
+
|
267 |
+
return Mage::helper('catalog/image')
|
268 |
+
->init($product, $type, $file)
|
269 |
+
->resize($width, $height)
|
270 |
+
->__toString();
|
271 |
+
}
|
272 |
+
|
273 |
+
private function _success ($data = null) {
|
274 |
+
echo Mage::helper('core')->jsonEncode(array(
|
275 |
+
'success' => true,
|
276 |
+
'data' => $data
|
277 |
+
));
|
278 |
+
}
|
279 |
+
|
280 |
+
private function _error () {
|
281 |
+
echo Mage::helper('core')->jsonEncode(array('success' => false));
|
282 |
+
}
|
283 |
+
}
|
app/code/community/MVentory/Productivity/controllers/ProductController.php
ADDED
@@ -0,0 +1,85 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
require_once 'Mage/Adminhtml/controllers/Catalog/ProductController.php';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Product controller
|
20 |
+
*
|
21 |
+
* @package MVentory/Productivity
|
22 |
+
* @author <daniel@clockworkgeek.com>
|
23 |
+
*/
|
24 |
+
class MVentory_Productivity_ProductController extends Mage_Core_Controller_Front_Action
|
25 |
+
{
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Save new product details then redirect to product page.
|
29 |
+
* Reviewer will see the page refresh.
|
30 |
+
*/
|
31 |
+
public function saveAction() {
|
32 |
+
$request = $this->getRequest();
|
33 |
+
|
34 |
+
// URL parameter
|
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 |
+
// Product saves must be made from admin store
|
43 |
+
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
|
44 |
+
|
45 |
+
//Don't set store ID to product because it has to be saved
|
46 |
+
//in a global scope
|
47 |
+
$product = Mage::getModel('catalog/product')->load($productId);
|
48 |
+
|
49 |
+
// Only allow certain attributes to be set, if missing product will not be changed.
|
50 |
+
$data = array_intersect_key(
|
51 |
+
$request->getPost(),
|
52 |
+
$helper->getVisibleAttributes($product)
|
53 |
+
);
|
54 |
+
if (isset($data['description'])) {
|
55 |
+
$data['short_description'] = $data['description'];
|
56 |
+
}
|
57 |
+
|
58 |
+
if ($product->getTypeId() != 'configurable') {
|
59 |
+
$qty = (float) $request->getParam('qty');
|
60 |
+
|
61 |
+
$data['stock_data'] = array(
|
62 |
+
'qty'
|
63 |
+
=> $qty < Mage_Adminhtml_Catalog_ProductController::MAX_QTY_VALUE
|
64 |
+
? $qty
|
65 |
+
: Mage_Adminhtml_Catalog_ProductController::MAX_QTY_VALUE,
|
66 |
+
'is_in_stock'
|
67 |
+
=> $qty > 0
|
68 |
+
? Mage_CatalogInventory_Model_Stock_Status::STATUS_IN_STOCK
|
69 |
+
: Mage_CatalogInventory_Model_Stock_Status::STATUS_OUT_OF_STOCK
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
$product->addData($data)
|
74 |
+
->save();
|
75 |
+
|
76 |
+
// Reset store to be neat
|
77 |
+
Mage::app()->setCurrentStore($storeId);
|
78 |
+
}
|
79 |
+
|
80 |
+
// Always show same page, even if nothing has changed
|
81 |
+
$this->_redirectUrl($product->setData('url', null)->getProductUrl());
|
82 |
+
}
|
83 |
+
|
84 |
+
}
|
85 |
+
|
app/code/community/MVentory/Productivity/controllers/Rss/ProductController.php
ADDED
@@ -0,0 +1,33 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* RSS controller
|
18 |
+
*
|
19 |
+
* @package MVentory/Productivity
|
20 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
21 |
+
*/
|
22 |
+
class MVentory_Productivity_Rss_ProductController
|
23 |
+
extends Mage_Core_Controller_Front_Action {
|
24 |
+
|
25 |
+
public function latestAction () {
|
26 |
+
$this
|
27 |
+
->getResponse()
|
28 |
+
->setHeader('Content-type', 'application/rss+xml; charset=UTF-8');
|
29 |
+
|
30 |
+
$this->loadLayout(false);
|
31 |
+
$this->renderLayout();
|
32 |
+
}
|
33 |
+
}
|
app/code/community/MVentory/Productivity/etc/config.xml
ADDED
@@ -0,0 +1,195 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<!--
|
4 |
+
/**
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
*
|
12 |
+
* @package MVentory/Productivity
|
13 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
14 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
15 |
+
*/
|
16 |
+
-->
|
17 |
+
|
18 |
+
<config>
|
19 |
+
<modules>
|
20 |
+
<MVentory_Productivity>
|
21 |
+
<version>0</version>
|
22 |
+
</MVentory_Productivity>
|
23 |
+
</modules>
|
24 |
+
|
25 |
+
<global>
|
26 |
+
<blocks>
|
27 |
+
<productivity>
|
28 |
+
<class>MVentory_Productivity_Block</class>
|
29 |
+
</productivity>
|
30 |
+
|
31 |
+
<page>
|
32 |
+
<rewrite>
|
33 |
+
<html_breadcrumbs>MVentory_Productivity_Block_Mage_Page_Html_Breadcrumbs</html_breadcrumbs>
|
34 |
+
</rewrite>
|
35 |
+
</page>
|
36 |
+
|
37 |
+
<catalog>
|
38 |
+
<rewrite>
|
39 |
+
<product_view>MVentory_Productivity_Block_Product_View</product_view>
|
40 |
+
</rewrite>
|
41 |
+
</catalog>
|
42 |
+
|
43 |
+
<adminhtml>
|
44 |
+
<rewrite>
|
45 |
+
<catalog_product_attribute_edit_tab_options>MVentory_Productivity_Block_Catalog_Product_Attribute_Edit_Tab_Options</catalog_product_attribute_edit_tab_options>
|
46 |
+
</rewrite>
|
47 |
+
</adminhtml>
|
48 |
+
</blocks>
|
49 |
+
|
50 |
+
<helpers>
|
51 |
+
<productivity>
|
52 |
+
<class>MVentory_Productivity_Helper</class>
|
53 |
+
</productivity>
|
54 |
+
|
55 |
+
<catalog>
|
56 |
+
<rewrite>
|
57 |
+
<category>MVentory_Productivity_Helper_Mage_Catalog_Category</category>
|
58 |
+
</rewrite>
|
59 |
+
</catalog>
|
60 |
+
</helpers>
|
61 |
+
|
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>
|
71 |
+
</rewrite>
|
72 |
+
</catalog>
|
73 |
+
</models>
|
74 |
+
</global>
|
75 |
+
|
76 |
+
<frontend>
|
77 |
+
<layout>
|
78 |
+
<updates>
|
79 |
+
<productivity>
|
80 |
+
<file>productivity.xml</file>
|
81 |
+
</productivity>
|
82 |
+
</updates>
|
83 |
+
</layout>
|
84 |
+
|
85 |
+
<routers>
|
86 |
+
<productivity>
|
87 |
+
<use>standard</use>
|
88 |
+
<args>
|
89 |
+
<module>MVentory_Productivity</module>
|
90 |
+
<frontName>productivity</frontName>
|
91 |
+
</args>
|
92 |
+
</productivity>
|
93 |
+
|
94 |
+
<catalog>
|
95 |
+
<args>
|
96 |
+
<modules>
|
97 |
+
<MVentory_Productivity before="Mage_Catalog">MVentory_Productivity</MVentory_Productivity>
|
98 |
+
</modules>
|
99 |
+
</args>
|
100 |
+
</catalog>
|
101 |
+
</routers>
|
102 |
+
|
103 |
+
<events>
|
104 |
+
<controller_action_layout_render_before_catalog_category_view>
|
105 |
+
<observers>
|
106 |
+
<productivity_add_category_feed>
|
107 |
+
<type>singleton</type>
|
108 |
+
<class>MVentory_Productivity_Model_Observer</class>
|
109 |
+
<method>addCategoryFeed</method>
|
110 |
+
</productivity_add_category_feed>
|
111 |
+
</observers>
|
112 |
+
</controller_action_layout_render_before_catalog_category_view>
|
113 |
+
|
114 |
+
<controller_action_layout_render_before_cms_index_index>
|
115 |
+
<observers>
|
116 |
+
<productivity_add_latest__product_feed>
|
117 |
+
<type>singleton</type>
|
118 |
+
<class>MVentory_Productivity_Model_Observer</class>
|
119 |
+
<method>addLatestProductsFeed</method>
|
120 |
+
</productivity_add_latest__product_feed>
|
121 |
+
|
122 |
+
<productivity_add_top_categories_feed>
|
123 |
+
<type>singleton</type>
|
124 |
+
<class>MVentory_Productivity_Model_Observer</class>
|
125 |
+
<method>addTopCategoriesFeed</method>
|
126 |
+
</productivity_add_top_categories_feed>
|
127 |
+
</observers>
|
128 |
+
</controller_action_layout_render_before_cms_index_index>
|
129 |
+
|
130 |
+
<controller_action_predispatch_catalog>
|
131 |
+
<observers>
|
132 |
+
<productivity_remember_admin_state>
|
133 |
+
<type>singleton</type>
|
134 |
+
<class>MVentory_Productivity_Model_Observer</class>
|
135 |
+
<method>rememberAdminState</method>
|
136 |
+
</productivity_remember_admin_state>
|
137 |
+
</observers>
|
138 |
+
</controller_action_predispatch_catalog>
|
139 |
+
|
140 |
+
<controller_action_predispatch_cms>
|
141 |
+
<observers>
|
142 |
+
<productivity_remember_admin_state>
|
143 |
+
<type>singleton</type>
|
144 |
+
<class>MVentory_Productivity_Model_Observer</class>
|
145 |
+
<method>rememberAdminState</method>
|
146 |
+
</productivity_remember_admin_state>
|
147 |
+
</observers>
|
148 |
+
</controller_action_predispatch_cms>
|
149 |
+
|
150 |
+
<catalog_block_product_list_collection>
|
151 |
+
<observers>
|
152 |
+
<productivity_show_products_without_small_image_only>
|
153 |
+
<type>singleton</type>
|
154 |
+
<class>MVentory_Productivity_Model_Observer</class>
|
155 |
+
<method>showProductsWithoutSmallImagesOnly</method>
|
156 |
+
</productivity_show_products_without_small_image_only>
|
157 |
+
</observers>
|
158 |
+
</catalog_block_product_list_collection>
|
159 |
+
</events>
|
160 |
+
</frontend>
|
161 |
+
|
162 |
+
<admin>
|
163 |
+
<routers>
|
164 |
+
<productivity>
|
165 |
+
<use>admin</use>
|
166 |
+
<args>
|
167 |
+
<module>MVentory_Productivity</module>
|
168 |
+
<frontName>productivity_admin</frontName>
|
169 |
+
</args>
|
170 |
+
</productivity>
|
171 |
+
</routers>
|
172 |
+
</admin>
|
173 |
+
|
174 |
+
<adminhtml>
|
175 |
+
<events>
|
176 |
+
<catalog_entity_attribute_save_before>
|
177 |
+
<observers>
|
178 |
+
<productivity_merge_attribute_options>
|
179 |
+
<type>singleton</type>
|
180 |
+
<class>MVentory_Productivity_Model_Observer</class>
|
181 |
+
<method>mergeAttributeOptions</method>
|
182 |
+
</productivity_merge_attribute_options>
|
183 |
+
</observers>
|
184 |
+
</catalog_entity_attribute_save_before>
|
185 |
+
</events>
|
186 |
+
|
187 |
+
<layout>
|
188 |
+
<updates>
|
189 |
+
<productivity>
|
190 |
+
<file>productivity.xml</file>
|
191 |
+
</productivity>
|
192 |
+
</updates>
|
193 |
+
</layout>
|
194 |
+
</adminhtml>
|
195 |
+
</config>
|
app/code/community/MVentory/Productivity/etc/jstranslator.xml
ADDED
@@ -0,0 +1,6 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<jstranslator>
|
3 |
+
<productivity_confirm_remove translate="message" module="productivity">
|
4 |
+
<message>Do you want to delete this image?</message>
|
5 |
+
</productivity_confirm_remove>
|
6 |
+
</jstranslator>
|
app/code/community/MVentory/Productivity/etc/system.xml
ADDED
@@ -0,0 +1,88 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<!--
|
4 |
+
/**
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
*
|
12 |
+
* @package MVentory/Productivity
|
13 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
14 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
15 |
+
*/
|
16 |
+
-->
|
17 |
+
|
18 |
+
<config>
|
19 |
+
<sections>
|
20 |
+
<catalog>
|
21 |
+
<groups>
|
22 |
+
<frontend>
|
23 |
+
<fields>
|
24 |
+
<display_descending_products translate="label" module="productivity">
|
25 |
+
<label>Display all descending products</label>
|
26 |
+
<frontend_type>select</frontend_type>
|
27 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
28 |
+
|
29 |
+
<show_in_default>1</show_in_default>
|
30 |
+
<show_in_website>1</show_in_website>
|
31 |
+
<show_in_store>0</show_in_store>
|
32 |
+
|
33 |
+
<sort_order>300</sort_order>
|
34 |
+
</display_descending_products>
|
35 |
+
</fields>
|
36 |
+
</frontend>
|
37 |
+
|
38 |
+
<navigation>
|
39 |
+
<fields>
|
40 |
+
<hide_empty_categories translate="label" module="productivity">
|
41 |
+
<label>Show categories only with 2 or more sub-categories</label>
|
42 |
+
<frontend_type>select</frontend_type>
|
43 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
44 |
+
|
45 |
+
<show_in_default>1</show_in_default>
|
46 |
+
<show_in_website>1</show_in_website>
|
47 |
+
<show_in_store>0</show_in_store>
|
48 |
+
|
49 |
+
<sort_order>100</sort_order>
|
50 |
+
</hide_empty_categories>
|
51 |
+
|
52 |
+
<home_url translate="label" module="productivity">
|
53 |
+
<label>External Home URL</label>
|
54 |
+
<frontend_type>text</frontend_type>
|
55 |
+
|
56 |
+
<show_in_default>0</show_in_default>
|
57 |
+
<show_in_website>1</show_in_website>
|
58 |
+
<show_in_store>0</show_in_store>
|
59 |
+
|
60 |
+
<sort_order>101</sort_order>
|
61 |
+
</home_url>
|
62 |
+
</fields>
|
63 |
+
</navigation>
|
64 |
+
</groups>
|
65 |
+
</catalog>
|
66 |
+
|
67 |
+
<google>
|
68 |
+
<groups>
|
69 |
+
<analytics>
|
70 |
+
<fields>
|
71 |
+
<productivity_analytics_url translate="label comment" module="productivity">
|
72 |
+
<label>Analytics Reports URL</label>
|
73 |
+
<frontend_type>text</frontend_type>
|
74 |
+
<validate>validate-url</validate>
|
75 |
+
<comment>Link to analytics reports for Productivity toolbar.</comment>
|
76 |
+
|
77 |
+
<show_in_default>0</show_in_default>
|
78 |
+
<show_in_website>1</show_in_website>
|
79 |
+
<show_in_store>0</show_in_store>
|
80 |
+
|
81 |
+
<sort_order>30</sort_order>
|
82 |
+
</productivity_analytics_url>
|
83 |
+
</fields>
|
84 |
+
</analytics>
|
85 |
+
</groups>
|
86 |
+
</google>
|
87 |
+
</sections>
|
88 |
+
</config>
|
app/code/community/MVentory/Productivity/etc/widget.xml
ADDED
@@ -0,0 +1,101 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<!--
|
4 |
+
/**
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
*
|
12 |
+
* @package MVentory/Productivity
|
13 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
14 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
15 |
+
*/
|
16 |
+
-->
|
17 |
+
|
18 |
+
<widgets>
|
19 |
+
<productivity_slideshow type="productivity/slideshow" translate="name description" module="productivity">
|
20 |
+
<name>Productivity: Universal slideshow</name>
|
21 |
+
<description>A generic way of inserting different dynamic slideshows and galleries into pages via the admin</description>
|
22 |
+
<parameters>
|
23 |
+
<products_count translate="label">
|
24 |
+
<required>1</required>
|
25 |
+
<visible>1</visible>
|
26 |
+
<value>10</value>
|
27 |
+
<label>Number of Products to Display</label>
|
28 |
+
<type>text</type>
|
29 |
+
</products_count>
|
30 |
+
<item_template translate="label">
|
31 |
+
<required>1</required>
|
32 |
+
<visible>1</visible>
|
33 |
+
<value><![CDATA[<li><a href=\"%url%\"><img src=\"%img%\" alt=\"%name% %price%\"/></a></li>]]></value>
|
34 |
+
<label>Item template</label>
|
35 |
+
<type>text</type>
|
36 |
+
</item_template>
|
37 |
+
<image_size translate="label">
|
38 |
+
<required>1</required>
|
39 |
+
<visible>1</visible>
|
40 |
+
<value>300x200</value>
|
41 |
+
<label>Size of product image</label>
|
42 |
+
<type>text</type>
|
43 |
+
</image_size>
|
44 |
+
<!--<frontend_js translate="label">
|
45 |
+
<required>1</required>
|
46 |
+
<visible>1</visible>
|
47 |
+
<label>JS</label>
|
48 |
+
<type>text</type>
|
49 |
+
</frontend_js>-->
|
50 |
+
</parameters>
|
51 |
+
</productivity_slideshow>
|
52 |
+
|
53 |
+
<productivity_latest type="productivity/widget_latest" translate="name description" module="productivity">
|
54 |
+
<name>Productivity: Display latest products</name>
|
55 |
+
<description>A generic way of inserting different dynamic slideshows and galleries into pages via the admin</description>
|
56 |
+
<parameters>
|
57 |
+
<products_count translate="label">
|
58 |
+
<required>1</required>
|
59 |
+
<visible>1</visible>
|
60 |
+
<value>10</value>
|
61 |
+
<label>Number of Products to Display</label>
|
62 |
+
<type>text</type>
|
63 |
+
</products_count>
|
64 |
+
<item_template translate="label">
|
65 |
+
<required>1</required>
|
66 |
+
<visible>1</visible>
|
67 |
+
<value><![CDATA[<li><a href=\"%url%\"><img src=\"%img%\" alt=\"%name% %price%\"/></a></li>]]></value>
|
68 |
+
<label>Item template</label>
|
69 |
+
<type>text</type>
|
70 |
+
</item_template>
|
71 |
+
<image_size translate="label">
|
72 |
+
<required>1</required>
|
73 |
+
<visible>1</visible>
|
74 |
+
<value>300x200</value>
|
75 |
+
<label>Size of product image</label>
|
76 |
+
<type>text</type>
|
77 |
+
</image_size>
|
78 |
+
</parameters>
|
79 |
+
</productivity_latest>
|
80 |
+
|
81 |
+
<productivity_attribute type="productivity/widget_attribute" translate="name description" module="productivity">
|
82 |
+
<name>Productivity: Output values of attributes</name>
|
83 |
+
<description>A generic way to output values of attribute into pages via the admin</description>
|
84 |
+
<parameters>
|
85 |
+
<item_template translate="label">
|
86 |
+
<required>1</required>
|
87 |
+
<visible>1</visible>
|
88 |
+
<value><![CDATA[<li>%code%: %label% (%value%)</li>]]></value>
|
89 |
+
<label>Item template</label>
|
90 |
+
<type>text</type>
|
91 |
+
</item_template>
|
92 |
+
<code translate="label">
|
93 |
+
<required>1</required>
|
94 |
+
<visible>1</visible>
|
95 |
+
<value></value>
|
96 |
+
<label>Attribute code</label>
|
97 |
+
<type>text</type>
|
98 |
+
</code>
|
99 |
+
</parameters>
|
100 |
+
</productivity_attribute>
|
101 |
+
</widgets>
|
app/design/adminhtml/default/default/layout/productivity.xml
ADDED
@@ -0,0 +1,59 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
|
3 |
+
<!--
|
4 |
+
/**
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
*
|
12 |
+
* @package MVentory/Productivity
|
13 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
14 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
15 |
+
*/
|
16 |
+
-->
|
17 |
+
|
18 |
+
<layout>
|
19 |
+
<adminhtml_catalog_product_set_edit>
|
20 |
+
<reference name="js">
|
21 |
+
<block type="productivity/adminhtml_catalog_product_attribute_set_edit_script" template="productivity/catalog/product/attribute/set/edit/script.js.phtml" name="attribute.script.js" />
|
22 |
+
</reference>
|
23 |
+
</adminhtml_catalog_product_set_edit>
|
24 |
+
<adminhtml_catalog_product_attribute_index>
|
25 |
+
<reference name="head">
|
26 |
+
<action method="addJs"><script>productivity/adminhtml/update_grid.js</script></action>
|
27 |
+
<action method="addCss"><name>productivity.css</name></action>
|
28 |
+
</reference>
|
29 |
+
</adminhtml_catalog_product_attribute_index>
|
30 |
+
<adminhtml_catalog_product_set_index>
|
31 |
+
<reference name="head">
|
32 |
+
<action method="addJs"><script>productivity/adminhtml/update_grid.js</script></action>
|
33 |
+
</reference>
|
34 |
+
</adminhtml_catalog_product_set_index>
|
35 |
+
<adminhtml_catalog_product_edit>
|
36 |
+
<reference name="head">
|
37 |
+
<action method="addCss"><name>productivity.css</name></action>
|
38 |
+
</reference>
|
39 |
+
<reference name="content">
|
40 |
+
<block name="product.edit.frontview.button" type="productivity/adminhtml_catalog_product_edit_button" before="-" template="productivity/catalog/product/edit/button.phtml" />
|
41 |
+
</reference>
|
42 |
+
</adminhtml_catalog_product_edit>
|
43 |
+
<adminhtml_catalog_category_edit>
|
44 |
+
<reference name="head">
|
45 |
+
<action method="addCss"><name>productivity.css</name></action>
|
46 |
+
</reference>
|
47 |
+
<reference name="content">
|
48 |
+
<block name="category.edit.frontview.button" type="productivity/adminhtml_catalog_category_edit_button" before="-" template="productivity/catalog/category/edit/button.phtml" />
|
49 |
+
</reference>
|
50 |
+
</adminhtml_catalog_category_edit>
|
51 |
+
<adminhtml_cms_page_edit>
|
52 |
+
<reference name="head">
|
53 |
+
<action method="addCss"><name>productivity.css</name></action>
|
54 |
+
</reference>
|
55 |
+
<reference name="content">
|
56 |
+
<block name="page.edit.frontview.button" type="productivity/adminhtml_cms_page_edit_button" before="-" template="productivity/cms/page/edit/button.phtml" />
|
57 |
+
</reference>
|
58 |
+
</adminhtml_cms_page_edit>
|
59 |
+
</layout>
|
app/design/adminhtml/default/default/template/productivity/catalog/category/edit/button.phtml
ADDED
@@ -0,0 +1,43 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
|
18 |
+
<script>
|
19 |
+
var categories = <?php echo $this->getJson() ?>;
|
20 |
+
var key = '<?php echo Mage::getSingleton('adminhtml/url')->getSecretKey("catalog_product_attribute","edit");?>';
|
21 |
+
Event.observe(window, 'load', function() {
|
22 |
+
$('front-button').observe('click', function() {
|
23 |
+
var id = $$('input[name="general[id]"]')[0].value;
|
24 |
+
if(id > 0) {
|
25 |
+
var url = categories[id];
|
26 |
+
window.open(url);
|
27 |
+
}
|
28 |
+
});
|
29 |
+
$('category-edit-container').observe('mousedown', function(e) {
|
30 |
+
if(Event.isMiddleClick(e)) {
|
31 |
+
var tr = e.target.up('tr');
|
32 |
+
if(tr && e.target.up('table.data') && e.target.tagName == 'TD') {
|
33 |
+
var id = tr.down('input[type="checkbox"]').value;
|
34 |
+
window.open('/admin/catalog_product/edit/id/'+id+'/key/'+key+'/');
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
});
|
39 |
+
});
|
40 |
+
</script>
|
41 |
+
<div class="frontshop-button">
|
42 |
+
<button id="front-button" type="button" class="scalable frontshop"><span><?php echo $this->__('FrontShop Preview') ?></span></button>
|
43 |
+
</div>
|
app/design/adminhtml/default/default/template/productivity/catalog/product/attribute/options.phtml
ADDED
@@ -0,0 +1,219 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 options control
|
18 |
+
*
|
19 |
+
* @see MVentory_Productivity_Block_Catalog_Product_Attribute_Edit_Tab_Options
|
20 |
+
*/
|
21 |
+
|
22 |
+
?>
|
23 |
+
|
24 |
+
<div>
|
25 |
+
<ul class="messages">
|
26 |
+
<li class="notice-msg">
|
27 |
+
<ul>
|
28 |
+
<li><?php echo Mage::helper('catalog')->__('If you do not specify an option value for a specific store view then the default (Admin) value will be used.') ?></li>
|
29 |
+
</ul>
|
30 |
+
</li>
|
31 |
+
</ul>
|
32 |
+
</div>
|
33 |
+
|
34 |
+
<div class="entity-edit">
|
35 |
+
<div class="entry-edit-head">
|
36 |
+
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Manage Titles (Size, Color, etc.)') ?></h4>
|
37 |
+
</div>
|
38 |
+
<div class="box">
|
39 |
+
<div class="hor-scroll">
|
40 |
+
<table class="dynamic-grid" cellspacing="0" id="attribute-labels-table">
|
41 |
+
<tr>
|
42 |
+
<?php foreach ($this->getStores() as $_store): ?>
|
43 |
+
<th><?php echo $_store->getName() ?></th>
|
44 |
+
<?php endforeach; ?>
|
45 |
+
</tr>
|
46 |
+
<tr>
|
47 |
+
<?php $_labels = $this->getLabelValues() ?>
|
48 |
+
<?php foreach ($this->getStores() as $_store): ?>
|
49 |
+
<td>
|
50 |
+
<input class="input-text<?php if($_store->getId()==0): ?> required-option<?php endif; ?>" type="text" name="frontend_label[<?php echo $_store->getId() ?>]" value="<?php echo $this->escapeHtml($_labels[$_store->getId()]) ?>"<?php if ($this->getReadOnly()):?> disabled="disabled"<?php endif;?>/>
|
51 |
+
</td>
|
52 |
+
<?php endforeach; ?>
|
53 |
+
</tr>
|
54 |
+
</table>
|
55 |
+
</div>
|
56 |
+
</div>
|
57 |
+
</div>
|
58 |
+
<br/>
|
59 |
+
<div class="entity-edit" id="matage-options-panel">
|
60 |
+
<div class="entry-edit-head">
|
61 |
+
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Manage Options (values of your attribute)') ?></h4>
|
62 |
+
</div>
|
63 |
+
<div class="box">
|
64 |
+
<div class="hor-scroll">
|
65 |
+
<table class="dynamic-grid" cellspacing="0" cellpadding="0">
|
66 |
+
<tr id="attribute-options-table">
|
67 |
+
<th><?php echo Mage::helper('productivity')->__('From') ?></th>
|
68 |
+
<th><?php echo Mage::helper('productivity')->__('To') ?></th>
|
69 |
+
<?php foreach ($this->getStores() as $_store): ?>
|
70 |
+
<th><?php echo $_store->getName() ?></th>
|
71 |
+
<?php endforeach; ?>
|
72 |
+
<th><?php echo Mage::helper('catalog')->__('Position') ?></th>
|
73 |
+
<th class="nobr a-center"><?php echo Mage::helper('catalog')->__('Is Default') ?></th>
|
74 |
+
<th>
|
75 |
+
<?php if (!$this->getReadOnly()):?>
|
76 |
+
<?php echo $this->getAddNewButtonHtml() ?>
|
77 |
+
<?php endif;?>
|
78 |
+
</th>
|
79 |
+
</tr>
|
80 |
+
<tr class="no-display template" id="row-template">
|
81 |
+
<td><input class="input-radio" type="radio" name="option[merge][from]" value="{{id}}" /></td>
|
82 |
+
<td><input class="input-radio" type="radio" name="option[merge][to]" value="{{id}}" /></td>
|
83 |
+
<?php foreach ($this->getStores() as $_store): ?>
|
84 |
+
<td><input name="option[value][{{id}}][<?php echo $_store->getId() ?>]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text<?php if($_store->getId()==0): ?> required-option<?php endif; ?>" type="text" <?php if ($this->getReadOnly()):?> disabled="disabled"<?php endif;?>/></td>
|
85 |
+
<?php endforeach; ?>
|
86 |
+
<td class="a-center"><input class="input-text" type="text" name="option[order][{{id}}]" value="{{sort_order}}" <?php if ($this->getReadOnly()):?> disabled="disabled"<?php endif;?>/></td>
|
87 |
+
<td><input class="input-radio" type="radio" name="default[]" value="{{id}}" <?php if ($this->getReadOnly()):?> disabled="disabled"<?php endif;?>/></td>
|
88 |
+
<td class="a-left">
|
89 |
+
<input type="hidden" class="delete-flag" name="option[delete][{{id}}]" value="" />
|
90 |
+
<?php if (!$this->getReadOnly()):?>
|
91 |
+
<?php echo $this->getDeleteButtonHtml() ?>
|
92 |
+
<?php endif;?>
|
93 |
+
</td>
|
94 |
+
</tr>
|
95 |
+
</table>
|
96 |
+
</div>
|
97 |
+
<input type="hidden" id="option-count-check" value="" />
|
98 |
+
</div>
|
99 |
+
</div>
|
100 |
+
<script type="text/javascript">
|
101 |
+
//<![CDATA[
|
102 |
+
var optionDefaultInputType = 'radio';
|
103 |
+
|
104 |
+
// IE removes quotes from element.innerHTML whenever it thinks they're not needed, which breaks html.
|
105 |
+
var templateText =
|
106 |
+
'<tr class="option-row">'+
|
107 |
+
'<td><input class="input-radio" type="radio" name="option[merge][from]" value="{{id}}" /><\/td>'+
|
108 |
+
'<td><input class="input-radio" type="radio" name="option[merge][to]" value="{{id}}" /><\/td>'+
|
109 |
+
<?php foreach ($this->getStores() as $_store): ?>
|
110 |
+
'<td><input name="option[value][{{id}}][<?php echo $_store->getId() ?>]" value="{{store<?php echo $_store->getId() ?>}}" class="input-text<?php if($_store->getId()==0): ?> required-option<?php endif; ?>" type="text" <?php if ($this->getReadOnly()):?> disabled="disabled"<?php endif;?>/><\/td>'+
|
111 |
+
<?php endforeach; ?>
|
112 |
+
'<td><input class="input-text" type="text" name="option[order][{{id}}]" value="{{sort_order}}" <?php if ($this->getReadOnly()):?> disabled="disabled"<?php endif;?>/><\/td>'+
|
113 |
+
'<td class="a-center"><input class="input-radio" type="{{intype}}" name="default[]" value="{{id}}" {{checked}} <?php if ($this->getReadOnly()):?> disabled="disabled"<?php endif;?>/><\/td>'+
|
114 |
+
'<td class="a-left" id="delete_button_container_{{id}}">'+
|
115 |
+
'<input type="hidden" class="delete-flag" name="option[delete][{{id}}]" value="" />'+
|
116 |
+
<?php if (!$this->getReadOnly()):?>
|
117 |
+
'<?php echo $this->getDeleteButtonHtml() ?>'+
|
118 |
+
<?php endif;?>
|
119 |
+
'<\/td>'+
|
120 |
+
'<\/tr>';
|
121 |
+
|
122 |
+
var attributeOption = {
|
123 |
+
table : $('attribute-options-table'),
|
124 |
+
templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
|
125 |
+
templateText : templateText,
|
126 |
+
itemCount : 0,
|
127 |
+
totalItems : 0,
|
128 |
+
isReadOnly: <?php echo (int)$this->getReadOnly(); ?>,
|
129 |
+
add : function(data) {
|
130 |
+
this.template = new Template(this.templateText, this.templateSyntax);
|
131 |
+
var isNewOption = false;
|
132 |
+
if(!data.id){
|
133 |
+
data = {};
|
134 |
+
data.id = 'option_'+this.itemCount;
|
135 |
+
isNewOption = true;
|
136 |
+
}
|
137 |
+
if (!data.intype)
|
138 |
+
data.intype = optionDefaultInputType;
|
139 |
+
Element.insert(this.table, {after: this.template.evaluate(data)});
|
140 |
+
if (isNewOption && !this.isReadOnly) {
|
141 |
+
this.enableNewOptionDeleteButton(data.id);
|
142 |
+
}
|
143 |
+
this.bindRemoveButtons();
|
144 |
+
this.itemCount++;
|
145 |
+
this.totalItems++;
|
146 |
+
this.updateItemsCountField();
|
147 |
+
},
|
148 |
+
remove : function(event){
|
149 |
+
var element = $(Event.findElement(event, 'tr')); // !!! Button already
|
150 |
+
// have table parent in safari
|
151 |
+
// Safari workaround
|
152 |
+
element.ancestors().each(function(parentItem){
|
153 |
+
if (parentItem.hasClassName('option-row')) {
|
154 |
+
element = parentItem;
|
155 |
+
throw $break;
|
156 |
+
} else if (parentItem.hasClassName('box')) {
|
157 |
+
throw $break;
|
158 |
+
}
|
159 |
+
});
|
160 |
+
|
161 |
+
|
162 |
+
if(element){
|
163 |
+
var elementFlags = element.getElementsByClassName('delete-flag');
|
164 |
+
if(elementFlags[0]){
|
165 |
+
elementFlags[0].value=1;
|
166 |
+
}
|
167 |
+
|
168 |
+
element.addClassName('no-display');
|
169 |
+
element.addClassName('template');
|
170 |
+
element.hide();
|
171 |
+
this.totalItems--;
|
172 |
+
this.updateItemsCountField();
|
173 |
+
}
|
174 |
+
},
|
175 |
+
updateItemsCountField: function() {
|
176 |
+
if (this.totalItems > 0) {
|
177 |
+
$('option-count-check').value = '1';
|
178 |
+
} else {
|
179 |
+
$('option-count-check').value = '';
|
180 |
+
}
|
181 |
+
},
|
182 |
+
enableNewOptionDeleteButton: function(id) {
|
183 |
+
$$('#delete_button_container_' + id + ' button').each(function(button) {
|
184 |
+
button.enable();
|
185 |
+
button.removeClassName('disabled');
|
186 |
+
});
|
187 |
+
},
|
188 |
+
bindRemoveButtons : function(){
|
189 |
+
var buttons = $$('.delete-option');
|
190 |
+
for(var i=0;i<buttons.length;i++){
|
191 |
+
if(!$(buttons[i]).binded){
|
192 |
+
$(buttons[i]).binded = true;
|
193 |
+
Event.observe(buttons[i], 'click', this.remove.bind(this));
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
}
|
199 |
+
if($('row-template')){
|
200 |
+
$('row-template').remove();
|
201 |
+
}
|
202 |
+
attributeOption.bindRemoveButtons();
|
203 |
+
|
204 |
+
if($('add_new_option_button')){
|
205 |
+
Event.observe('add_new_option_button', 'click', attributeOption.add.bind(attributeOption));
|
206 |
+
}
|
207 |
+
Validation.addAllThese([
|
208 |
+
['required-option', '<?php echo Mage::helper('catalog')->__('Failed') ?>', function(v) {
|
209 |
+
return !Validation.get('IsEmpty').test(v);
|
210 |
+
}]]);
|
211 |
+
Validation.addAllThese([
|
212 |
+
['required-options-count', '<?php echo Mage::helper('catalog')->__('Options is required') ?>', function(v) {
|
213 |
+
return !Validation.get('IsEmpty').test(v);
|
214 |
+
}]]);
|
215 |
+
<?php foreach ($this->getOptionValues() as $_value): ?>
|
216 |
+
attributeOption.add(<?php echo $_value->toJson() ?>);
|
217 |
+
<?php endforeach; ?>
|
218 |
+
//]]>
|
219 |
+
</script>
|
app/design/adminhtml/default/default/template/productivity/catalog/product/attribute/set/edit/script.js.phtml
ADDED
@@ -0,0 +1,36 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Mouse middle button click for attributes
|
18 |
+
*/
|
19 |
+
|
20 |
+
?>
|
21 |
+
|
22 |
+
<script>
|
23 |
+
var attribute = <?php echo $this->getJson() ?>;
|
24 |
+
var key = '<?php echo Mage::getSingleton('adminhtml/url')->getSecretKey("catalog_product_attribute","edit");?>';
|
25 |
+
Event.observe(window, 'load', function() {
|
26 |
+
$$('.x-tree-node-leaf').each(function(item) {
|
27 |
+
item.down('a').observe('mousedown', function(event){
|
28 |
+
if(Event.isMiddleClick(event)) {
|
29 |
+
event.preventDefault();
|
30 |
+
var id = attribute[event.target.innerHTML];
|
31 |
+
window.open('/admin/catalog_product_attribute/edit/attribute_id/'+id+'/key/'+key+'/', '_blank');
|
32 |
+
}
|
33 |
+
});
|
34 |
+
});
|
35 |
+
});
|
36 |
+
</script>
|
app/design/adminhtml/default/default/template/productivity/catalog/product/edit/button.phtml
ADDED
@@ -0,0 +1,18 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
|
18 |
+
<div class="frontshop-button"><button id="front-button" type="button" class="scalable frontshop" onclick="window.open('<?php echo $this->getProductUrl() ?>');"><span><?php echo $this->__('FrontShop Preview') ?></span></button></div>
|
app/design/adminhtml/default/default/template/productivity/cms/page/edit/button.phtml
ADDED
@@ -0,0 +1,18 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
|
18 |
+
<div class="frontshop-button"><button id="front-button" type="button" class="scalable frontshop" onclick="window.open('<?php echo $this->getPageUrl() ?>');"><span><?php echo $this->__('FrontShop Preview') ?></span></button></div>
|
app/design/frontend/base/default/layout/productivity.xml
ADDED
@@ -0,0 +1,96 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<!--
|
4 |
+
/**
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
*
|
12 |
+
* @package MVentory/Productivity
|
13 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
14 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
15 |
+
*/
|
16 |
+
-->
|
17 |
+
|
18 |
+
<layout version="0.1.0">
|
19 |
+
<productivity_rss_product_latest>
|
20 |
+
<block type="productivity/rss_product_latest" output="toHtml" name="rss.product.latest" />
|
21 |
+
</productivity_rss_product_latest>
|
22 |
+
|
23 |
+
<productivity_panel>
|
24 |
+
<reference name="head">
|
25 |
+
<action method="addCss">
|
26 |
+
<stylesheet>productivity/css/styles.css</stylesheet>
|
27 |
+
</action>
|
28 |
+
</reference>
|
29 |
+
|
30 |
+
<reference name="after_body_start">
|
31 |
+
<block type="productivity/panel" name="admin_panel" after="-" template="productivity/panel.phtml" />
|
32 |
+
</reference>
|
33 |
+
</productivity_panel>
|
34 |
+
|
35 |
+
<catalog_product_view>
|
36 |
+
<update handle="jquery" />
|
37 |
+
|
38 |
+
<reference name="head">
|
39 |
+
<action method="addJs">
|
40 |
+
<script>jquery/jquery-fineuploader-min.js</script>
|
41 |
+
</action>
|
42 |
+
|
43 |
+
<action method="addJs">
|
44 |
+
<script>productivity/image/edit.js</script>
|
45 |
+
</action>
|
46 |
+
</reference>
|
47 |
+
|
48 |
+
<reference name="before_body_end">
|
49 |
+
<block type="productivity/image_edit" name="productivity.image.edit" template="productivity/image/edit.phtml">
|
50 |
+
<action method="setImageWrapperSelector">
|
51 |
+
<selector><![CDATA[#product_addtocart_form > .product-img-box > .product-image]]></selector>
|
52 |
+
</action>
|
53 |
+
|
54 |
+
<action method="setImageSelector">
|
55 |
+
<selector><![CDATA[> img]]></selector>
|
56 |
+
</action>
|
57 |
+
|
58 |
+
<action method="setThumbWrapperSelector">
|
59 |
+
<selector><![CDATA[#product_addtocart_form > .product-img-box > .more-views > ul > li > a]]></selector>
|
60 |
+
</action>
|
61 |
+
|
62 |
+
<action method="setThumbSelector">
|
63 |
+
<selector><![CDATA[> img]]></selector>
|
64 |
+
</action>
|
65 |
+
|
66 |
+
<action method="setImageSize">
|
67 |
+
<width>265</width>
|
68 |
+
<height></height>
|
69 |
+
</action>
|
70 |
+
|
71 |
+
<action method="setThumbSize">
|
72 |
+
<width>56</width>
|
73 |
+
<height></height>
|
74 |
+
</action>
|
75 |
+
</block>
|
76 |
+
|
77 |
+
<block type="core/template" name="productivity.panel.upload.js" template="productivity/panel/uploader/js.phtml" />
|
78 |
+
</reference>
|
79 |
+
</catalog_product_view>
|
80 |
+
|
81 |
+
<catalog_category_default>
|
82 |
+
<update handle="productivity_panel" />
|
83 |
+
</catalog_category_default>
|
84 |
+
|
85 |
+
<catalog_category_layered>
|
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>
|
96 |
+
</layout>
|
app/design/frontend/base/default/template/productivity/catalog/product/latest.phtml
ADDED
@@ -0,0 +1,97 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
* Latest products
|
18 |
+
*
|
19 |
+
* @see MVentory_Productivity_Block_Product_Latest
|
20 |
+
*/
|
21 |
+
|
22 |
+
?>
|
23 |
+
|
24 |
+
<h1 class="no-display">Building materials and supplies</h1>
|
25 |
+
|
26 |
+
<?php if (($_productCollection = $this->getProductCollection()) && $_productCollection->getSize()): ?>
|
27 |
+
|
28 |
+
<div id="lastProducts" class="block" style="border-radius: 3px 3px 3px 3px;">
|
29 |
+
<div class="listing-type-grid catalog-listing latest-products">
|
30 |
+
<h2>Latest products</h2>
|
31 |
+
|
32 |
+
<?php $_collectionSize = $_productCollection->count() ?>
|
33 |
+
|
34 |
+
<table cellspacing="0" class="generic-product-grid" id="product-list-table">
|
35 |
+
|
36 |
+
<?php $_columnCount = 3; ?>
|
37 |
+
<?php $i = 0; foreach ($_productCollection as $_product): ?>
|
38 |
+
|
39 |
+
<?php if ($i++ % $_columnCount == 0): ?>
|
40 |
+
<tr>
|
41 |
+
<?php endif ?>
|
42 |
+
<td>
|
43 |
+
<p class="product-image">
|
44 |
+
<a class="preview" rel="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(300, 300); ?>" href="<?php echo $_product->getProductUrl(); ?>" title="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')); ?>">
|
45 |
+
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(215, 170); ?>" alt="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')); ?>" title="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')); ?>" />
|
46 |
+
</a>
|
47 |
+
</p>
|
48 |
+
|
49 |
+
<h3>
|
50 |
+
<a href="<?php echo $_product->getProductUrl(); ?>" title="<?php echo $this->htmlEscape($_product->getName()); ?>"><?php echo $this->htmlEscape($_product->getName()); ?></a>
|
51 |
+
</h3>
|
52 |
+
|
53 |
+
<?php if($_product->getRatingSummary()): ?>
|
54 |
+
<?php echo $this->getReviewsSummaryHtml($_product, 'short'); ?>
|
55 |
+
<?php endif; ?>
|
56 |
+
|
57 |
+
<?php echo $this->getPriceHtml($_product, true); ?>
|
58 |
+
|
59 |
+
<?php if($_product->isSaleable()): ?>
|
60 |
+
<a href="#" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product); ?>')" class="add-to-cart"><?php echo $this->__('Add to Cart + '); ?></a>
|
61 |
+
<?php else: ?>
|
62 |
+
<div class="out-of-stock"><?php echo $this->__('Out of stock'); ?></div>
|
63 |
+
<?php endif; ?>
|
64 |
+
|
65 |
+
<div class="clear"></div>
|
66 |
+
|
67 |
+
<ul class="add-to">
|
68 |
+
<?php if ($this->helper('wishlist')->isAllow()) : ?>
|
69 |
+
<li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product); ?>"><?php echo $this->__('Add to Wishlist'); ?></a></li>
|
70 |
+
<?php endif; ?>
|
71 |
+
|
72 |
+
<?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
|
73 |
+
<li><a href="<?php echo $_compareUrl ?>"><?php echo $this->__('Add to Compare'); ?></a></li>
|
74 |
+
<?php endif; ?>
|
75 |
+
</ul>
|
76 |
+
</td>
|
77 |
+
<?php if ($i % $_columnCount == 0 && $i != $_collectionSize): ?>
|
78 |
+
</tr>
|
79 |
+
<?php endif ?>
|
80 |
+
|
81 |
+
<?php endforeach ?>
|
82 |
+
|
83 |
+
<?php for($i; $i % $_columnCount != 0; $i++): ?>
|
84 |
+
<td class="empty-product"> </td>
|
85 |
+
<?php endfor ?>
|
86 |
+
|
87 |
+
<?php if ($i % $_columnCount == 0): ?>
|
88 |
+
</tr>
|
89 |
+
<?php endif ?>
|
90 |
+
|
91 |
+
</table>
|
92 |
+
|
93 |
+
<script type="text/javascript">decorateTable('product-list-table')</script>
|
94 |
+
|
95 |
+
</div>
|
96 |
+
</div>
|
97 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/productivity/image/edit.phtml
ADDED
@@ -0,0 +1,72 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
|
18 |
+
<?php
|
19 |
+
|
20 |
+
$helper = Mage::helper('core');
|
21 |
+
|
22 |
+
?>
|
23 |
+
|
24 |
+
<div id="productivity-image-edit-panel" class="tm-image-editor-menu">
|
25 |
+
<div class="set-main-image"
|
26 |
+
title="<?php echo $this->__('Set as main image'); ?>">
|
27 |
+
</div>
|
28 |
+
|
29 |
+
<div class="remove-image"
|
30 |
+
title="<?php echo $this->__('Remove'); ?>">
|
31 |
+
</div>
|
32 |
+
|
33 |
+
<div class="rotate-image rotate-left"
|
34 |
+
title="<?php echo $this->__('Rotate left'); ?>">
|
35 |
+
</div>
|
36 |
+
|
37 |
+
<div class="rotate-image rotate-right"
|
38 |
+
title="<?php echo $this->__('Rotate right'); ?>">
|
39 |
+
</div>
|
40 |
+
</div>
|
41 |
+
|
42 |
+
<script type="text/javascript">
|
43 |
+
//<![CDATA[
|
44 |
+
|
45 |
+
productivity.image.url = {
|
46 |
+
rotate: '<?php echo $this->getUrl('productivity/image/rotate') ?>',
|
47 |
+
remove: '<?php echo $this->getUrl('productivity/image/remove') ?>',
|
48 |
+
setmain: '<?php echo $this->getUrl('productivity/image/setmain') ?>'
|
49 |
+
};
|
50 |
+
|
51 |
+
productivity.edit.selector = {
|
52 |
+
image: '<?php echo $this->getImageSelector() ?>',
|
53 |
+
thumbnail: '<?php echo $this->getThumbSelector() ?>'
|
54 |
+
};
|
55 |
+
|
56 |
+
productivity.edit.wrapper = {
|
57 |
+
image: '<?php echo $this->getImageWrapperSelector() ?>',
|
58 |
+
thumbnail: '<?php echo $this->getThumbWrapperSelector() ?>'
|
59 |
+
};
|
60 |
+
|
61 |
+
productivity.edit.size = {
|
62 |
+
image: <?php echo $helper->jsonEncode($this->getImageSize()) ?>,
|
63 |
+
thumbnail: <?php echo $helper->jsonEncode($this->getThumbSize()) ?>
|
64 |
+
};
|
65 |
+
|
66 |
+
Translator.add(
|
67 |
+
'Do you want to delete this image?',
|
68 |
+
'<?php echo $this->__('Do you want to delete this image?'); ?>'
|
69 |
+
);
|
70 |
+
|
71 |
+
//]]>
|
72 |
+
</script>
|
app/design/frontend/base/default/template/productivity/panel.phtml
ADDED
@@ -0,0 +1,197 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
|
18 |
+
<?php
|
19 |
+
/* @var $this MVentory_Productivity_Block_Panel */
|
20 |
+
$_helper = Mage::helper('productivity');
|
21 |
+
$_type = $this->_getType();
|
22 |
+
|
23 |
+
if ($_type == 'product') {
|
24 |
+
$__uploadTitle = $this->__('Upload a product image');
|
25 |
+
$__editTitle = $this->__('Edit product details');
|
26 |
+
} else {
|
27 |
+
$__uploadTitle = $this->__('Select a product and click on Upload again to add more product images');
|
28 |
+
$__editTitle = $this->__('Select a product and click on Edit again to edit product details');
|
29 |
+
|
30 |
+
$_onClick = ' onclick="alert(this.title); return false;"';
|
31 |
+
}
|
32 |
+
|
33 |
+
?>
|
34 |
+
|
35 |
+
<?php if ($_helper->isReviewerLogged()): ?>
|
36 |
+
|
37 |
+
<div id="productivity-panel" class="productivity">
|
38 |
+
<div id="productivity-panel-menu" class="clearer">
|
39 |
+
|
40 |
+
<?php if ($_type == 'product'): ?>
|
41 |
+
<ul id="productivity-context" class="productivity-set">
|
42 |
+
<li id="productivity-uploader-notice">
|
43 |
+
<a title="<?php echo $this->__('Refresh the page to see changes'); ?>" href="<?php echo $this->_getCurrentUrl(); ?>"><?php echo $this->__('<span>Refresh</span> the page to see changes'); ?></a>
|
44 |
+
</li>
|
45 |
+
</ul>
|
46 |
+
<?php endif; ?>
|
47 |
+
|
48 |
+
<ul id="productivity-tasks" class="productivity-set">
|
49 |
+
|
50 |
+
<?php if ($url = $this->_getAnalyticsUrl()): ?>
|
51 |
+
<li>
|
52 |
+
<a title="<?php echo $this->__('Analytics reports'); ?>" href="<?php echo $url; ?>" target="_blank"><?php echo $this->__('Analytics'); ?></a>
|
53 |
+
</li>
|
54 |
+
<?php endif; ?>
|
55 |
+
|
56 |
+
<?php if ($_helper->isAdminLogged()): ?>
|
57 |
+
|
58 |
+
<?php
|
59 |
+
|
60 |
+
switch ($_type) {
|
61 |
+
case 'page':
|
62 |
+
case 'index': $_link = $this->_getCmsPageLink(); break;
|
63 |
+
case 'category': $_link = $this->_getCategoryLink(); break;
|
64 |
+
case 'product': $_link = $this->_getProductLink(); break;
|
65 |
+
}
|
66 |
+
|
67 |
+
?>
|
68 |
+
|
69 |
+
<?php if (isset($_link) && $_link): ?>
|
70 |
+
<li>
|
71 |
+
<a title="<?php echo $this->__('Go to Magento admin panel'); ?>" href="<?php echo $_link ?>"><?php echo $this->__('Admin'); ?></a>
|
72 |
+
</li>
|
73 |
+
<?php endif; ?>
|
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>
|
80 |
+
|
81 |
+
<li>
|
82 |
+
<a title="<?php echo $__uploadTitle; ?>" id="productivity-task-upload" class="productivity-panel-task" href="#"<?php if (isset($_onClick)) echo $_onClick; ?>><?php echo $this->__('Upload') ?></a>
|
83 |
+
</li>
|
84 |
+
|
85 |
+
<li>
|
86 |
+
<a title="<?php echo $__editTitle; ?>" id="productivity-task-edit-form" class="productivity-panel-task" href="#"<?php if (isset($_onClick)) echo $_onClick; ?>><?php echo $this->__('Edit') ?></a>
|
87 |
+
</li>
|
88 |
+
|
89 |
+
<li>
|
90 |
+
<a title="<?php echo $this->__('About this extension'); ?>" href="<?php echo $this->_getHelpUrl(); ?>" target="_blank"><?php echo $this->__('Help') ?></a>
|
91 |
+
</li>
|
92 |
+
|
93 |
+
<?php if ($_type == 'product'): ?>
|
94 |
+
<li>
|
95 |
+
<a title="<?php echo $this->__('Hide the editing panel'); ?>" id="productivity-action-close" href="#">×</a>
|
96 |
+
</li>
|
97 |
+
<?php endif; ?>
|
98 |
+
|
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 |
+
|
109 |
+
<div id="productivity-uploader-dropzone-wrapper">
|
110 |
+
<div id="productivity-uploader-dropzone">
|
111 |
+
<span><?php echo $this->__('Drag and drop product images to upload here'); ?></span>
|
112 |
+
</div>
|
113 |
+
</div>
|
114 |
+
|
115 |
+
<ul id="productivity-uploader-previews"></ul>
|
116 |
+
</div>
|
117 |
+
|
118 |
+
<?php //A quick form for editing select attributes in a hurry. ?>
|
119 |
+
|
120 |
+
<div id="productivity-edit-attributes">
|
121 |
+
<h3><?php echo $this->__('Edit product details'); ?></h3>
|
122 |
+
|
123 |
+
<div id="productivity-edit-form">
|
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 |
+
|
145 |
+
$panel.css('height', menu_height);
|
146 |
+
|
147 |
+
function resize_panel () {
|
148 |
+
$panel.css('height', $content.height() + menu_height);
|
149 |
+
|
150 |
+
return false;
|
151 |
+
}
|
152 |
+
|
153 |
+
$panel.on('mouseenter drop', resize_panel)
|
154 |
+
|
155 |
+
var tasks = '';
|
156 |
+
|
157 |
+
$('#productivity-tasks .productivity-panel-task').each(function () {
|
158 |
+
var $this = $(this);
|
159 |
+
|
160 |
+
var task = $this.attr('id') + '-on';
|
161 |
+
|
162 |
+
tasks += task + ' ';
|
163 |
+
|
164 |
+
$(this).on('click', function () {
|
165 |
+
$panel.hasClass(task)
|
166 |
+
? $panel.removeClass(task)
|
167 |
+
: $panel.addClass(task);
|
168 |
+
|
169 |
+
resize_panel();
|
170 |
+
|
171 |
+
return false;
|
172 |
+
});
|
173 |
+
});
|
174 |
+
|
175 |
+
$('#productivity-action-close').on('click', function () {
|
176 |
+
$panel.removeClass(tasks);
|
177 |
+
|
178 |
+
resize_panel();
|
179 |
+
|
180 |
+
return false;
|
181 |
+
});
|
182 |
+
|
183 |
+
$('#productivity_edit_form_cancel').on('click', function () {
|
184 |
+
$panel.removeClass('productivity-task-edit-form-on');
|
185 |
+
|
186 |
+
resize_panel();
|
187 |
+
|
188 |
+
return false;
|
189 |
+
});
|
190 |
+
});
|
191 |
+
|
192 |
+
//]]>
|
193 |
+
</script>
|
194 |
+
|
195 |
+
<?php endif; ?>
|
196 |
+
|
197 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/productivity/panel/uploader/js.phtml
ADDED
@@ -0,0 +1,144 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
|
18 |
+
<?php if (Mage::helper('productivity')->isReviewerLogged()) : ?>
|
19 |
+
|
20 |
+
<?php
|
21 |
+
|
22 |
+
$_productId = Mage::registry('product')->getId();
|
23 |
+
$_url = $this->getUrl('productivity/image/upload');
|
24 |
+
|
25 |
+
?>
|
26 |
+
|
27 |
+
<script type="text/javascript">
|
28 |
+
//<![CDATA[
|
29 |
+
|
30 |
+
jQuery(function ($) {
|
31 |
+
|
32 |
+
var $panel = $('#productivity-panel');
|
33 |
+
var $upload_elem = $('#productivity-uploader-element');
|
34 |
+
var $upload_btn = $('#productivity-uploader-button-upload');
|
35 |
+
|
36 |
+
$upload_elem
|
37 |
+
.fineUploader({
|
38 |
+
button: $('#productivity-uploader-dropzone'),
|
39 |
+
listElement: $('#productivity-uploader-previews'),
|
40 |
+
|
41 |
+
request: {
|
42 |
+
endpoint: '<?php echo $_url; ?>',
|
43 |
+
params: {
|
44 |
+
product_id: <?php echo $_productId; ?>
|
45 |
+
}
|
46 |
+
},
|
47 |
+
|
48 |
+
dragAndDrop: {
|
49 |
+
disableDefaultDropzone: true,
|
50 |
+
hideDropzones: false,
|
51 |
+
extraDropzones: [$('#productivity-uploader-dropzone')]
|
52 |
+
},
|
53 |
+
|
54 |
+
text: {
|
55 |
+
cancelButton: ''
|
56 |
+
}
|
57 |
+
})
|
58 |
+
.on('submitted', function (event, id, name) {
|
59 |
+
var $this = $(this);
|
60 |
+
var reader = new FileReader();
|
61 |
+
|
62 |
+
reader.onload = function (e) {
|
63 |
+
$this
|
64 |
+
.fineUploader('getItemByFileId', id)
|
65 |
+
.css('background-image', 'url(' + e.target.result + ')');
|
66 |
+
};
|
67 |
+
|
68 |
+
reader.readAsDataURL($this.fineUploader('getFile', id));
|
69 |
+
|
70 |
+
$upload_btn.css('display', 'block');
|
71 |
+
})
|
72 |
+
.on('complete', function (event, id, name, response, xhr) {
|
73 |
+
if (!response.success)
|
74 |
+
return;
|
75 |
+
|
76 |
+
$panel.addClass('productivity-state-uploaded');
|
77 |
+
|
78 |
+
if (typeof productivity === 'undefined')
|
79 |
+
return;
|
80 |
+
|
81 |
+
function on_error ($element, data) {
|
82 |
+
$element
|
83 |
+
.removeClass('qq-upload-success')
|
84 |
+
.addClass('qq-upload-fail');
|
85 |
+
|
86 |
+
setTimeout(
|
87 |
+
function () { $element.removeClass('qq-upload-fail'); },
|
88 |
+
5000
|
89 |
+
);
|
90 |
+
}
|
91 |
+
|
92 |
+
productivity.func.add_panel(
|
93 |
+
$(this).fineUploader('getItemByFileId', id),
|
94 |
+
{
|
95 |
+
panel: {
|
96 |
+
position: { top: 2, left: 2 },
|
97 |
+
scope: 'uploader',
|
98 |
+
action: {
|
99 |
+
remove: {
|
100 |
+
on_error: on_error,
|
101 |
+
on_success: function ($element, data) {
|
102 |
+
$element.remove();
|
103 |
+
}
|
104 |
+
},
|
105 |
+
rotate: {
|
106 |
+
on_error: on_error,
|
107 |
+
on_success: function ($element, data) {
|
108 |
+
$element.css('background-image', 'url(' + data.url + ')');
|
109 |
+
$element.data('productivity').file = data.file;
|
110 |
+
}
|
111 |
+
},
|
112 |
+
setmain: {
|
113 |
+
on_error: on_error,
|
114 |
+
on_success: function ($element, data) {
|
115 |
+
$element.image.prop('src', data.image.url);
|
116 |
+
$element.image.data('productivity').file = data.image.file;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
}
|
120 |
+
},
|
121 |
+
image: {
|
122 |
+
file: response.data.file,
|
123 |
+
type: 'thumbnail',
|
124 |
+
width: null,
|
125 |
+
height: null
|
126 |
+
}
|
127 |
+
}
|
128 |
+
);
|
129 |
+
});
|
130 |
+
|
131 |
+
$upload_btn.on('click', function () {
|
132 |
+
$upload_elem.fineUploader('uploadStoredFiles');
|
133 |
+
});
|
134 |
+
|
135 |
+
//function get_image_edit_panel_size ($element) {
|
136 |
+
// return { width: $element.width(), height: $element.height() };
|
137 |
+
//}
|
138 |
+
|
139 |
+
});
|
140 |
+
|
141 |
+
//]]>
|
142 |
+
</script>
|
143 |
+
|
144 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/productivity/rss/import.phtml
ADDED
@@ -0,0 +1,32 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
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 |
+
|
18 |
+
<?php
|
19 |
+
|
20 |
+
$_id = $this->getElementId();
|
21 |
+
$_class = $this->getAdditionalClass();
|
22 |
+
|
23 |
+
$_id = $_id ? 'id="' . $_id . '" ' : '';
|
24 |
+
$_class = 'class="productivity-rss-wrapper'
|
25 |
+
. ($_class ? ' ' . $_class : '')
|
26 |
+
. '"';
|
27 |
+
|
28 |
+
?>
|
29 |
+
|
30 |
+
<div <?php echo $_id, $_class; ?>>
|
31 |
+
<?php echo $this->getContent(); ?>
|
32 |
+
</div>
|
app/etc/modules/MVentory_Productivity.xml
ADDED
@@ -0,0 +1,25 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<!--
|
4 |
+
/**
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
*
|
12 |
+
* @package MVentory/Productivity
|
13 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
14 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
15 |
+
*/
|
16 |
+
-->
|
17 |
+
|
18 |
+
<config>
|
19 |
+
<modules>
|
20 |
+
<MVentory_Productivity>
|
21 |
+
<active>true</active>
|
22 |
+
<codePool>community</codePool>
|
23 |
+
</MVentory_Productivity>
|
24 |
+
</modules>
|
25 |
+
</config>
|
js/jquery/jquery-fineuploader-min.js
ADDED
@@ -0,0 +1,19 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
/*!
|
2 |
+
* Fine Uploader
|
3 |
+
*
|
4 |
+
* Copyright 2013, Widen Enterprises, Inc. info@fineuploader.com
|
5 |
+
*
|
6 |
+
* Version: 3.7.1
|
7 |
+
*
|
8 |
+
* Homepage: http://fineuploader.com
|
9 |
+
*
|
10 |
+
* Repository: git://github.com/Widen/fine-uploader.git
|
11 |
+
*
|
12 |
+
* Licensed under GNU GPL v3, see LICENSE
|
13 |
+
*/
|
14 |
+
|
15 |
+
|
16 |
+
var qq=function(a){"use strict";return{hide:function(){return a.style.display="none",this},attach:function(b,c){return a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c),function(){qq(a).detach(b,c)}},detach:function(b,c){return a.removeEventListener?a.removeEventListener(b,c,!1):a.attachEvent&&a.detachEvent("on"+b,c),this},contains:function(b){return b?a===b?!0:a.contains?a.contains(b):!!(8&b.compareDocumentPosition(a)):!1},insertBefore:function(b){return b.parentNode.insertBefore(a,b),this},remove:function(){return a.parentNode.removeChild(a),this},css:function(b){return null!=b.opacity&&"string"!=typeof a.style.opacity&&"undefined"!=typeof a.filters&&(b.filter="alpha(opacity="+Math.round(100*b.opacity)+")"),qq.extend(a.style,b),this},hasClass:function(b){var c=new RegExp("(^| )"+b+"( |$)");return c.test(a.className)},addClass:function(b){return qq(a).hasClass(b)||(a.className+=" "+b),this},removeClass:function(b){var c=new RegExp("(^| )"+b+"( |$)");return a.className=a.className.replace(c," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(b){var c,d=[];return a.querySelectorAll?a.querySelectorAll("."+b):(c=a.getElementsByTagName("*"),qq.each(c,function(a,c){qq(c).hasClass(b)&&d.push(c)}),d)},children:function(){for(var b=[],c=a.firstChild;c;)1===c.nodeType&&b.push(c),c=c.nextSibling;return b},setText:function(b){return a.innerText=b,a.textContent=b,this},clearText:function(){return qq(a).setText("")}}};qq.log=function(a,b){"use strict";window.console&&(b&&"info"!==b?window.console[b]?window.console[b](a):window.console.log("<"+b+"> "+a):window.console.log(a))},qq.isObject=function(a){"use strict";return a&&!a.nodeType&&"[object Object]"===Object.prototype.toString.call(a)},qq.isFunction=function(a){"use strict";return"function"==typeof a},qq.isArray=function(a){"use strict";return"[object Array]"===Object.prototype.toString.call(a)},qq.isString=function(a){"use strict";return"[object String]"===Object.prototype.toString.call(a)},qq.trimStr=function(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")},qq.format=function(a){"use strict";var b=Array.prototype.slice.call(arguments,1),c=a;return qq.each(b,function(a,b){c=c.replace(/{}/,b)}),c},qq.isFile=function(a){"use strict";return window.File&&"[object File]"===Object.prototype.toString.call(a)},qq.isFileList=function(a){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(a)},qq.isFileOrInput=function(a){"use strict";return qq.isFile(a)||qq.isInput(a)},qq.isInput=function(a){return window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(a)&&a.type&&"file"===a.type.toLowerCase()?!0:a.tagName&&"input"===a.tagName.toLowerCase()&&a.type&&"file"===a.type.toLowerCase()?!0:!1},qq.isBlob=function(a){"use strict";return window.Blob&&"[object Blob]"===Object.prototype.toString.call(a)},qq.isXhrUploadSupported=function(){"use strict";var a=document.createElement("input");return a.type="file",void 0!==a.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&"undefined"!=typeof(new XMLHttpRequest).upload},qq.isFolderDropSupported=function(a){"use strict";return a.items&&a.items[0].webkitGetAsEntry},qq.isFileChunkingSupported=function(){"use strict";return!qq.android()&&qq.isXhrUploadSupported()&&(void 0!==File.prototype.slice||void 0!==File.prototype.webkitSlice||void 0!==File.prototype.mozSlice)},qq.extend=function(a,b,c){"use strict";return qq.each(b,function(b,d){c&&qq.isObject(d)?(void 0===a[b]&&(a[b]={}),qq.extend(a[b],d,!0)):a[b]=d}),a},qq.indexOf=function(a,b,c){"use strict";if(a.indexOf)return a.indexOf(b,c);c=c||0;var d=a.length;for(0>c&&(c+=d);d>c;c+=1)if(a.hasOwnProperty(c)&&a[c]===b)return c;return-1},qq.getUniqueId=function(){"use strict";return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=0|16*Math.random(),c="x"==a?b:8|3&b;return c.toString(16)})},qq.ie=function(){"use strict";return-1!==navigator.userAgent.indexOf("MSIE")},qq.ie10=function(){"use strict";return-1!==navigator.userAgent.indexOf("MSIE 10")},qq.safari=function(){"use strict";return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Apple")},qq.chrome=function(){"use strict";return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Google")},qq.firefox=function(){"use strict";return-1!==navigator.userAgent.indexOf("Mozilla")&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){"use strict";return"Win32"===navigator.platform},qq.android=function(){"use strict";return-1!==navigator.userAgent.toLowerCase().indexOf("android")},qq.ios=function(){"use strict";return-1!==navigator.userAgent.indexOf("iPad")||-1!==navigator.userAgent.indexOf("iPod")||-1!==navigator.userAgent.indexOf("iPhone")},qq.preventDefault=function(a){"use strict";a.preventDefault?a.preventDefault():a.returnValue=!1},qq.toElement=function(){"use strict";var a=document.createElement("div");return function(b){a.innerHTML=b;var c=a.firstChild;return a.removeChild(c),c}}(),qq.each=function(a,b){"use strict";var c,d;if(a)if(qq.isArray(a))for(c=0;c<a.length&&(d=b(c,a[c]),d!==!1);c++);else for(c in a)if(Object.prototype.hasOwnProperty.call(a,c)&&(d=b(c,a[c]),d===!1))break},qq.bind=function(a,b){if(qq.isFunction(a)){var c=Array.prototype.slice.call(arguments,2);return function(){return arguments.length&&(c=c.concat(Array.prototype.slice.call(arguments))),a.apply(b,c)}}throw new Error("first parameter must be a function!")},qq.obj2url=function(a,b,c){"use strict";var d,e,f=[],g="&",h=function(a,c){var d=b?/\[\]$/.test(b)?b:b+"["+c+"]":c;"undefined"!==d&&"undefined"!==c&&f.push("object"==typeof a?qq.obj2url(a,d,!0):"[object Function]"===Object.prototype.toString.call(a)?encodeURIComponent(d)+"="+encodeURIComponent(a()):encodeURIComponent(d)+"="+encodeURIComponent(a))};if(!c&&b)g=/\?/.test(b)?/\?$/.test(b)?"":"&":"?",f.push(b),f.push(qq.obj2url(a));else if("[object Array]"===Object.prototype.toString.call(a)&&"undefined"!=typeof a)for(d=-1,e=a.length;e>d;d+=1)h(a[d],d);else if("undefined"!=typeof a&&null!==a&&"object"==typeof a)for(d in a)a.hasOwnProperty(d)&&h(a[d],d);else f.push(encodeURIComponent(b)+"="+encodeURIComponent(a));return b?f.join(g):f.join(g).replace(/^&/,"").replace(/%20/g,"+")},qq.obj2FormData=function(a,b,c){"use strict";return b||(b=new FormData),qq.each(a,function(a,d){a=c?c+"["+a+"]":a,qq.isObject(d)?qq.obj2FormData(d,b,a):qq.isFunction(d)?b.append(a,d()):b.append(a,d)}),b},qq.obj2Inputs=function(a,b){"use strict";var c;return b||(b=document.createElement("form")),qq.obj2FormData(a,{append:function(a,d){c=document.createElement("input"),c.setAttribute("name",a),c.setAttribute("value",d),b.appendChild(c)}}),b},qq.setCookie=function(a,b,c){var d=new Date,e="";c&&(d.setTime(d.getTime()+1e3*60*60*24*c),e="; expires="+d.toGMTString()),document.cookie=a+"="+b+e+"; path=/"},qq.getCookie=function(a){var b,c=a+"=",d=document.cookie.split(";");return qq.each(d,function(a,d){for(var e=d;" "==e.charAt(0);)e=e.substring(1,e.length);return 0===e.indexOf(c)?(b=e.substring(c.length,e.length),!1):void 0}),b},qq.getCookieNames=function(a){var b=document.cookie.split(";"),c=[];return qq.each(b,function(b,d){d=qq.trimStr(d);var e=d.indexOf("=");d.match(a)&&c.push(d.substr(0,e))}),c},qq.deleteCookie=function(a){qq.setCookie(a,"",-1)},qq.areCookiesEnabled=function(){var a=1e5*Math.random(),b="qqCookieTest:"+a;return qq.setCookie(b,1),qq.getCookie(b)?(qq.deleteCookie(b),!0):!1},qq.parseJson=function(json){return window.JSON&&qq.isFunction(JSON.parse)?JSON.parse(json):eval("("+json+")")},qq.DisposeSupport=function(){"use strict";var a=[];return{dispose:function(){var b;do b=a.shift(),b&&b();while(b)},attach:function(){var a=arguments;this.addDisposer(qq(a[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(b){a.push(b)}}},qq.version="3.7.1",qq.supportedFeatures=function(){function a(){var a,b=!0;try{a=document.createElement("input"),a.type="file",qq(a).hide(),a.disabled&&(b=!1)}catch(c){b=!1}return b}function b(){return qq.chrome()&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function c(){return qq.chrome()&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function d(){if(window.XMLHttpRequest){var a=new XMLHttpRequest;return void 0!==a.withCredentials}return!1}function e(){return void 0!==window.XDomainRequest}function f(){return d()?!0:e()}var g,h,i,j,k,l,m,n,o,p;return g=a(),h=g&&qq.isXhrUploadSupported(),i=h&&b(),j=h&&qq.isFileChunkingSupported(),k=h&&j&&qq.areCookiesEnabled(),l=h&&c(),m=g&&(void 0!==window.postMessage||h),o=d(),n=e(),p=f(),{uploading:g,ajaxUploading:h,fileDrop:h,folderDrop:i,chunking:j,resume:k,uploadCustomHeaders:h,uploadNonMultipart:h,itemSizeValidation:h,uploadViaPaste:l,progressBar:h,uploadCors:m,deleteFileCorsXhr:o,deleteFileCorsXdr:n,deleteFileCors:p,canDetermineSize:h}}(),qq.Promise=function(){"use strict";var a,b,c=[],d=[],e=[],f=0;return{then:function(e,g){return 0===f?(e&&c.push(e),g&&d.push(g)):-1===f&&g?g(b):e&&e(a),this},done:function(a){return 0===f?e.push(a):a(),this},success:function(b){return f=1,a=b,c.length&&qq.each(c,function(a,c){c(b)}),e.length&&qq.each(e,function(a,b){b()}),this},failure:function(a){return f=-1,b=a,d.length&&qq.each(d,function(b,c){c(a)}),e.length&&qq.each(e,function(a,b){b()}),this}}},qq.isPromise=function(a){return a&&a.then&&a.done},qq.UploadButton=function(a){"use strict";function b(){var a=document.createElement("input");return e.multiple&&a.setAttribute("multiple","multiple"),e.acceptFiles&&a.setAttribute("accept",e.acceptFiles),a.setAttribute("type","file"),a.setAttribute("name",e.name),qq(a).css({position:"absolute",right:0,top:0,fontFamily:"Arial",fontSize:"118px",margin:0,padding:0,cursor:"pointer",opacity:0}),e.element.appendChild(a),d.attach(a,"change",function(){e.onChange(a)}),d.attach(a,"mouseover",function(){qq(e.element).addClass(e.hoverClass)}),d.attach(a,"mouseout",function(){qq(e.element).removeClass(e.hoverClass)}),d.attach(a,"focus",function(){qq(e.element).addClass(e.focusClass)}),d.attach(a,"blur",function(){qq(e.element).removeClass(e.focusClass)}),window.attachEvent&&a.setAttribute("tabIndex","-1"),a}var c,d=new qq.DisposeSupport,e={element:null,multiple:!1,acceptFiles:null,name:"qqfile",onChange:function(){},hoverClass:"qq-upload-button-hover",focusClass:"qq-upload-button-focus"};return qq.extend(e,a),qq(e.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),c=b(),{getInput:function(){return c},reset:function(){c.parentNode&&qq(c).remove(),qq(e.element).removeClass(e.focusClass),c=b()}}},qq.PasteSupport=function(a){"use strict";function b(a){return a.type&&0===a.type.indexOf("image/")}function c(){qq(e.targetElement).attach("paste",function(a){var c=a.clipboardData;c&&qq.each(c.items,function(a,c){if(b(c)){var d=c.getAsFile();e.callbacks.pasteReceived(d)}})})}function d(){f&&f()}var e,f;return e={targetElement:null,callbacks:{log:function(){},pasteReceived:function(){}}},qq.extend(e,a),c(),{reset:function(){d()}}},qq.UploadData=function(a){function b(a){if(qq.isArray(a)){var b=[];return qq.each(a,function(a,c){b.push(f[g[c]])}),b}return f[g[a]]}function c(a){if(qq.isArray(a)){var b=[];return qq.each(a,function(a,c){b.push(f[h[c]])}),b}return f[h[a]]}function d(a){var b=[],c=[].concat(a);return qq.each(c,function(a,c){var d=i[c];void 0!==d&&qq.each(d,function(a,c){b.push(f[c])})}),b}var e,f=[],g={},h={},i={};return e={added:function(b){var c=a.getUuid(b),d=a.getName(b),e=a.getSize(b),j=qq.status.SUBMITTING,k=f.push({id:b,name:d,originalName:d,uuid:c,size:e,status:j})-1;g[b]=k,h[c]=k,void 0===i[j]&&(i[j]=[]),i[j].push(k),a.onStatusChange(b,void 0,j)},retrieve:function(a){return qq.isObject(a)&&f.length?void 0!==a.id?b(a.id):void 0!==a.uuid?c(a.uuid):a.status?d(a.status):void 0:qq.extend([],f,!0)},reset:function(){f=[],g={},h={},i={}},setStatus:function(b,c){var d=g[b],e=f[d].status,h=qq.indexOf(i[e],d);i[e].splice(h,1),f[d].status=c,void 0===i[c]&&(i[c]=[]),i[c].push(d),a.onStatusChange(b,e,c)},uuidChanged:function(a,b){var c=g[a],d=f[c].uuid;f[c].uuid=b,h[b]=c,delete h[d]},nameChanged:function(a,b){var c=g[a];f[c].name=b}}},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",UPLOADING:"uploading",UPLOAD_RETRYING:"retrying upload",UPLOAD_SUCCESSFUL:"upload successful",UPLOAD_FAILED:"upload failed",DELETE_FAILED:"delete failed",DELETING:"deleting",DELETED:"deleted"},qq.FineUploaderBasic=function(a){this._options={debug:!1,button:null,multiple:!0,maxConnections:3,disableCancelForFormUploads:!1,autoUpload:!0,request:{endpoint:"/server/upload",params:{},paramsInBody:!0,customHeaders:{},forceMultipart:!0,inputName:"qqfile",uuidName:"qquuid",totalFileSizeName:"qqtotalfilesize",filenameParam:"qqfilename"},validation:{allowedExtensions:[],sizeLimit:0,minSizeLimit:0,itemLimit:0,stopOnFirstInvalidFile:!0,acceptFiles:null},callbacks:{onSubmit:function(){},onSubmitted:function(){},onComplete:function(){},onCancel:function(){},onUpload:function(){},onUploadChunk:function(){},onResume:function(){},onProgress:function(){},onError:function(){},onAutoRetry:function(){},onManualRetry:function(){},onValidateBatch:function(){},onValidate:function(){},onSubmitDelete:function(){},onDelete:function(){},onDeleteComplete:function(){},onPasteReceived:function(){},onStatusChange:function(){}},messages:{typeError:"{file} has an invalid extension. Valid extension(s): {extensions}.",sizeError:"{file} is too large, maximum file size is {sizeLimit}.",minSizeError:"{file} is too small, minimum file size is {minSizeLimit}.",emptyError:"{file} is empty, please select files again without it.",noFilesError:"No files to upload.",tooManyItemsError:"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.",retryFailTooManyItems:"Retry failed - you have reached your file limit.",onLeave:"The files are being uploaded, if you leave now the upload will be cancelled."},retry:{enableAuto:!1,maxAutoAttempts:3,autoAttemptDelay:5,preventRetryResponseProperty:"preventRetry"},classes:{buttonHover:"qq-upload-button-hover",buttonFocus:"qq-upload-button-focus"},chunking:{enabled:!1,partSize:2e6,paramNames:{partIndex:"qqpartindex",partByteOffset:"qqpartbyteoffset",chunkSize:"qqchunksize",totalFileSize:"qqtotalfilesize",totalParts:"qqtotalparts"}},resume:{enabled:!1,id:null,cookiesExpireIn:7,paramNames:{resuming:"qqresume"}},formatFileName:function(a){return void 0!==a&&a.length>33&&(a=a.slice(0,19)+"..."+a.slice(-14)),a},text:{defaultResponseError:"Upload failure reason unknown",sizeSymbols:["kB","MB","GB","TB","PB","EB"]},deleteFile:{enabled:!1,method:"DELETE",endpoint:"/server/upload",customHeaders:{},params:{}},cors:{expected:!1,sendCredentials:!1,allowXdr:!1},blobs:{defaultName:"misc_data"},paste:{targetElement:null,defaultName:"pasted_image"},camera:{ios:!1}},qq.extend(this._options,a,!0),this._handleCameraAccess(),this._wrapCallbacks(),this._disposeSupport=new qq.DisposeSupport,this._filesInProgress=[],this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._netUploadedOrQueued=0,this._netUploaded=0,this._uploadData=this._createUploadDataTracker(),this._paramsStore=this._createParamsStore("request"),this._deleteFileParamsStore=this._createParamsStore("deleteFile"),this._endpointStore=this._createEndpointStore("request"),this._deleteFileEndpointStore=this._createEndpointStore("deleteFile"),this._handler=this._createUploadHandler(),this._deleteHandler=this._createDeleteHandler(),this._options.button&&(this._button=this._createUploadButton(this._options.button)),this._options.paste.targetElement&&(this._pasteHandler=this._createPasteHandler()),this._preventLeaveInProgress()},qq.FineUploaderBasic.prototype={log:function(a,b){!this._options.debug||b&&"info"!==b?b&&"info"!==b&&qq.log("[FineUploader "+qq.version+"] "+a,b):qq.log("[FineUploader "+qq.version+"] "+a)},setParams:function(a,b){null==b?this._options.request.params=a:this._paramsStore.setParams(a,b)},setDeleteFileParams:function(a,b){null==b?this._options.deleteFile.params=a:this._deleteFileParamsStore.setParams(a,b)},setEndpoint:function(a,b){null==b?this._options.request.endpoint=a:this._endpointStore.setEndpoint(a,b)},getInProgress:function(){return this._filesInProgress.length},getNetUploads:function(){return this._netUploaded},uploadStoredFiles:function(){var a;if(0===this._storedIds.length)this._itemError("noFilesError");else for(;this._storedIds.length;)a=this._storedIds.shift(),this._filesInProgress.push(a),this._handler.upload(a)},clearStoredFiles:function(){this._storedIds=[]},retry:function(a){return this._onBeforeManualRetry(a)?(this._netUploadedOrQueued++,this._uploadData.setStatus(a,qq.status.UPLOAD_RETRYING),this._handler.retry(a),!0):!1},cancel:function(a){this._handler.cancel(a)},cancelAll:function(){var a=[],b=this;qq.extend(a,this._storedIds),qq.each(a,function(a,c){b.cancel(c)}),this._handler.cancelAll()},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._filesInProgress=[],this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._button.reset(),this._paramsStore.reset(),this._endpointStore.reset(),this._netUploadedOrQueued=0,this._netUploaded=0,this._uploadData.reset(),this._pasteHandler&&this._pasteHandler.reset()},addFiles:function(a,b,c){var d,e,f,g=this,h=[];if(a){for(qq.isFileList(a)||(a=[].concat(a)),d=0;d<a.length;d+=1)if(e=a[d],qq.isFileOrInput(e))if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading)for(f=0;f<e.files.length;f++)h.push(e.files[f]);else h.push(e);else g.log(e+" is not a File or INPUT element! Ignoring!","warn");this.log("Received "+h.length+" files or inputs."),this._prepareItemsForUpload(h,b,c)}},addBlobs:function(a,b,c){if(a){var d=[].concat(a),e=[],f=this;qq.each(d,function(a,b){qq.isBlob(b)&&!qq.isFileOrInput(b)?e.push({blob:b,name:f._options.blobs.defaultName}):qq.isObject(b)&&b.blob&&b.name?e.push(b):f.log("addBlobs: entry at index "+a+" is not a Blob or a BlobData object","error")}),this._prepareItemsForUpload(e,b,c)}else this.log("undefined or non-array parameter passed into addBlobs","error")},getUuid:function(a){return this._handler.getUuid(a)},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(a){return this._handler.getSize(a)},getName:function(a){return this._handler.getName(a)},setName:function(a,b){this._handler.setName(a,b),this._uploadData.nameChanged(a,b)},getFile:function(a){return this._handler.getFile(a)},deleteFile:function(a){this._onSubmitDelete(a)},setDeleteFileEndpoint:function(a,b){null==b?this._options.deleteFile.endpoint=a:this._deleteFileEndpointStore.setEndpoint(a,b)},doesExist:function(a){return this._handler.isValid(a)},getUploads:function(a){return this._uploadData.retrieve(a)},_handleCheckedCallback:function(a){var b=this,c=a.callback();return qq.isPromise(c)?(this.log(a.name+" - waiting for "+a.name+" promise to be fulfilled for "+a.identifier),c.then(function(c){b.log(a.name+" promise success for "+a.identifier),a.onSuccess(c)},function(){a.onFailure?(b.log(a.name+" promise failure for "+a.identifier),a.onFailure()):b.log(a.name+" promise failure for "+a.identifier)})):(c!==!1?a.onSuccess(c):a.onFailure?(this.log(a.name+" - return value was 'false' for "+a.identifier+". Invoking failure callback."),a.onFailure()):this.log(a.name+" - return value was 'false' for "+a.identifier+". Will not proceed."),c)},_createUploadButton:function(a){var b=this,c=new qq.UploadButton({element:a,multiple:this._options.multiple&&qq.supportedFeatures.ajaxUploading,acceptFiles:this._options.validation.acceptFiles,onChange:function(a){b._onInputChange(a)},hoverClass:this._options.classes.buttonHover,focusClass:this._options.classes.buttonFocus});return this._disposeSupport.addDisposer(function(){c.dispose()}),c},_createUploadHandler:function(){var a=this;return new qq.UploadHandler({debug:this._options.debug,forceMultipart:this._options.request.forceMultipart,maxConnections:this._options.maxConnections,customHeaders:this._options.request.customHeaders,inputName:this._options.request.inputName,uuidParamName:this._options.request.uuidName,filenameParam:this._options.request.filenameParam,totalFileSizeParamName:this._options.request.totalFileSizeName,cors:this._options.cors,demoMode:this._options.demoMode,paramsInBody:this._options.request.paramsInBody,paramsStore:this._paramsStore,endpointStore:this._endpointStore,chunking:this._options.chunking,resume:this._options.resume,blobs:this._options.blobs,log:function(b,c){a.log(b,c)},onProgress:function(b,c,d,e){a._onProgress(b,c,d,e),a._options.callbacks.onProgress(b,c,d,e)},onComplete:function(b,c,d,e){a._onComplete(b,c,d,e),a._options.callbacks.onComplete(b,c,d,e)},onCancel:function(b,c){return a._handleCheckedCallback({name:"onCancel",callback:qq.bind(a._options.callbacks.onCancel,a,b,c),onSuccess:qq.bind(a._onCancel,a,b,c),identifier:b})},onUpload:function(b,c){a._onUpload(b,c),a._options.callbacks.onUpload(b,c)},onUploadChunk:function(b,c,d){a._options.callbacks.onUploadChunk(b,c,d)},onResume:function(b,c,d){return a._options.callbacks.onResume(b,c,d)},onAutoRetry:function(b,c,d,e){return a._preventRetries[b]=d[a._options.retry.preventRetryResponseProperty],a._shouldAutoRetry(b,c,d)?(a._maybeParseAndSendUploadError(b,c,d,e),a._options.callbacks.onAutoRetry(b,c,a._autoRetries[b]+1),a._onBeforeAutoRetry(b,c),a._retryTimeouts[b]=setTimeout(function(){a._onAutoRetry(b,c,d)},1e3*a._options.retry.autoAttemptDelay),!0):!1},onUuidChanged:function(b,c){a._uploadData.uuidChanged(b,c)}})},_createDeleteHandler:function(){var a=this;return new qq.DeleteFileAjaxRequestor({method:this._options.deleteFile.method,maxConnections:this._options.maxConnections,uuidParamName:this._options.request.uuidName,customHeaders:this._options.deleteFile.customHeaders,paramsStore:this._deleteFileParamsStore,endpointStore:this._deleteFileEndpointStore,demoMode:this._options.demoMode,cors:this._options.cors,log:function(b,c){a.log(b,c)},onDelete:function(b){a._onDelete(b),a._options.callbacks.onDelete(b)},onDeleteComplete:function(b,c,d){a._onDeleteComplete(b,c,d),a._options.callbacks.onDeleteComplete(b,c,d)}})},_createPasteHandler:function(){var a=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:function(b,c){a.log(b,c)},pasteReceived:function(b){a._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(a._options.callbacks.onPasteReceived,a,b),onSuccess:qq.bind(a._handlePasteSuccess,a,b),identifier:"pasted image"})}}})},_createUploadDataTracker:function(){var a=this;return new qq.UploadData({getName:function(b){return a.getName(b)},getUuid:function(b){return a.getUuid(b)},getSize:function(b){return a.getSize(b)},onStatusChange:function(b,c,d){a._onUploadStatusChange(b,c,d),a._options.callbacks.onStatusChange(b,c,d)}})},_onUploadStatusChange:function(){},_handlePasteSuccess:function(a,b){var c=a.type.split("/")[1],d=b;null==d&&(d=this._options.paste.defaultName),d+="."+c,this.addBlobs({name:d,blob:a})},_preventLeaveInProgress:function(){var a=this;this._disposeSupport.attach(window,"beforeunload",function(b){if(a._filesInProgress.length){var b=b||window.event;return b.returnValue=a._options.messages.onLeave,a._options.messages.onLeave}})},_onSubmit:function(a){this._netUploadedOrQueued++,this._options.autoUpload&&this._filesInProgress.push(a)},_onProgress:function(){},_onComplete:function(a,b,c,d){c.success?(this._netUploaded++,this._uploadData.setStatus(a,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(a,qq.status.UPLOAD_FAILED)),this._removeFromFilesInProgress(a),this._maybeParseAndSendUploadError(a,b,c,d)},_onCancel:function(a){this._netUploadedOrQueued--,this._removeFromFilesInProgress(a),clearTimeout(this._retryTimeouts[a]);var b=qq.indexOf(this._storedIds,a);!this._options.autoUpload&&b>=0&&this._storedIds.splice(b,1),this._uploadData.setStatus(a,qq.status.CANCELED)},_isDeletePossible:function(){return this._options.deleteFile.enabled?this._options.cors.expected?qq.supportedFeatures.deleteFileCorsXhr?!0:qq.supportedFeatures.deleteFileCorsXdr&&this._options.cors.allowXdr?!0:!1:!0:!1},_onSubmitDelete:function(a,b){return this._isDeletePossible()?this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,a),onSuccess:b||qq.bind(this._deleteHandler.sendDelete,this,a,this.getUuid(a)),identifier:a}):(this.log("Delete request ignored for ID "+a+", delete feature is disabled or request not possible "+"due to CORS on a user agent that does not support pre-flighting.","warn"),!1)},_onDelete:function(a){this._uploadData.setStatus(a,qq.status.DELETING)},_onDeleteComplete:function(a,b,c){var d=this._handler.getName(a);c?(this._uploadData.setStatus(a,qq.status.DELETE_FAILED),this.log("Delete request for '"+d+"' has failed.","error"),void 0===b.withCredentials?this._options.callbacks.onError(a,d,"Delete request failed",b):this._options.callbacks.onError(a,d,"Delete request failed with response code "+b.status,b)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(a),this._uploadData.setStatus(a,qq.status.DELETED),this.log("Delete request for '"+d+"' has succeeded."))},_removeFromFilesInProgress:function(a){var b=qq.indexOf(this._filesInProgress,a);b>=0&&this._filesInProgress.splice(b,1)},_onUpload:function(a){this._uploadData.setStatus(a,qq.status.UPLOADING)},_onInputChange:function(a){qq.supportedFeatures.ajaxUploading?this.addFiles(a.files):this.addFiles(a),this._button.reset()},_onBeforeAutoRetry:function(a,b){this.log("Waiting "+this._options.retry.autoAttemptDelay+" seconds before retrying "+b+"...")},_onAutoRetry:function(a,b){this.log("Retrying "+b+"..."),this._autoRetries[a]++,this._uploadData.setStatus(a,qq.status.UPLOAD_RETRYING),this._handler.retry(a)},_shouldAutoRetry:function(a){return!this._preventRetries[a]&&this._options.retry.enableAuto?(void 0===this._autoRetries[a]&&(this._autoRetries[a]=0),this._autoRetries[a]<this._options.retry.maxAutoAttempts):!1},_onBeforeManualRetry:function(a){var b=this._options.validation.itemLimit;if(this._preventRetries[a])return this.log("Retries are forbidden for id "+a,"warn"),!1;if(this._handler.isValid(a)){var c=this._handler.getName(a);return this._options.callbacks.onManualRetry(a,c)===!1?!1:b>0&&this._netUploadedOrQueued+1>b?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+c+"' (id: "+a+")..."),this._filesInProgress.push(a),!0)}return this.log("'"+a+"' is not a valid file ID","error"),!1},_maybeParseAndSendUploadError:function(a,b,c,d){if(!c.success)if(d&&200!==d.status&&!c.error)this._options.callbacks.onError(a,b,"XHR returned response code "+d.status,d);else{var e=c.error?c.error:this._options.text.defaultResponseError;this._options.callbacks.onError(a,b,e,d)}},_prepareItemsForUpload:function(a,b,c){var d=this._getValidationDescriptors(a);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,d),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,d,a,b,c),identifier:"batch validation"})},_upload:function(a,b,c){var d=this._handler.add(a),e=this._handler.getName(d);this._uploadData.added(d),b&&this.setParams(b,d),c&&this.setEndpoint(c,d),this._handleCheckedCallback({name:"onSubmit",callback:qq.bind(this._options.callbacks.onSubmit,this,d,e),onSuccess:qq.bind(this._onSubmitCallbackSuccess,this,d,e),onFailure:qq.bind(this._fileOrBlobRejected,this,d,e),identifier:d})},_onSubmitCallbackSuccess:function(a){this._uploadData.setStatus(a,qq.status.SUBMITTED),this._onSubmit.apply(this,arguments),this._onSubmitted.apply(this,arguments),this._options.callbacks.onSubmitted.apply(this,arguments),this._options.autoUpload?this._handler.upload(a)||this._uploadData.setStatus(a,qq.status.QUEUED):this._storeForLater(a)},_onSubmitted:function(){},_storeForLater:function(a){this._storedIds.push(a)},_onValidateBatchCallbackSuccess:function(a,b,c,d){var e,f=this._options.validation.itemLimit,g=this._netUploadedOrQueued+a.length;0===f||f>=g?b.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,b[0]),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,b,0,c,d),onFailure:qq.bind(this._onValidateCallbackFailure,this,b,0,c,d),identifier:"Item '"+b[0].name+"', size: "+b[0].size}):this._itemError("noFilesError"):(e=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,g).replace(/\{itemLimit\}/g,f),this._batchError(e))},_onValidateCallbackSuccess:function(a,b,c,d){var e=b+1,f=this._getValidationDescriptor(a[b]),g=!1;this._validateFileOrBlobData(a[b],f)&&(g=!0,this._upload(a[b],c,d)),this._maybeProcessNextItemAfterOnValidateCallback(g,a,e,c,d)},_onValidateCallbackFailure:function(a,b,c,d){var e=b+1;this._fileOrBlobRejected(void 0,a[0].name),this._maybeProcessNextItemAfterOnValidateCallback(!1,a,e,c,d)},_maybeProcessNextItemAfterOnValidateCallback:function(a,b,c,d,e){var f=this;b.length>c&&(a||!this._options.validation.stopOnFirstInvalidFile)&&setTimeout(function(){var a=f._getValidationDescriptor(b[c]);f._handleCheckedCallback({name:"onValidate",callback:qq.bind(f._options.callbacks.onValidate,f,b[c]),onSuccess:qq.bind(f._onValidateCallbackSuccess,f,b,c,d,e),onFailure:qq.bind(f._onValidateCallbackFailure,f,b,c,d,e),identifier:"Item '"+a.name+"', size: "+a.size})},0)},_validateFileOrBlobData:function(a,b){var c=b.name,d=b.size,e=!0;return this._options.callbacks.onValidate(b)===!1&&(e=!1),qq.isFileOrInput(a)&&!this._isAllowedExtension(c)?(this._itemError("typeError",c),e=!1):0===d?(this._itemError("emptyError",c),e=!1):d&&this._options.validation.sizeLimit&&d>this._options.validation.sizeLimit?(this._itemError("sizeError",c),e=!1):d&&d<this._options.validation.minSizeLimit&&(this._itemError("minSizeError",c),e=!1),e||this._fileOrBlobRejected(void 0,c),e},_fileOrBlobRejected:function(a){void 0!==a&&this._uploadData.setStatus(a,qq.status.REJECTED)},_itemError:function(a,b){function c(a,b){f=f.replace(a,b)}var d,e,f=this._options.messages[a],g=[],h=[].concat(b),i=h[0];return qq.each(this._options.validation.allowedExtensions,function(a,b){qq.isString(b)&&g.push(b)}),d=g.join(", ").toLowerCase(),c("{file}",this._options.formatFileName(i)),c("{extensions}",d),c("{sizeLimit}",this._formatSize(this._options.validation.sizeLimit)),c("{minSizeLimit}",this._formatSize(this._options.validation.minSizeLimit)),e=f.match(/(\{\w+\})/g),null!==e&&qq.each(e,function(a,b){c(b,h[a])}),this._options.callbacks.onError(null,i,f,void 0),f},_batchError:function(a){this._options.callbacks.onError(null,null,a,void 0)},_isAllowedExtension:function(a){var b=this._options.validation.allowedExtensions,c=!1;return b.length?(qq.each(b,function(b,d){if(qq.isString(d)){var e=new RegExp("\\."+d+"$","i");if(null!=a.match(e))return c=!0,!1}}),c):!0},_formatSize:function(a){var b=-1;do a/=1e3,b++;while(a>999);return Math.max(a,.1).toFixed(1)+this._options.text.sizeSymbols[b]},_wrapCallbacks:function(){var a,b;a=this,b=function(b,c,d){try{return c.apply(a,d)}catch(e){a.log("Caught exception in '"+b+"' callback - "+e.message,"error")}};for(var c in this._options.callbacks)!function(){var d,e;d=c,e=a._options.callbacks[d],a._options.callbacks[d]=function(){return b(d,e,arguments)}}()},_parseFileOrBlobDataName:function(a){var b;return b=qq.isFileOrInput(a)?a.value?a.value.replace(/.*(\/|\\)/,""):null!==a.fileName&&void 0!==a.fileName?a.fileName:a.name:a.name},_parseFileOrBlobDataSize:function(a){var b;return qq.isFileOrInput(a)?a.value||(b=null!==a.fileSize&&void 0!==a.fileSize?a.fileSize:a.size):b=a.blob.size,b},_getValidationDescriptor:function(a){var b,c,d;return d={},b=this._parseFileOrBlobDataName(a),c=this._parseFileOrBlobDataSize(a),d.name=b,void 0!==c&&(d.size=c),d},_getValidationDescriptors:function(a){var b=this,c=[];return qq.each(a,function(a,d){c.push(b._getValidationDescriptor(d))
|
17 |
+
}),c},_createParamsStore:function(a){var b={},c=this;return{setParams:function(a,c){var d={};qq.extend(d,a),b[c]=d},getParams:function(d){var e={};return null!=d&&b[d]?qq.extend(e,b[d]):qq.extend(e,c._options[a].params),e},remove:function(a){return delete b[a]},reset:function(){b={}}}},_createEndpointStore:function(a){var b={},c=this;return{setEndpoint:function(a,c){b[c]=a},getEndpoint:function(d){return null!=d&&b[d]?b[d]:c._options[a].endpoint},remove:function(a){return delete b[a]},reset:function(){b={}}}},_handleCameraAccess:function(){this._options.camera.ios&&qq.ios()&&(this._options.multiple=!1,null===this._options.validation.acceptFiles?this._options.validation.acceptFiles="image/*;capture=camera":this._options.validation.acceptFiles+=",image/*;capture=camera")}},qq.DragAndDrop=function(a){"use strict";function b(a){h.callbacks.dropLog("Grabbed "+a.length+" dropped files."),i.dropDisabled(!1),h.callbacks.processingDroppedFilesComplete(a)}function c(a){var b,d,e=new qq.Promise;return a.isFile?a.file(function(a){j.push(a),e.success()},function(b){h.callbacks.dropLog("Problem parsing '"+a.fullPath+"'. FileError code "+b.code+".","error"),e.failure()}):a.isDirectory&&(b=a.createReader(),b.readEntries(function(a){var b=a.length;for(d=0;d<a.length;d+=1)c(a[d]).done(function(){b-=1,0===b&&e.success()});a.length||e.success()},function(b){h.callbacks.dropLog("Problem parsing '"+a.fullPath+"'. FileError code "+b.code+".","error"),e.failure()})),e}function d(a){var b,d,e,f=[],g=new qq.Promise;if(h.callbacks.processingDroppedFiles(),i.dropDisabled(!0),a.files.length>1&&!h.allowMultipleItems)h.callbacks.processingDroppedFilesComplete([]),h.callbacks.dropError("tooManyFilesError",""),i.dropDisabled(!1),g.failure();else{if(j=[],qq.isFolderDropSupported(a))for(d=a.items,b=0;b<d.length;b+=1)e=d[b].webkitGetAsEntry(),e&&(e.isFile?j.push(d[b].getAsFile()):f.push(c(e).done(function(){f.pop(),0===f.length&&g.success()})));else j=a.files;0===f.length&&g.success()}return g}function e(a){i=new qq.UploadDropZone({element:a,onEnter:function(b){qq(a).addClass(h.classes.dropActive),b.stopPropagation()},onLeaveNotDescendants:function(){qq(a).removeClass(h.classes.dropActive)},onDrop:function(c){h.hideDropZonesBeforeEnter&&qq(a).hide(),qq(a).removeClass(h.classes.dropActive),d(c.dataTransfer).done(function(){b(j)})}}),k.addDisposer(function(){i.dispose()}),h.hideDropZonesBeforeEnter&&qq(a).hide()}function f(a){var b;return qq.each(a.dataTransfer.types,function(a,c){return"Files"===c?(b=!0,!1):void 0}),b}function g(){var a=h.dropZoneElements;qq.each(a,function(a,b){e(b)}),!a.length||qq.ie()&&!qq.ie10()||k.attach(document,"dragenter",function(b){!i.dropDisabled()&&f(b)&&qq.each(a,function(a,b){qq(b).css({display:"block"})})}),k.attach(document,"dragleave",function(b){h.hideDropZonesBeforeEnter&&qq.FineUploader.prototype._leaving_document_out(b)&&qq.each(a,function(a,b){qq(b).hide()})}),k.attach(document,"drop",function(b){h.hideDropZonesBeforeEnter&&qq.each(a,function(a,b){qq(b).hide()}),b.preventDefault()})}var h,i,j=[],k=new qq.DisposeSupport;return h={dropZoneElements:[],hideDropZonesBeforeEnter:!1,allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(h,a,!0),g(),{setupExtraDropzone:function(a){h.dropZoneElements.push(a),e(a)},removeDropzone:function(a){var b,c=h.dropZoneElements;for(b in c)if(c[b]===a)return c.splice(b,1)},dispose:function(){k.dispose(),i.dispose()}}},qq.DragAndDrop.callbacks=function(){return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(){},dropError:function(a,b){qq.log("Drag & drop error code '"+a+" with these specifics: '"+b+"'","error")},dropLog:function(a,b){qq.log(a,b)}}},qq.UploadDropZone=function(a){"use strict";function b(){return qq.safari()||qq.firefox()&&qq.windows()}function c(){j||(b?k.attach(document,"dragover",function(a){a.preventDefault()}):k.attach(document,"dragover",function(a){a.dataTransfer&&(a.dataTransfer.dropEffect="none",a.preventDefault())}),j=!0)}function d(a){if(qq.ie()&&!qq.ie10())return!1;var b,c=a.dataTransfer,d=qq.safari();return b=qq.ie10()?!0:"none"!==c.effectAllowed,c&&b&&(c.files||!d&&c.types.contains&&c.types.contains("Files"))}function e(a){return void 0!==a&&(i=a),i}function f(){k.attach(h,"dragover",function(a){if(d(a)){var b=qq.ie()?null:a.dataTransfer.effectAllowed;a.dataTransfer.dropEffect="move"===b||"linkMove"===b?"move":"copy",a.stopPropagation(),a.preventDefault()}}),k.attach(h,"dragenter",function(a){if(!e()){if(!d(a))return;g.onEnter(a)}}),k.attach(h,"dragleave",function(a){if(d(a)){g.onLeave(a);var b=document.elementFromPoint(a.clientX,a.clientY);qq(this).contains(b)||g.onLeaveNotDescendants(a)}}),k.attach(h,"drop",function(a){if(!e()){if(!d(a))return;a.preventDefault(),g.onDrop(a)}})}var g,h,i,j,k=new qq.DisposeSupport;return g={element:null,onEnter:function(){},onLeave:function(){},onLeaveNotDescendants:function(){},onDrop:function(){}},qq.extend(g,a),h=g.element,c(),f(),{dropDisabled:function(a){return e(a)},dispose:function(){k.dispose()}}},qq.FineUploader=function(a){qq.FineUploaderBasic.apply(this,arguments),qq.extend(this._options,{element:null,listElement:null,dragAndDrop:{extraDropzones:[],hideDropzones:!0,disableDefaultDropzone:!1},text:{uploadButton:"Upload a file",cancelButton:"Cancel",retryButton:"Retry",deleteButton:"Delete",failUpload:"Upload failed",dragZone:"Drop files here to upload",dropProcessing:"Processing dropped files...",formatProgress:"{percent}% of {total_size}",waitingForResponse:"Processing..."},template:'<div class="qq-uploader">'+(this._options.dragAndDrop&&this._options.dragAndDrop.disableDefaultDropzone?"":'<div class="qq-upload-drop-area"><span>{dragZoneText}</span></div>')+(this._options.button?"":'<div class="qq-upload-button"><div>{uploadButtonText}</div></div>')+'<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>'+(this._options.listElement?"":'<ul class="qq-upload-list"></ul>')+"</div>",fileTemplate:'<li><div class="qq-progress-bar"></div><span class="qq-upload-spinner"></span><span class="qq-upload-finished"></span>'+(this._options.editFilename&&this._options.editFilename.enabled?'<span class="qq-edit-filename-icon"></span>':"")+'<span class="qq-upload-file"></span>'+(this._options.editFilename&&this._options.editFilename.enabled?'<input class="qq-edit-filename" tabindex="0" type="text">':"")+'<span class="qq-upload-size"></span>'+'<a class="qq-upload-cancel" href="#">{cancelButtonText}</a>'+'<a class="qq-upload-retry" href="#">{retryButtonText}</a>'+'<a class="qq-upload-delete" href="#">{deleteButtonText}</a>'+'<span class="qq-upload-status-text">{statusText}</span>'+"</li>",classes:{button:"qq-upload-button",drop:"qq-upload-drop-area",dropActive:"qq-upload-drop-area-active",list:"qq-upload-list",progressBar:"qq-progress-bar",file:"qq-upload-file",spinner:"qq-upload-spinner",finished:"qq-upload-finished",retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",size:"qq-upload-size",cancel:"qq-upload-cancel",deleteButton:"qq-upload-delete",retry:"qq-upload-retry",statusText:"qq-upload-status-text",editFilenameInput:"qq-edit-filename",success:"qq-upload-success",fail:"qq-upload-fail",successIcon:null,failIcon:null,editNameIcon:"qq-edit-filename-icon",editable:"qq-editable",dropProcessing:"qq-drop-processing",dropProcessingSpinner:"qq-drop-processing-spinner"},failedUploadTextDisplay:{mode:"default",maxChars:50,responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}...",showButton:!1},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},editFilename:{enabled:!1},showMessage:function(a){setTimeout(function(){window.alert(a)},0)},showConfirm:function(a,b,c){setTimeout(function(){var d=window.confirm(a);d?b():c&&c()},0)},showPrompt:function(a,b){var c=new qq.Promise,d=window.prompt(a,b);return null!=d&&qq.trimStr(d).length>0?c.success(d):c.failure("Undefined or invalid user-supplied value."),c}},!0),qq.extend(this._options,a,!0),!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._options.element.innerHTML="<div>"+this._options.messages.unsupportedBrowser+"</div>":(this._wrapCallbacks(),this._options.template=this._options.template.replace(/\{dragZoneText\}/g,this._options.text.dragZone),this._options.template=this._options.template.replace(/\{uploadButtonText\}/g,this._options.text.uploadButton),this._options.template=this._options.template.replace(/\{dropProcessingText\}/g,this._options.text.dropProcessing),this._options.fileTemplate=this._options.fileTemplate.replace(/\{cancelButtonText\}/g,this._options.text.cancelButton),this._options.fileTemplate=this._options.fileTemplate.replace(/\{retryButtonText\}/g,this._options.text.retryButton),this._options.fileTemplate=this._options.fileTemplate.replace(/\{deleteButtonText\}/g,this._options.text.deleteButton),this._options.fileTemplate=this._options.fileTemplate.replace(/\{statusText\}/g,""),this._element=this._options.element,this._element.innerHTML=this._options.template,this._listElement=this._options.listElement||this._find(this._element,"list"),this._classes=this._options.classes,this._button||(this._button=this._createUploadButton(this._find(this._element,"button"))),this._deleteRetryOrCancelClickHandler=this._bindDeleteRetryOrCancelClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent()),this._dnd=this._setupDragAndDrop(),this._options.paste.targetElement&&this._options.paste.promptForName&&this._setupPastePrompt(),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.FineUploaderBasic.prototype),qq.extend(qq.FineUploader.prototype,{clearStoredFiles:function(){qq.FineUploaderBasic.prototype.clearStoredFiles.apply(this,arguments),this._listElement.innerHTML=""},addExtraDropzone:function(a){this._dnd.setupExtraDropzone(a)},removeExtraDropzone:function(a){return this._dnd.removeDropzone(a)},getItemByFileId:function(a){for(var b=this._listElement.firstChild;b;){if(b.qqFileId==a)return b;b=b.nextSibling}},reset:function(){qq.FineUploaderBasic.prototype.reset.apply(this,arguments),this._element.innerHTML=this._options.template,this._listElement=this._options.listElement||this._find(this._element,"list"),this._options.button||(this._button=this._createUploadButton(this._find(this._element,"button"))),this._dnd.dispose(),this._dnd=this._setupDragAndDrop(),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0},_removeFileItem:function(a){var b=this.getItemByFileId(a);qq(b).remove()},_setupDragAndDrop:function(){var a,b=this,c=this._find(this._element,"dropProcessing"),d=this._options.dragAndDrop.extraDropzones;return a=function(a){a.preventDefault()},this._options.dragAndDrop.disableDefaultDropzone||d.push(this._find(this._options.element,"drop")),new qq.DragAndDrop({dropZoneElements:d,hideDropZonesBeforeEnter:this._options.dragAndDrop.hideDropzones,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){var d=b._button.getInput();qq(c).css({display:"block"}),qq(d).attach("click",a)},processingDroppedFilesComplete:function(d){var e=b._button.getInput();qq(c).hide(),qq(e).detach("click",a),d&&b.addFiles(d)},dropError:function(a,c){b._itemError(a,c)},dropLog:function(a,c){b.log(a,c)}}})},_bindDeleteRetryOrCancelClickEvent:function(){var a=this;return new qq.DeleteRetryOrCancelClickHandler({listElement:this._listElement,classes:this._classes,log:function(b,c){a.log(b,c)},onDeleteFile:function(b){a.deleteFile(b)},onCancel:function(b){a.cancel(b)},onRetry:function(b){var c=a.getItemByFileId(b);qq(c).removeClass(a._classes.retryable),a.retry(b)},onGetName:function(b){return a.getName(b)}})},_isEditFilenameEnabled:function(){return this._options.editFilename.enabled&&!this._options.autoUpload},_filenameEditHandler:function(){var a=this;return{listElement:this._listElement,classes:this._classes,log:function(b,c){a.log(b,c)},onGetUploadStatus:function(b){return a.getUploads({id:b}).status},onGetName:function(b){return a.getName(b)},onSetName:function(b,c){var d=a.getItemByFileId(b),e=qq(a._find(d,"file")),f=a._options.formatFileName(c);e.setText(f),a.setName(b,c)},onGetInput:function(b){return a._find(b,"editFilenameInput")},onEditingStatusChange:function(b,c){var d=a.getItemByFileId(b),e=qq(a._find(d,"editFilenameInput")),f=qq(a._find(d,"file")),g=qq(a._find(d,"editNameIcon")),h=a._classes.editable;c?(e.addClass("qq-editing"),f.hide(),g.removeClass(h)):(e.removeClass("qq-editing"),f.css({display:""}),g.addClass(h)),qq(d).addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(a,b,c){if(this._isEditFilenameEnabled()){var d,e,f=this.getItemByFileId(a),g=this._classes.editable;f&&c!==qq.status.SUBMITTED&&(d=qq(this._find(f,"file")),e=qq(this._find(f,"editNameIcon")),d.removeClass(g),e.removeClass(g))}},_bindFilenameInputFocusInEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(a)},_bindFilenameInputFocusEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(a)},_bindFilenameClickEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(a)},_leaving_document_out:function(a){return(qq.chrome()||qq.safari()&&qq.windows())&&0==a.clientX&&0==a.clientY||qq.firefox()&&!a.relatedTarget},_storeForLater:function(a){qq.FineUploaderBasic.prototype._storeForLater.apply(this,arguments);var b=this.getItemByFileId(a);qq(this._find(b,"spinner")).hide()},_find:function(a,b){var c=qq(a).getByClass(this._options.classes[b])[0];if(!c)throw new Error("element not found "+b);return c},_onSubmit:function(a,b){qq.FineUploaderBasic.prototype._onSubmit.apply(this,arguments),this._addToList(a,b)},_onSubmitted:function(a){if(this._isEditFilenameEnabled()){var b=this.getItemByFileId(a),c=qq(this._find(b,"file")),d=qq(this._find(b,"editNameIcon")),e=this._classes.editable;c.addClass(e),d.addClass(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._find(b,"editFilenameInput"))}},_onProgress:function(a,b,c,d){qq.FineUploaderBasic.prototype._onProgress.apply(this,arguments);var e,f,g,h;e=this.getItemByFileId(a),f=this._find(e,"progressBar"),g=Math.round(100*(c/d)),c===d?(h=this._find(e,"cancel"),qq(h).hide(),qq(f).hide(),qq(this._find(e,"statusText")).setText(this._options.text.waitingForResponse),this._displayFileSize(a)):(this._displayFileSize(a,c,d),qq(f).css({display:"block"})),qq(f).css({width:g+"%"})},_onComplete:function(a,b,c){qq.FineUploaderBasic.prototype._onComplete.apply(this,arguments);var d=this.getItemByFileId(a);qq(this._find(d,"statusText")).clearText(),qq(d).removeClass(this._classes.retrying),qq(this._find(d,"progressBar")).hide(),(!this._options.disableCancelForFormUploads||qq.supportedFeatures.ajaxUploading)&&qq(this._find(d,"cancel")).hide(),qq(this._find(d,"spinner")).hide(),c.success?(this._isDeletePossible()&&this._showDeleteLink(a),qq(d).addClass(this._classes.success),this._classes.successIcon&&(this._find(d,"finished").style.display="inline-block",qq(d).addClass(this._classes.successIcon))):(qq(d).addClass(this._classes.fail),this._classes.failIcon&&(this._find(d,"finished").style.display="inline-block",qq(d).addClass(this._classes.failIcon)),this._options.retry.showButton&&!this._preventRetries[a]&&qq(d).addClass(this._classes.retryable),this._controlFailureTextDisplay(d,c))},_onUpload:function(a){qq.FineUploaderBasic.prototype._onUpload.apply(this,arguments),this._showSpinner(a)},_onCancel:function(a){qq.FineUploaderBasic.prototype._onCancel.apply(this,arguments),this._removeFileItem(a)},_onBeforeAutoRetry:function(a){var b,c,d,e,f,g;qq.FineUploaderBasic.prototype._onBeforeAutoRetry.apply(this,arguments),b=this.getItemByFileId(a),c=this._find(b,"progressBar"),this._showCancelLink(b),c.style.width=0,qq(c).hide(),this._options.retry.showAutoRetryNote&&(d=this._find(b,"statusText"),e=this._autoRetries[a]+1,f=this._options.retry.maxAutoAttempts,g=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,e),g=g.replace(/\{maxAuto\}/g,f),qq(d).setText(g),1===e&&qq(b).addClass(this._classes.retrying))},_onBeforeManualRetry:function(a){var b=this.getItemByFileId(a);return qq.FineUploaderBasic.prototype._onBeforeManualRetry.apply(this,arguments)?(this._find(b,"progressBar").style.width=0,qq(b).removeClass(this._classes.fail),qq(this._find(b,"statusText")).clearText(),this._showSpinner(a),this._showCancelLink(b),!0):(qq(b).addClass(this._classes.retryable),!1)},_onSubmitDelete:function(a){var b=qq.bind(this._onSubmitDeleteSuccess,this,a);qq.FineUploaderBasic.prototype._onSubmitDelete.call(this,a,b)},_onSubmitDeleteSuccess:function(a){this._options.deleteFile.forceConfirm?this._showDeleteConfirm(a):this._sendDeleteRequest(a)},_onDeleteComplete:function(a,b,c){qq.FineUploaderBasic.prototype._onDeleteComplete.apply(this,arguments);var d=this.getItemByFileId(a),e=this._find(d,"spinner"),f=this._find(d,"statusText");qq(e).hide(),c?(qq(f).setText(this._options.deleteFile.deletingFailedText),this._showDeleteLink(a)):this._removeFileItem(a)},_sendDeleteRequest:function(a){var b=this.getItemByFileId(a),c=this._find(b,"deleteButton"),d=this._find(b,"statusText");qq(c).hide(),this._showSpinner(a),qq(d).setText(this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete(a,this.getUuid(a))},_showDeleteConfirm:function(a){var b=this._handler.getName(a),c=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,b),d=(this.getUuid(a),this);this._options.showConfirm(c,function(){d._sendDeleteRequest(a)})},_addToList:function(a,b){var c=qq.toElement(this._options.fileTemplate);if(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading){var d=this._find(c,"cancel");qq(d).remove()}c.qqFileId=a;var e=this._find(c,"file");qq(e).setText(this._options.formatFileName(b)),qq(this._find(c,"size")).hide(),this._options.multiple||(this._handler.cancelAll(),this._clearList()),this._options.display.prependFiles?this._prependItem(c):this._listElement.appendChild(c),this._filesInBatchAddedToUi+=1,this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading&&this._displayFileSize(a)},_prependItem:function(a){var b=this._listElement,c=b.firstChild;this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(c=qq(b).children()[this._filesInBatchAddedToUi-1].nextSibling),b.insertBefore(a,c)},_clearList:function(){this._listElement.innerHTML="",this.clearStoredFiles()},_displayFileSize:function(a,b,c){var d=this.getItemByFileId(a),e=this.getSize(a),f=this._formatSize(e),g=this._find(d,"size");void 0!==b&&void 0!==c&&(f=this._formatProgress(b,c)),qq(g).css({display:"inline"}),qq(g).setText(f)},_formatProgress:function(a,b){function c(a,b){d=d.replace(a,b)}var d=this._options.text.formatProgress;return c("{percent}",Math.round(100*(a/b))),c("{total_size}",this._formatSize(b)),d},_controlFailureTextDisplay:function(a,b){var c,d,e,f,g;c=this._options.failedUploadTextDisplay.mode,d=this._options.failedUploadTextDisplay.maxChars,e=this._options.failedUploadTextDisplay.responseProperty,"custom"===c?(f=b[e],f?f.length>d&&(g=f.substring(0,d)+"..."):(f=this._options.text.failUpload,this.log("'"+e+"' is not a valid property on the server response.","warn")),qq(this._find(a,"statusText")).setText(g||f),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(a,f)):"default"===c?qq(this._find(a,"statusText")).setText(this._options.text.failUpload):"none"!==c&&this.log("failedUploadTextDisplay.mode value of '"+c+"' is not valid","warn")},_showTooltip:function(a,b){a.title=b},_showSpinner:function(a){var b=this.getItemByFileId(a),c=this._find(b,"spinner");c.style.display="inline-block"},_showCancelLink:function(a){if(!this._options.disableCancelForFormUploads||qq.supportedFeatures.ajaxUploading){var b=this._find(a,"cancel");qq(b).css({display:"inline"})}},_showDeleteLink:function(a){var b=this.getItemByFileId(a),c=this._find(b,"deleteButton");qq(c).css({display:"inline"})},_itemError:function(){var a=qq.FineUploaderBasic.prototype._itemError.apply(this,arguments);this._options.showMessage(a)},_batchError:function(a){qq.FineUploaderBasic.prototype._batchError.apply(this,arguments),this._options.showMessage(a)},_setupPastePrompt:function(){var a=this;this._options.callbacks.onPasteReceived=function(){var b=a._options.paste.namePromptMessage,c=a._options.paste.defaultName;return a._options.showPrompt(b,c)}},_fileOrBlobRejected:function(){this._totalFilesInBatch-=1,qq.FineUploaderBasic.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(a){this._totalFilesInBatch=a.length,this._filesInBatchAddedToUi=0,qq.FineUploaderBasic.prototype._prepareItemsForUpload.apply(this,arguments)}}),qq.AjaxRequestor=function(a){"use strict";function b(){return qq.indexOf(["GET","POST","HEAD"],v.method)>=0}function c(){var a=!1;return qq.each(a,function(b,c){return qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],c)<0?(a=!0,!1):void 0}),a}function d(a){return v.cors.expected&&void 0===a.withCredentials}function e(){var a;return window.XMLHttpRequest&&(a=new XMLHttpRequest,void 0===a.withCredentials&&(a=new XDomainRequest)),a}function f(a,b){var c=u[a].xhr;return c||b||(c=v.cors.expected?e():new XMLHttpRequest,u[a].xhr=c),c}function g(a){var b,c=qq.indexOf(t,a),d=v.maxConnections;delete u[a],t.splice(c,1),t.length>=d&&d>c&&(b=t[d-1],j(b))}function h(a,b){var c=f(a),e=v.method,h=b===!1;g(a),h?r(e+" request for "+a+" has failed","error"):d(c)||q(c.status)||(h=!0,r(e+" request for "+a+" has failed - response code "+c.status,"error")),v.onComplete(a,c,h)}function i(a){var b={},c=u[a].additionalParams,d=v.mandatedParams;return v.paramsStore.getParams&&(b=v.paramsStore.getParams(a)),c&&qq.each(c,function(a,c){b[a]=c}),d&&qq.each(d,function(a,c){b[a]=c}),b}function j(a){var b,c=f(a),e=v.method,g=i(a);v.onSend(a),b=k(a,g),d(c)?(c.onload=m(a),c.onerror=n(a)):c.onreadystatechange=l(a),c.open(e,b,!0),v.cors.expected&&v.cors.sendCredentials&&!d(c)&&(c.withCredentials=!0),o(a),r("Sending "+e+" request for "+a),!s&&g?c.send(qq.obj2url(g,"")):c.send()}function k(a,b){var c=v.endpointStore.getEndpoint(a),d=u[a].addToPath;return void 0!=d&&(c+="/"+d),s&&b?qq.obj2url(b,c):c}function l(a){return function(){4===f(a).readyState&&h(a)}}function m(a){return function(){h(a)}}function n(a){return function(){h(a,!0)}}function o(a){var e=f(a),g=v.customHeaders;d(e)&&(v.cors.expected&&b()&&!c(g)||(e.setRequestHeader("X-Requested-With","XMLHttpRequest"),e.setRequestHeader("Cache-Control","no-cache"))),"POST"!==v.method&&"PUT"!==v.method||d(e)||e.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),d(e)||qq.each(g,function(a,b){e.setRequestHeader(a,b)})}function p(a){var b=f(a,!0),c=v.method;return b?(d(b)?(b.onerror=null,b.onload=null):b.onreadystatechange=null,b.abort(),g(a),r("Cancelled "+c+" for "+a),v.onCancel(a),!0):!1}function q(a){return qq.indexOf(v.successfulResponseCodes[v.method],a)>=0}var r,s,t=[],u=[],v={method:"POST",maxConnections:3,customHeaders:{},endpointStore:{},paramsStore:{},mandatedParams:{},successfulResponseCodes:{DELETE:[200,202,204],POST:[200,204]},cors:{expected:!1,sendCredentials:!1},log:function(){},onSend:function(){},onComplete:function(){},onCancel:function(){}};return qq.extend(v,a),r=v.log,s="GET"===v.method||"DELETE"===v.method,{send:function(a,b,c){u[a]={addToPath:b,additionalParams:c};var d=t.push(a);d<=v.maxConnections&&j(a)},cancel:function(a){return p(a)}}},qq.DeleteFileAjaxRequestor=function(a){"use strict";function b(){return f.method.toUpperCase()}function c(){return"POST"===b()?{_method:"DELETE"}:{}}var d,e=["POST","DELETE"],f={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:{},paramsStore:{},demoMode:!1,cors:{expected:!1,sendCredentials:!1},log:function(){},onDelete:function(){},onDeleteComplete:function(){}};if(qq.extend(f,a),qq.indexOf(e,b())<0)throw new Error("'"+b()+"' is not a supported method for delete file requests!");return d=new qq.AjaxRequestor({method:b(),endpointStore:f.endpointStore,paramsStore:f.paramsStore,mandatedParams:c(),maxConnections:f.maxConnections,customHeaders:f.customHeaders,demoMode:f.demoMode,log:f.log,onSend:f.onDelete,onComplete:f.onDeleteComplete,cors:f.cors}),{sendDelete:function(a,c){var e={};f.log("Submitting delete file request for "+a),"DELETE"===b()?d.send(a,c):(e[f.uuidParamName]=c,d.send(a,null,e))}}},qq.WindowReceiveMessage=function(a){var b={log:function(){}},c={};return qq.extend(b,a),{receiveMessage:function(a,b){var d=function(a){b(a.data)};window.postMessage?c[a]=qq(window).attach("message",d):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(a){if(window.postMessage){var b=c[a];b&&b()}}}},qq.UploadHandler=function(a){"use strict";function b(a){var b,c=qq.indexOf(h,a),e=d.maxConnections;c>=0&&(h.splice(c,1),h.length>=e&&e>c&&(b=h[e-1],f.upload(b)))}function c(a){e("Cancelling "+a),d.paramsStore.remove(a),b(a)}var d,e,f,g,h=[];return d={debug:!1,forceMultipart:!0,paramsInBody:!1,paramsStore:{},endpointStore:{},filenameParam:"qqfilename",cors:{expected:!1,sendCredentials:!1},maxConnections:3,uuidParamName:"qquuid",totalFileSizeParamName:"qqtotalfilesize",chunking:{enabled:!1,partSize:2e6,paramNames:{partIndex:"qqpartindex",partByteOffset:"qqpartbyteoffset",chunkSize:"qqchunksize",totalParts:"qqtotalparts",filename:"qqfilename"}},resume:{enabled:!1,id:null,cookiesExpireIn:7,paramNames:{resuming:"qqresume"}},log:function(){},onProgress:function(){},onComplete:function(){},onCancel:function(){},onUpload:function(){},onUploadChunk:function(){},onAutoRetry:function(){},onResume:function(){},onUuidChanged:function(){}},qq.extend(d,a),e=d.log,f=qq.supportedFeatures.ajaxUploading?new qq.UploadHandlerXhr(d,b,d.onUuidChanged,e):new qq.UploadHandlerForm(d,b,d.onUuidChanged,e),g={add:function(a){return f.add(a)},upload:function(a){var b=h.push(a);return b<=d.maxConnections?(f.upload(a),!0):!1},retry:function(a){var b=qq.indexOf(h,a);return b>=0?f.upload(a,!0):this.upload(a)},cancel:function(a){var b=f.cancel(a);qq.isPromise(b)?b.then(function(){c(a)}):b!==!1&&c(a)},cancelAll:function(){var a=this,b=[];qq.extend(b,h),qq.each(b,function(b,c){a.cancel(c)}),h=[]},getName:function(a){return f.getName(a)},setName:function(a,b){f.setName(a,b)},getSize:function(a){return f.getSize?f.getSize(a):void 0},getFile:function(a){return f.getFile?f.getFile(a):void 0},reset:function(){e("Resetting upload handler"),g.cancelAll(),h=[],f.reset()},expunge:function(a){return f.expunge(a)},getUuid:function(a){return f.getUuid(a)},isValid:function(a){return f.isValid(a)},getResumableFilesData:function(){return f.getResumableFilesData?f.getResumableFilesData():[]}}},qq.UploadHandlerForm=function(a,b,c,d){"use strict";function e(a){void 0!==t[a]&&(t[a](),delete t[a])}function f(a,b){var c=a.id,d=m(c);y[r[d]]=b,t[d]=qq(a).attach("load",function(){q[d]&&(w("Received iframe load event for CORS upload request (iframe name "+c+")"),u[c]=setTimeout(function(){var a="No valid message received from loaded iframe for iframe name "+c;w(a,"error"),b({error:a})},1e3))}),x.receiveMessage(c,function(a){w("Received the following window message: '"+a+"'");var b,d=i(m(c),a),f=d.uuid;f&&y[f]?(w("Handling response for iframe name "+c),clearTimeout(u[c]),delete u[c],e(c),b=y[f],delete y[f],x.stopReceivingMessages(c),b(d)):f||w("'"+a+"' does not contain a UUID - ignoring.")})}function g(a,b){p.cors.expected?f(a,b):t[a.id]=qq(a).attach("load",function(){if(w("Received response for "+a.id),a.parentNode){try{if(a.contentDocument&&a.contentDocument.body&&"false"==a.contentDocument.body.innerHTML)return}catch(c){w("Error when attempting to access iframe during handling of upload response ("+c+")","error")}b()}})}function h(a,b){var c;try{var d=b.contentDocument||b.contentWindow.document,e=d.body.innerHTML;w("converting iframe's innerHTML to JSON"),w("innerHTML = "+e),e&&e.match(/^<pre/i)&&(e=d.body.firstChild.firstChild.nodeValue),c=i(a,e)}catch(f){w("Error when attempting to parse form upload response ("+f+")","error"),c={success:!1}}return c}function i(a,b){var d;try{d=qq.parseJson(b),void 0!==d.newUuid&&(w("Server requested UUID change from '"+r[a]+"' to '"+d.newUuid+"'"),r[a]=d.newUuid,c(a,d.newUuid))}catch(e){w("Error when attempting to parse iframe upload response ("+e+")","error"),d={}}return d}function j(a){var b=n(a),c=qq.toElement('<iframe src="javascript:false;" name="'+b+'" />');return c.setAttribute("id",b),c.style.display="none",document.body.appendChild(c),c}function k(a,b){var c=p.paramsStore.getParams(a),d=p.demoMode?"GET":"POST",e=qq.toElement('<form method="'+d+'" enctype="multipart/form-data"></form>'),f=p.endpointStore.getEndpoint(a),g=f;return c[p.uuidParamName]=r[a],void 0!==s[a]&&(c[p.filenameParam]=s[a]),p.paramsInBody?qq.obj2Inputs(c,e):g=qq.obj2url(c,f),e.setAttribute("action",g),e.setAttribute("target",b.name),e.style.display="none",document.body.appendChild(e),e}function l(a){delete q[a],delete r[a],delete t[a],p.cors.expected&&(clearTimeout(u[a]),delete u[a],x.stopReceivingMessages(a));var b=document.getElementById(n(a));b&&(b.setAttribute("src","java"+String.fromCharCode(115)+"cript:false;"),qq(b).remove())}function m(a){return a.split("_")[0]}function n(a){return a+"_"+z}var o,p=a,q=[],r=[],s=[],t={},u={},v=b,w=d,x=new qq.WindowReceiveMessage({log:w}),y={},z=qq.getUniqueId();return o={add:function(a){a.setAttribute("name",p.inputName);var b=q.push(a)-1;return r[b]=qq.getUniqueId(),a.parentNode&&qq(a).remove(),b},getName:function(a){return void 0!==s[a]?s[a]:o.isValid(a)?q[a].value.replace(/.*(\/|\\)/,""):(w(a+" is not a valid item ID.","error"),void 0)},setName:function(a,b){s[a]=b},isValid:function(a){return void 0!==q[a]},reset:function(){q=[],r=[],s=[],t={},z=qq.getUniqueId()},expunge:function(a){return l(a)},getUuid:function(a){return r[a]},cancel:function(a){var b=p.onCancel(a,o.getName(a));return qq.isPromise(b)?b.then(function(){l(a)}):b!==!1?(l(a),!0):!1},upload:function(a){var b,c=q[a],d=o.getName(a),f=j(a);if(!c)throw new Error("file with passed id was not added, or already uploaded or cancelled");p.onUpload(a,o.getName(a)),b=k(a,f),b.appendChild(c),g(f,function(b){w("iframe loaded");var c=b?b:h(a,f);e(a),p.cors.expected||qq(f).remove(),(c.success||!p.onAutoRetry(a,d,c))&&(p.onComplete(a,d,c),v(a))}),w("Sending upload request for "+a),b.submit(),qq(b).remove()}}},qq.UploadHandlerXhr=function(a,b,c,d){"use strict";function e(a,b,c){var d=K.getSize(a),e=K.getName(a);b[L.chunking.paramNames.partIndex]=c.part,b[L.chunking.paramNames.partByteOffset]=c.start,b[L.chunking.paramNames.chunkSize]=c.size,b[L.chunking.paramNames.totalParts]=c.count,b[L.totalFileSizeParamName]=d,T&&(b[L.filenameParam]=e)}function f(a){a[L.resume.paramNames.resuming]=!0}function g(a,b,c){return a.slice?a.slice(b,c):a.mozSlice?a.mozSlice(b,c):a.webkitSlice?a.webkitSlice(b,c):void 0}function h(a,b){var c=L.chunking.partSize,d=K.getSize(a),e=O[a].file||O[a].blobData.blob,f=c*b,h=f+c>=d?d:f+c,j=i(a);return{part:b,start:f,end:h,count:j,blob:g(e,f,h),size:h-f}}function i(a){var b=K.getSize(a),c=L.chunking.partSize;return Math.ceil(b/c)}function j(a){var b=new XMLHttpRequest;
|
18 |
+
return O[a].xhr=b,b}function k(a,b,c,d){var e=new FormData,f=L.demoMode?"GET":"POST",g=L.endpointStore.getEndpoint(d),h=g,i=K.getName(d),j=K.getSize(d),k=O[d].blobData,l=O[d].newName;return a[L.uuidParamName]=O[d].uuid,T&&(a[L.totalFileSizeParamName]=j,k&&(a[L.filenameParam]=k.name)),void 0!==l&&(a[L.filenameParam]=l),L.paramsInBody||(T||(a[L.inputName]=l||i),h=qq.obj2url(a,g)),b.open(f,h,!0),L.cors.expected&&L.cors.sendCredentials&&(b.withCredentials=!0),T?(L.paramsInBody&&qq.obj2FormData(a,e),e.append(L.inputName,c),e):c}function l(a,b){var c=L.customHeaders,d=O[a].file||O[a].blobData.blob;b.setRequestHeader("X-Requested-With","XMLHttpRequest"),b.setRequestHeader("Cache-Control","no-cache"),T||(b.setRequestHeader("Content-Type","application/octet-stream"),b.setRequestHeader("X-Mime-Type",d.type)),qq.each(c,function(a,c){b.setRequestHeader(a,c)})}function m(a,b,c){var d=K.getName(a),e=K.getSize(a);O[a].attemptingResume=!1,L.onProgress(a,d,e,e),L.onComplete(a,d,b,c),O[a]&&delete O[a].xhr,M(a)}function n(a){var b,c,d=O[a].remainingChunkIdxs[0],g=h(a,d),i=j(a),m=K.getSize(a),n=K.getName(a);void 0===O[a].loaded&&(O[a].loaded=0),R&&O[a].file&&z(a,g),i.onreadystatechange=y(a,i),i.upload.onprogress=function(b){if(b.lengthComputable){var c=b.loaded+O[a].loaded,e=o(a,d,b.total);L.onProgress(a,n,c,e)}},L.onUploadChunk(a,n,x(g)),c=L.paramsStore.getParams(a),e(a,c,g),O[a].attemptingResume&&f(c),b=k(c,i,g.blob,a),l(a,i),N("Sending chunked upload request for item "+a+": bytes "+(g.start+1)+"-"+g.end+" of "+m),i.send(b)}function o(a,b,c){var d=h(a,b),e=d.size,f=c-e,g=K.getSize(a),i=d.count,j=O[a].initialRequestOverhead,k=f-j;return O[a].lastRequestOverhead=f,0===b?(O[a].lastChunkIdxProgress=0,O[a].initialRequestOverhead=f,O[a].estTotalRequestsSize=g+i*f):O[a].lastChunkIdxProgress!==b&&(O[a].lastChunkIdxProgress=b,O[a].estTotalRequestsSize+=k),O[a].estTotalRequestsSize}function p(a){return T?O[a].lastRequestOverhead:0}function q(a,b,c){var d=O[a].remainingChunkIdxs.shift(),e=h(a,d);O[a].attemptingResume=!1,O[a].loaded+=e.size+p(a),O[a].remainingChunkIdxs.length>0?n(a):(R&&A(a),m(a,b,c))}function r(a,b){return 200!==a.status||!b.success||b.reset}function s(a,b){var d;try{d=qq.parseJson(b.responseText),void 0!==d.newUuid&&(N("Server requested UUID change from '"+O[a].uuid+"' to '"+d.newUuid+"'"),O[a].uuid=d.newUuid,c(a,d.newUuid))}catch(e){N("Error when attempting to parse xhr response text ("+e+")","error"),d={}}return d}function t(a){N("Server has ordered chunking effort to be restarted on next attempt for item ID "+a,"error"),R&&(A(a),O[a].attemptingResume=!1),O[a].remainingChunkIdxs=[],delete O[a].loaded,delete O[a].estTotalRequestsSize,delete O[a].initialRequestOverhead}function u(a){O[a].attemptingResume=!1,N("Server has declared that it cannot handle resume for item ID "+a+" - starting from the first chunk","error"),t(a),K.upload(a,!0)}function v(a,b,c){var d=K.getName(a);L.onAutoRetry(a,d,b,c)||m(a,b,c)}function w(a,b){var c;O[a]&&(N("xhr - server response received for "+a),N("responseText = "+b.responseText),c=s(a,b),r(b,c)?(c.reset&&t(a),O[a].attemptingResume&&c.reset?u(a):v(a,c,b)):Q?q(a,c,b):m(a,c,b))}function x(a){return{partIndex:a.part,startByte:a.start+1,endByte:a.end,totalParts:a.count}}function y(a,b){return function(){4===b.readyState&&w(a,b)}}function z(a,b){var c=K.getUuid(a),d=O[a].loaded,e=O[a].initialRequestOverhead,f=O[a].estTotalRequestsSize,g=C(a),h=c+P+b.part+P+d+P+e+P+f,i=L.resume.cookiesExpireIn;qq.setCookie(g,h,i)}function A(a){if(O[a].file){var b=C(a);qq.deleteCookie(b)}}function B(a){var b,c,d,e,f,g,h=qq.getCookie(C(a)),i=K.getName(a);if(h){if(b=h.split(P),5===b.length)return c=b[0],d=parseInt(b[1],10),e=parseInt(b[2],10),f=parseInt(b[3],10),g=parseInt(b[4],10),{uuid:c,part:d,lastByteSent:e,initialRequestOverhead:f,estTotalRequestsSize:g};N("Ignoring previously stored resume/chunk cookie for "+i+" - old cookie format","warn")}}function C(a){var b,c=K.getName(a),d=K.getSize(a),e=L.chunking.partSize;return b="qqfilechunk"+P+encodeURIComponent(c)+P+d+P+e,void 0!==S&&(b+=P+S),b}function D(){return null===L.resume.id||void 0===L.resume.id||qq.isFunction(L.resume.id)||qq.isObject(L.resume.id)?void 0:L.resume.id}function E(a,b){var c;for(c=i(a)-1;c>=b;c-=1)O[a].remainingChunkIdxs.unshift(c);n(a)}function F(a,b,c,d){c=d.part,O[a].loaded=d.lastByteSent,O[a].estTotalRequestsSize=d.estTotalRequestsSize,O[a].initialRequestOverhead=d.initialRequestOverhead,O[a].attemptingResume=!0,N("Resuming "+b+" at partition index "+c),E(a,c)}function G(a,b,c){var d,e=K.getName(a),f=h(a,b.part);d=L.onResume(a,e,x(f)),qq.isPromise(d)?(N("Waiting for onResume promise to be fulfilled for "+a),d.then(function(){F(a,e,c,b)},function(){N("onResume promise fulfilled - failure indicated. Will not resume."),E(a,c)})):d!==!1?F(a,e,c,b):(N("onResume callback returned false. Will not resume."),E(a,c))}function H(a,b){var c,d=0;O[a].remainingChunkIdxs&&0!==O[a].remainingChunkIdxs.length?n(a):(O[a].remainingChunkIdxs=[],R&&!b&&O[a].file?(c=B(a),c?G(a,c,d):E(a,d)):E(a,d))}function I(a){var b,c,d,e=O[a].file||O[a].blobData.blob,f=K.getName(a);O[a].loaded=0,b=j(a),b.upload.onprogress=function(b){b.lengthComputable&&(O[a].loaded=b.loaded,L.onProgress(a,f,b.loaded,b.total))},b.onreadystatechange=y(a,b),c=L.paramsStore.getParams(a),d=k(c,b,e,a),l(a,b),N("Sending upload request for "+a),b.send(d)}function J(a){var b=O[a].xhr;b&&(b.onreadystatechange=null,b.abort()),R&&A(a),delete O[a]}var K,L=a,M=b,N=d,O=[],P="|",Q=L.chunking.enabled&&qq.supportedFeatures.chunking,R=L.resume.enabled&&Q&&qq.supportedFeatures.resume,S=D(),T=L.forceMultipart||L.paramsInBody;return K={add:function(a){var b,c,d=qq.getUniqueId();if(qq.isFile(a))b=O.push({file:a})-1;else{if(!qq.isBlob(a.blob))throw new Error("Passed obj in not a File or BlobData (in qq.UploadHandlerXhr)");b=O.push({blobData:a})-1}return R&&(c=B(b),c&&(d=c.uuid)),O[b].uuid=d,b},getName:function(a){if(K.isValid(a)){var b=O[a].file,c=O[a].blobData,d=O[a].newName;return void 0!==d?d:b?null!==b.fileName&&void 0!==b.fileName?b.fileName:b.name:c.name}N(a+" is not a valid item ID.","error")},setName:function(a,b){O[a].newName=b},getSize:function(a){var b=O[a].file||O[a].blobData.blob;return qq.isFileOrInput(b)?null!=b.fileSize?b.fileSize:b.size:b.size},getFile:function(a){return O[a]?O[a].file||O[a].blobData.blob:void 0},isValid:function(a){return void 0!==O[a]},reset:function(){O=[]},expunge:function(a){return J(a)},getUuid:function(a){return O[a].uuid},upload:function(a,b){var c=this.getName(a);this.isValid(a)&&(L.onUpload(a,c),Q?H(a,b):I(a))},cancel:function(a){var b=L.onCancel(a,this.getName(a));return qq.isPromise(b)?b.then(function(){J(a)}):b!==!1?(J(a),!0):!1},getResumableFilesData:function(){var a=[],b=[];return Q&&R?(a=void 0===S?qq.getCookieNames(new RegExp("^qqfilechunk\\"+P+".+\\"+P+"\\d+\\"+P+L.chunking.partSize+"=")):qq.getCookieNames(new RegExp("^qqfilechunk\\"+P+".+\\"+P+"\\d+\\"+P+L.chunking.partSize+"\\"+P+S+"=")),qq.each(a,function(a,c){var d=c.split(P),e=qq.getCookie(c).split(P);b.push({name:decodeURIComponent(d[1]),size:d[2],uuid:e[0],partIdx:e[1]})}),b):[]}}},qq.UiEventHandler=function(a,b){"use strict";function c(a){d.attach(a,e.eventType,function(a){a=a||window.event;var b=a.target||a.srcElement;e.onHandled(b,a)})}var d=new qq.DisposeSupport,e={eventType:"click",attachTo:null,onHandled:function(){}},f={addHandler:function(a){c(a)},dispose:function(){d.dispose()}};return qq.extend(b,{getItemFromEventTarget:function(a){for(var b=a.parentNode;void 0===b.qqFileId;)b=b.parentNode;return b},getFileIdFromItem:function(a){return a.qqFileId},getDisposeSupport:function(){return d}}),qq.extend(e,a),e.attachTo&&c(e.attachTo),f},qq.DeleteRetryOrCancelClickHandler=function(a){"use strict";function b(a,b){if(qq(a).hasClass(e.classes.cancel)||qq(a).hasClass(e.classes.retry)||qq(a).hasClass(e.classes.deleteButton)){var f=d.getItemFromEventTarget(a),g=d.getFileIdFromItem(f);qq.preventDefault(b),e.log(qq.format("Detected valid cancel, retry, or delete click event on file '{}', ID: {}.",e.onGetName(g),g)),c(a,g)}}function c(a,b){qq(a).hasClass(e.classes.deleteButton)?e.onDeleteFile(b):qq(a).hasClass(e.classes.cancel)?e.onCancel(b):e.onRetry(b)}var d={},e={listElement:document,log:function(){},classes:{cancel:"qq-upload-cancel",deleteButton:"qq-upload-delete",retry:"qq-upload-retry"},onDeleteFile:function(){},onCancel:function(){},onRetry:function(){},onGetName:function(){}};qq.extend(e,a),e.eventType="click",e.onHandled=b,e.attachTo=e.listElement,qq.extend(this,new qq.UiEventHandler(e,d))},qq.FilenameEditHandler=function(a,b){"use strict";function c(a){var b=i.onGetName(a),c=b.lastIndexOf(".");return c>0&&(b=b.substr(0,c)),b}function d(a){var b=i.onGetName(a),c=b.lastIndexOf(".");return c>0?b.substr(c,b.length-c):void 0}function e(a,b){var c,e=a.value;void 0!==e&&qq.trimStr(e).length>0&&(c=d(b),void 0!==c&&(e+=d(b)),i.onSetName(b,e)),i.onEditingStatusChange(b,!1)}function f(a,c){b.getDisposeSupport().attach(a,"blur",function(){e(a,c)})}function g(a,c){b.getDisposeSupport().attach(a,"keyup",function(b){var d=b.keyCode||b.which;13===d&&e(a,c)})}var h,i={listElement:null,log:function(){},classes:{file:"qq-upload-file"},onGetUploadStatus:function(){},onGetName:function(){},onSetName:function(){},onGetInput:function(){},onEditingStatusChange:function(){}};return qq.extend(i,a),i.attachTo=i.listElement,h=qq.extend(this,new qq.UiEventHandler(i,b)),qq.extend(b,{handleFilenameEdit:function(a,b,d,e){var h=i.onGetInput(d);i.onEditingStatusChange(a,!0),h.value=c(a),e&&h.focus(),f(h,a),g(h,a)}}),h},qq.FilenameClickHandler=function(a){"use strict";function b(a,b){if(qq(a).hasClass(d.classes.file)||qq(a).hasClass(d.classes.editNameIcon)){var e=c.getItemFromEventTarget(a),f=c.getFileIdFromItem(e),g=d.onGetUploadStatus(f);g===qq.status.SUBMITTED&&(d.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",d.onGetName(f),f)),qq.preventDefault(b),c.handleFilenameEdit(f,a,e,!0))}}var c={},d={log:function(){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(){},onGetName:function(){}};return qq.extend(d,a),d.eventType="click",d.onHandled=b,qq.extend(this,new qq.FilenameEditHandler(d,c))},qq.FilenameInputFocusInHandler=function(a,b){"use strict";function c(a){if(qq(a).hasClass(d.classes.editFilenameInput)){var c=b.getItemFromEventTarget(a),e=b.getFileIdFromItem(c),f=d.onGetUploadStatus(e);f===qq.status.SUBMITTED&&(d.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",d.onGetName(e),e)),b.handleFilenameEdit(e,a,c))}}var d={listElement:null,classes:{editFilenameInput:"qq-edit-filename"},onGetUploadStatus:function(){},log:function(){}};return b||(b={}),d.eventType="focusin",d.onHandled=c,qq.extend(d,a),qq.extend(this,new qq.FilenameEditHandler(d,b))},qq.FilenameInputFocusHandler=function(a){"use strict";return a.eventType="focus",a.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(a,{}))},function(a){"use strict";var b,c,d,e,f,g,h,i,j,k;g=["uploaderType"],d=function(a){if(a){var d=i(a);h(d),"basic"===f("uploaderType")?b(new qq.FineUploaderBasic(d)):b(new qq.FineUploader(d))}return c},e=function(a,b){var d=c.data("fineuploader");return b?(void 0===d&&(d={}),d[a]=b,c.data("fineuploader",d),void 0):void 0===d?null:d[a]},b=function(a){return e("uploader",a)},f=function(a,b){return e(a,b)},h=function(b){var d=b.callbacks={},e=new qq.FineUploaderBasic;a.each(e._options.callbacks,function(a){var b,e;b=/^on(\w+)/.exec(a)[1],b=b.substring(0,1).toLowerCase()+b.substring(1),e=c,d[a]=function(){var a=Array.prototype.slice.call(arguments);return e.triggerHandler(b,a)}})},i=function(b,d){var e,h;return e=void 0===d?"basic"!==b.uploaderType?{element:c[0]}:{}:d,a.each(b,function(b,c){a.inArray(b,g)>=0?f(b,c):c instanceof a?e[b]=c[0]:a.isPlainObject(c)?(e[b]={},i(c,e[b])):a.isArray(c)?(h=[],a.each(c,function(b,c){c instanceof a?a.merge(h,c):h.push(c)}),e[b]=h):e[b]=c}),void 0===d?e:void 0},j=function(c){return"string"===a.type(c)&&!c.match(/^_/)&&void 0!==b()[c]},k=function(c){var d,e=[],f=Array.prototype.slice.call(arguments,1);return i(f,e),d=b()[c].apply(b(),e),"object"!=typeof d||1!==d.nodeType&&9!==d.nodeType||!d.cloneNode||(d=a(d)),d},a.fn.fineUploader=function(e){var f=this,g=arguments,h=[];return this.each(function(i,l){if(c=a(l),b()&&j(e)){if(h.push(k.apply(f,g)),1===f.length)return!1}else"object"!=typeof e&&e?a.error("Method "+e+" does not exist on jQuery.fineUploader"):d.apply(f,g)}),1===h.length?h[0]:h.length>1?h:this}}(jQuery),function(a){"use strict";function b(a){a||(a={}),a.dropZoneElements=[i];var b=f(a);return e(b),d(new qq.DragAndDrop(b)),i}function c(a,b){var c=i.data(j);return b?(void 0===c&&(c={}),c[a]=b,i.data(j,c),void 0):void 0===c?null:c[a]}function d(a){return c("dndInstance",a)}function e(b){var c=b.callbacks={};new qq.FineUploaderBasic,a.each(new qq.DragAndDrop.callbacks,function(a){var b,d=a;b=i,c[a]=function(){var a=Array.prototype.slice.call(arguments),c=b.triggerHandler(d,a);return c}})}function f(b,c){var d,e;return d=void 0===c?{}:c,a.each(b,function(b,c){c instanceof a?d[b]=c[0]:a.isPlainObject(c)?(d[b]={},f(c,d[b])):a.isArray(c)?(e=[],a.each(c,function(b,c){c instanceof a?a.merge(e,c):e.push(c)}),d[b]=e):d[b]=c}),void 0===c?d:void 0}function g(b){return"string"===a.type(b)&&"dispose"===b&&void 0!==d()[b]}function h(a){var b=[],c=Array.prototype.slice.call(arguments,1);return f(c,b),d()[a].apply(d(),b)}var i,j="fineUploaderDnd";a.fn.fineUploaderDnd=function(c){var e=this,f=arguments,j=[];return this.each(function(k,l){if(i=a(l),d()&&g(c)){if(j.push(h.apply(e,f)),1===e.length)return!1}else"object"!=typeof c&&c?a.error("Method "+c+" does not exist in Fine Uploader's DnD module."):b.apply(e,f)}),1===j.length?j[0]:j.length>1?j:this}}(jQuery);
|
19 |
+
/*! 2013-07-24 */
|
js/productivity/adminhtml/update_grid.js
ADDED
@@ -0,0 +1,31 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
/**
|
2 |
+
* NOTICE OF LICENSE
|
3 |
+
*
|
4 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
5 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
6 |
+
* It is also available through the world-wide-web at this URL:
|
7 |
+
* http://opensource.org/licenses/osl-3.0.php
|
8 |
+
*
|
9 |
+
* @package MVentory/Productivity
|
10 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
11 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
12 |
+
* @author <anemets1@gmail.com>
|
13 |
+
*/
|
14 |
+
|
15 |
+
function addMiddleClick() {
|
16 |
+
$$('table.data tbody tr').each(function(item) {
|
17 |
+
item.stopObserving('click');
|
18 |
+
item.observe('mousedown', function(e) {
|
19 |
+
if(Event.isMiddleClick(e)) {
|
20 |
+
window.open(item.readAttribute('title'), '_blank');
|
21 |
+
}
|
22 |
+
});
|
23 |
+
item.observe('click', function(e) {
|
24 |
+
if(Event.isLeftClick(e)) {
|
25 |
+
document.location.href = item.readAttribute('title');
|
26 |
+
}
|
27 |
+
});
|
28 |
+
});
|
29 |
+
}
|
30 |
+
|
31 |
+
Event.observe(window, 'load', addMiddleClick);
|
js/productivity/image/edit.js
ADDED
@@ -0,0 +1,542 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
/**
|
2 |
+
* NOTICE OF LICENSE
|
3 |
+
*
|
4 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
5 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
6 |
+
* It is also available through the world-wide-web at this URL:
|
7 |
+
* http://opensource.org/licenses/osl-3.0.php
|
8 |
+
*
|
9 |
+
* @package MVentory/Productivity
|
10 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
11 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
12 |
+
* @author Anatoly A. Kazantsev <anatoly@mventory.com>
|
13 |
+
*/
|
14 |
+
|
15 |
+
(function (productivity, $) {
|
16 |
+
|
17 |
+
productivity.image = {};
|
18 |
+
productivity.edit = {};
|
19 |
+
|
20 |
+
function __ (s) {
|
21 |
+
return window.Translator.translate(s);
|
22 |
+
}
|
23 |
+
|
24 |
+
function confirmRemove ($el) {
|
25 |
+
var answer;
|
26 |
+
|
27 |
+
$el.addClass('productivity-state-warning');
|
28 |
+
answer = confirm(__('Do you want to delete this image?'));
|
29 |
+
$el.removeClass('productivity-state-warning');
|
30 |
+
|
31 |
+
return answer;
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
|
36 |
+
$(function () {
|
37 |
+
|
38 |
+
var $form = $('#product_addtocart_form');
|
39 |
+
var $panel = $('#productivity-image-edit-panel');
|
40 |
+
var $menus = $form.find('.tm-image-editor-menu');
|
41 |
+
var $updImage;
|
42 |
+
var $updImageEditor;
|
43 |
+
|
44 |
+
for (var type in productivity.edit.selector) {
|
45 |
+
if (!productivity.edit.selector.hasOwnProperty(type))
|
46 |
+
continue;
|
47 |
+
|
48 |
+
var selector = productivity.edit.wrapper[type]
|
49 |
+
? productivity.edit.wrapper[type]
|
50 |
+
: productivity.edit.selector[type];
|
51 |
+
|
52 |
+
add_panel(
|
53 |
+
$(selector),
|
54 |
+
{
|
55 |
+
panel: {
|
56 |
+
position: get_panel_position,
|
57 |
+
element: get_element,
|
58 |
+
loader: show_loader,
|
59 |
+
scope: 'images',
|
60 |
+
action: {
|
61 |
+
remove: {
|
62 |
+
on_error: on_error,
|
63 |
+
on_success: on_remove
|
64 |
+
},
|
65 |
+
rotate: {
|
66 |
+
on_error: on_error,
|
67 |
+
on_success: on_rotate
|
68 |
+
},
|
69 |
+
setmain: {
|
70 |
+
on_error: on_error,
|
71 |
+
on_success: on_setmain
|
72 |
+
}
|
73 |
+
}
|
74 |
+
},
|
75 |
+
image: { type: type }
|
76 |
+
}
|
77 |
+
);
|
78 |
+
}
|
79 |
+
|
80 |
+
$panel
|
81 |
+
.on('mouseenter', function () {
|
82 |
+
$panel.show();
|
83 |
+
})
|
84 |
+
.on('mouseleave', panel_mouseleave_handler);
|
85 |
+
|
86 |
+
$panel
|
87 |
+
.children('.rotate-image')
|
88 |
+
.filter('.rotate-left')
|
89 |
+
.on('click', { rotate: 'left' }, rotate_button_click_handler)
|
90 |
+
.end()
|
91 |
+
.filter('.rotate-right')
|
92 |
+
.on('click', { rotate: 'right' }, rotate_button_click_handler);
|
93 |
+
|
94 |
+
$panel
|
95 |
+
.children('.remove-image')
|
96 |
+
.on('click', remove_button_click_handler);
|
97 |
+
|
98 |
+
$panel
|
99 |
+
.children('.set-main-image')
|
100 |
+
.on('click', set_main_button_click_handler);
|
101 |
+
|
102 |
+
function add_panel ($element, data) {
|
103 |
+
$element.on(
|
104 |
+
{
|
105 |
+
mouseenter: image_mouseenter_handler,
|
106 |
+
mouseleave: panel_mouseleave_handler,
|
107 |
+
},
|
108 |
+
data
|
109 |
+
);
|
110 |
+
}
|
111 |
+
|
112 |
+
productivity.func = { add_panel: add_panel };
|
113 |
+
|
114 |
+
function get_panel_position ($element) {
|
115 |
+
var position = $element.offset();
|
116 |
+
|
117 |
+
position.top += $element.height() - 10;
|
118 |
+
position.left += 10;
|
119 |
+
|
120 |
+
return position;
|
121 |
+
}
|
122 |
+
|
123 |
+
function get_element ($element, type) {
|
124 |
+
if (!productivity.edit.wrapper[type])
|
125 |
+
return $element;
|
126 |
+
|
127 |
+
$element = $element.find(productivity.edit.selector[type]);
|
128 |
+
|
129 |
+
if (!$element.length)
|
130 |
+
return;
|
131 |
+
|
132 |
+
return $element;
|
133 |
+
}
|
134 |
+
|
135 |
+
function show_loader ($element, type) {
|
136 |
+
if (type != 'image')
|
137 |
+
return;
|
138 |
+
|
139 |
+
var $loader = $('<div class="image-editor-loader" />')
|
140 |
+
.appendTo($element.parent())
|
141 |
+
.show();
|
142 |
+
|
143 |
+
return function () {
|
144 |
+
$loader.remove();
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
function on_error ($element, data) {
|
149 |
+
var currentBorder = $element.css('border');
|
150 |
+
$element.css('border','1px solid red');
|
151 |
+
setTimeout(function(){$element.css('border',currentBorder)}, 5000);
|
152 |
+
alert('Product ID: ' + data.product_id + '\nImage file: ' + data.file + '\nStatus: ' + data.status);
|
153 |
+
}
|
154 |
+
|
155 |
+
function on_remove ($element, data) {
|
156 |
+
if (data.url)
|
157 |
+
$element.prop('src', data.url);
|
158 |
+
else
|
159 |
+
$element.remove();
|
160 |
+
}
|
161 |
+
|
162 |
+
function on_rotate ($element, data) {
|
163 |
+
$element.prop('src', data.url);
|
164 |
+
|
165 |
+
//!!!FIX: also return link to full size image
|
166 |
+
//$element.parent('a').prop('href', '/media/catalog/product' + data.base);
|
167 |
+
|
168 |
+
$element.data('productivity').file = data.file;
|
169 |
+
}
|
170 |
+
|
171 |
+
function on_setmain ($element, data) {
|
172 |
+
$element.image.prop('src', data.image.url);
|
173 |
+
$element.thumb.prop('src', data.thumbnail.url);
|
174 |
+
|
175 |
+
$element.image.data('productivity').file = data.image.file;
|
176 |
+
$element.thumb.data('productivity').file = data.thumbnail.file;
|
177 |
+
}
|
178 |
+
|
179 |
+
function rotate_image ($img, params, type, cb) {
|
180 |
+
var productId = $form.find('input[name="product"]').val();
|
181 |
+
|
182 |
+
$.ajax({
|
183 |
+
url: productivity.image.url.rotate,
|
184 |
+
type: 'POST',
|
185 |
+
dataType: 'json',
|
186 |
+
data: {
|
187 |
+
params: params,
|
188 |
+
thumb: type == 'thumbnail',
|
189 |
+
productId: productId
|
190 |
+
},
|
191 |
+
error: function (jqXHR, status, errorThrown) {
|
192 |
+
var data = {
|
193 |
+
product_id: productId,
|
194 |
+
file: params.file,
|
195 |
+
status: status
|
196 |
+
};
|
197 |
+
|
198 |
+
cb.on_error($img, data);
|
199 |
+
},
|
200 |
+
success: function (data, status, jqXHR) {
|
201 |
+
if (data.success)
|
202 |
+
cb.on_success($img, data.data)
|
203 |
+
else {
|
204 |
+
var data = {
|
205 |
+
product_id: productId,
|
206 |
+
file: params.file,
|
207 |
+
status: status
|
208 |
+
};
|
209 |
+
|
210 |
+
cb.on_error($img, data);
|
211 |
+
}
|
212 |
+
},
|
213 |
+
complete: cb.on_complete
|
214 |
+
});
|
215 |
+
}
|
216 |
+
|
217 |
+
function remove_image ($img, params, product_id, type, cb) {
|
218 |
+
var thumb = type == 'thumbnail';
|
219 |
+
|
220 |
+
$.ajax({
|
221 |
+
url: productivity.image.url.remove,
|
222 |
+
type: 'POST',
|
223 |
+
dataType: 'json',
|
224 |
+
data: { params: params, product: product_id, thumb: thumb },
|
225 |
+
error: function (jqXHR, status, errorThrown) {
|
226 |
+
var data = {
|
227 |
+
product_id: product_id,
|
228 |
+
file: params.file,
|
229 |
+
status: status
|
230 |
+
};
|
231 |
+
|
232 |
+
cb.on_error($img, data);
|
233 |
+
},
|
234 |
+
success: function (data, status, jqXHR) {
|
235 |
+
if (data.success)
|
236 |
+
cb.on_success($img, data.data)
|
237 |
+
else {
|
238 |
+
var data = {
|
239 |
+
product_id: product_id,
|
240 |
+
file: params.file,
|
241 |
+
status: status
|
242 |
+
};
|
243 |
+
|
244 |
+
cb.on_error($img, data);
|
245 |
+
}
|
246 |
+
},
|
247 |
+
complete: cb.on_complete
|
248 |
+
});
|
249 |
+
}
|
250 |
+
|
251 |
+
function set_main_image ($image,
|
252 |
+
$thumb,
|
253 |
+
params,
|
254 |
+
main_image_params,
|
255 |
+
product_id,
|
256 |
+
cb) {
|
257 |
+
|
258 |
+
$.ajax({
|
259 |
+
url: productivity.image.url.setmain,
|
260 |
+
type: 'POST',
|
261 |
+
dataType: 'json',
|
262 |
+
data: { product: product_id,
|
263 |
+
params: params,
|
264 |
+
main_image_params: main_image_params },
|
265 |
+
error: function (jqXHR, status, errorThrown) {
|
266 |
+
var data = {
|
267 |
+
product_id: product_id,
|
268 |
+
file: params.file,
|
269 |
+
status: status
|
270 |
+
};
|
271 |
+
|
272 |
+
cb.on_error($image, data);
|
273 |
+
},
|
274 |
+
success: function (data, status, jqXHR) {
|
275 |
+
if (data.success)
|
276 |
+
cb.on_success({ image: $image, thumb: $thumb }, data.data)
|
277 |
+
else {
|
278 |
+
var data = {
|
279 |
+
product_id: product_id,
|
280 |
+
file: params.file,
|
281 |
+
status: status
|
282 |
+
};
|
283 |
+
|
284 |
+
cb.on_error($image, data);
|
285 |
+
}
|
286 |
+
},
|
287 |
+
complete: cb.on_complete
|
288 |
+
});
|
289 |
+
}
|
290 |
+
|
291 |
+
function image_mouseenter_handler (event) {
|
292 |
+
if($panel.hasClass('disabled'))
|
293 |
+
return;
|
294 |
+
|
295 |
+
var $this = $(this);
|
296 |
+
|
297 |
+
$panel.removeClass('productivity-scope-uploader productivity-scope-images');
|
298 |
+
|
299 |
+
var data = (typeof event.data === 'function') ? event.data() : event.data;
|
300 |
+
|
301 |
+
if (data.image.type == 'image')
|
302 |
+
$panel.addClass('productivity-state-main-image');
|
303 |
+
else
|
304 |
+
$panel.removeClass('productivity-state-main-image');
|
305 |
+
|
306 |
+
if (typeof data.panel.position === 'function')
|
307 |
+
css = data.panel.position($this)
|
308 |
+
else {
|
309 |
+
css = $this.offset();
|
310 |
+
|
311 |
+
css.top += data.panel.position.top;
|
312 |
+
css.left += data.panel.position.left;
|
313 |
+
}
|
314 |
+
|
315 |
+
if (typeof data.panel.size === 'function') {
|
316 |
+
var size = data.panel.size($this);
|
317 |
+
|
318 |
+
css.width = size.width;
|
319 |
+
css.height = size.height;
|
320 |
+
}
|
321 |
+
|
322 |
+
//Store elements for image and its wrapper
|
323 |
+
data.wrapper = { $: $this };
|
324 |
+
data.element = {
|
325 |
+
$: typeof data.panel.element === 'function'
|
326 |
+
? data.panel.element($this, data.image.type)
|
327 |
+
: $this
|
328 |
+
};
|
329 |
+
|
330 |
+
$panel
|
331 |
+
.removeAttr('style')
|
332 |
+
.css(css)
|
333 |
+
.addClass('productivity-scope-' + event.data.panel.scope)
|
334 |
+
.show()
|
335 |
+
.data(data);
|
336 |
+
}
|
337 |
+
|
338 |
+
function panel_mouseleave_handler () {
|
339 |
+
$panel.hide();
|
340 |
+
}
|
341 |
+
|
342 |
+
function rotate_button_click_handler (event) {
|
343 |
+
event.preventDefault();
|
344 |
+
|
345 |
+
var data = $panel.data();
|
346 |
+
|
347 |
+
$panel
|
348 |
+
.addClass('disabled')
|
349 |
+
.hide();
|
350 |
+
|
351 |
+
data.element.$.css('opacity', '0.5');
|
352 |
+
|
353 |
+
if (typeof data.panel.loader === 'function')
|
354 |
+
var hide_loader = data.panel.loader(data.element.$, data.image.type)
|
355 |
+
|
356 |
+
var image = data.element.$.data('productivity');
|
357 |
+
|
358 |
+
if (!image) {
|
359 |
+
image = {
|
360 |
+
file: data.image.file
|
361 |
+
? data.image.file
|
362 |
+
: get_filename_from_url(data.element.$.prop('src')),
|
363 |
+
};
|
364 |
+
}
|
365 |
+
|
366 |
+
data.element.$.data('productivity', image);
|
367 |
+
|
368 |
+
var params = {
|
369 |
+
file: image.file,
|
370 |
+
width: data.image.width === undefined
|
371 |
+
? productivity.edit.size[data.image.type].width
|
372 |
+
: data.image.width,
|
373 |
+
height: data.image.height === undefined
|
374 |
+
? productivity.edit.size[data.image.type].height
|
375 |
+
: data.image.height,
|
376 |
+
rotate: event.data.rotate
|
377 |
+
};
|
378 |
+
|
379 |
+
data.panel.action.rotate.on_complete = function () {
|
380 |
+
if (hide_loader)
|
381 |
+
hide_loader();
|
382 |
+
|
383 |
+
data.element.$.css('opacity', '1')
|
384 |
+
|
385 |
+
$panel.removeClass('disabled');
|
386 |
+
};
|
387 |
+
|
388 |
+
rotate_image(data.element.$, params, data.image.type, data.panel.action.rotate);
|
389 |
+
|
390 |
+
return false;
|
391 |
+
}
|
392 |
+
|
393 |
+
function remove_button_click_handler (event) {
|
394 |
+
event.preventDefault();
|
395 |
+
|
396 |
+
var data = $panel.data();
|
397 |
+
|
398 |
+
data.element.$.css('opacity', '0.5');
|
399 |
+
|
400 |
+
if (!confirmRemove(data.wrapper.$)) {
|
401 |
+
data.element.$.css('opacity', '1');
|
402 |
+
|
403 |
+
return false;
|
404 |
+
}
|
405 |
+
|
406 |
+
var image = data.element.$.data('productivity');
|
407 |
+
|
408 |
+
if (!image) {
|
409 |
+
image = {
|
410 |
+
file: data.image.file
|
411 |
+
? data.image.file
|
412 |
+
: get_filename_from_url(data.element.$.prop('src')),
|
413 |
+
};
|
414 |
+
}
|
415 |
+
|
416 |
+
data.element.$.data('productivity', image);
|
417 |
+
|
418 |
+
var params = {
|
419 |
+
file: image.file,
|
420 |
+
width: productivity.edit.size[data.image.type].width,
|
421 |
+
height: productivity.edit.size[data.image.type].height
|
422 |
+
};
|
423 |
+
|
424 |
+
var product_id = $form
|
425 |
+
.find('input[name="product"]')
|
426 |
+
.val();
|
427 |
+
|
428 |
+
data.panel.action.remove.on_complete = function () {
|
429 |
+
data.element.$.css('opacity', '1');
|
430 |
+
$panel.hide();
|
431 |
+
};
|
432 |
+
|
433 |
+
remove_image(data.element.$, params, product_id, data.image.type, data.panel.action.remove);
|
434 |
+
|
435 |
+
return false;
|
436 |
+
}
|
437 |
+
|
438 |
+
|
439 |
+
function set_main_button_click_handler (event) {
|
440 |
+
event.preventDefault();
|
441 |
+
|
442 |
+
var data = $panel.data();
|
443 |
+
|
444 |
+
if (data.image.type != 'thumbnail')
|
445 |
+
return false;
|
446 |
+
|
447 |
+
$panel
|
448 |
+
.addClass('disabled')
|
449 |
+
.hide();
|
450 |
+
|
451 |
+
if (typeof data.panel.loader === 'function')
|
452 |
+
var hide_loader = data.panel.loader(data.element.$, data.image.type)
|
453 |
+
|
454 |
+
var $this = $(this);
|
455 |
+
|
456 |
+
/*$this.off('click', set_main_button_click_handler);*/
|
457 |
+
|
458 |
+
var thumb = data.element.$.data('productivity');
|
459 |
+
|
460 |
+
if (!thumb) {
|
461 |
+
thumb = {
|
462 |
+
file: data.image.file
|
463 |
+
? data.image.file
|
464 |
+
: get_filename_from_url(data.element.$.prop('src')),
|
465 |
+
};
|
466 |
+
}
|
467 |
+
|
468 |
+
data.element.$.data('productivity', thumb);
|
469 |
+
|
470 |
+
var params = {
|
471 |
+
file: thumb.file,
|
472 |
+
width: data.image.width === undefined
|
473 |
+
? productivity.edit.size.thumbnail.width
|
474 |
+
: data.image.width,
|
475 |
+
height: data.image.height === undefined
|
476 |
+
? productivity.edit.size.thumbnail.height
|
477 |
+
: data.image.height
|
478 |
+
};
|
479 |
+
|
480 |
+
var product_id = $form
|
481 |
+
.find('input[name="product"]')
|
482 |
+
.val();
|
483 |
+
|
484 |
+
var $mainImage = productivity.edit.wrapper.image
|
485 |
+
? $(productivity.edit.wrapper.image)
|
486 |
+
.find(productivity.edit.selector.image)
|
487 |
+
: $(productivity.edit.selector.image);
|
488 |
+
|
489 |
+
var image = $mainImage.data('productivity');
|
490 |
+
|
491 |
+
if (!image) {
|
492 |
+
image = {
|
493 |
+
file: get_filename_from_url($mainImage.prop('src')),
|
494 |
+
};
|
495 |
+
}
|
496 |
+
|
497 |
+
$mainImage.data('productivity', image);
|
498 |
+
|
499 |
+
var main_image_params = {
|
500 |
+
file: image.file,
|
501 |
+
width: productivity.edit.size.image.width,
|
502 |
+
height: productivity.edit.size.image.height
|
503 |
+
};
|
504 |
+
|
505 |
+
$mainImage.css('opacity', '0.5');
|
506 |
+
data.element.$.css('opacity', '0.5');
|
507 |
+
|
508 |
+
$mainImage.parent().append('<div class="image-editor-loader"></div>');
|
509 |
+
$('.image-editor-loader').show();
|
510 |
+
|
511 |
+
data.panel.action.setmain.on_complete = function () {
|
512 |
+
var link = data.element.$.parent('a').prop('href');
|
513 |
+
data.element.$.parent('a').prop('href', $mainImage.parent('a').prop('href'));
|
514 |
+
$mainImage.parent('a').prop('href', link);
|
515 |
+
|
516 |
+
if (hide_loader)
|
517 |
+
hide_loader();
|
518 |
+
|
519 |
+
data.element.$.css('opacity', '1');
|
520 |
+
$mainImage.css('opacity', '1');
|
521 |
+
|
522 |
+
$panel.removeClass('disabled');
|
523 |
+
};
|
524 |
+
|
525 |
+
set_main_image(
|
526 |
+
$mainImage,
|
527 |
+
data.element.$,
|
528 |
+
params,
|
529 |
+
main_image_params,
|
530 |
+
product_id,
|
531 |
+
data.panel.action.setmain
|
532 |
+
);
|
533 |
+
}
|
534 |
+
|
535 |
+
function get_filename_from_url (url) {
|
536 |
+
return url.substring(
|
537 |
+
url.lastIndexOf('/', url.lastIndexOf('/', url.lastIndexOf('/') - 1) - 1)
|
538 |
+
);
|
539 |
+
}
|
540 |
+
});
|
541 |
+
|
542 |
+
}(window.productivity = window.productivity || {}, jQuery));
|
package.xml
ADDED
@@ -0,0 +1,55 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>mVentory_Productivity</name>
|
4 |
+
<version>1.0.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:
|
11 |
+

|
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.
|
13 |
+

|
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.
|
15 |
+
The same applies to category and CMS pages.
|
16 |
+

|
17 |
+
* Edit product details, price, attributes, etc.
|
18 |
+
* Upload product images
|
19 |
+
* Set main product image
|
20 |
+
* Delete, rotate product images
|
21 |
+
* Shortcuts to the admin interface for the page
|
22 |
+
* Easily find products with missing images
|
23 |
+
* Shortcut to Google Analytics
|
24 |
+

|
25 |
+
Theme compatibility
|
26 |
+

|
27 |
+
Most well designed themes are compatible with the extension. You may need to make a few minor changes. See documentation on GitHub.
|
28 |
+

|
29 |
+
Enable / Disable the Toolbar
|
30 |
+

|
31 |
+
1. Log in to the admin interface.
|
32 |
+
2. Come back to the front end.
|
33 |
+
3. You should see the toolbar at the top.
|
34 |
+

|
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.
|
36 |
+

|
37 |
+
Source code and documentation
|
38 |
+

|
39 |
+
https://github.com/mVentory/mvProductivity
|
40 |
+

|
41 |
+
Support
|
42 |
+

|
43 |
+
Bug reports are welcome at support@zetaprints.com
|
44 |
+

|
45 |
+
License
|
46 |
+

|
47 |
+
The extension is free open source released under OSL 3 license. Please, contribute your code if you make useful changes.</description>
|
48 |
+
<notes>Initial release</notes>
|
49 |
+
<authors><author><name>Anatoly A. Kazantsev</name><user>anatoly</user><email>anatoly@mventory.com</email></author></authors>
|
50 |
+
<date>2014-05-29</date>
|
51 |
+
<time>15:09:38</time>
|
52 |
+
<contents><target name="mageetc"><dir name="modules"><file name="MVentory_Productivity.xml" hash="00d807ff8a6f07f118a2019aad343fe2"/></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="Image"><file name="Edit.php" hash="859a79c62b6ce085d770d01ca9140a6d"/></dir><dir name="Mage"><dir name="Page"><dir name="Html"><file name="Breadcrumbs.php" hash="32e927420838a37870c2d49241425a63"/></dir></dir></dir><file name="Panel.php" hash="70842ca2ab8bff289598ba95fb82ff20"/><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"><dir name="Mage"><dir name="Catalog"><file name="Category.php" hash="9ea79bfffb1aded54b5bfe7940e7ec78"/></dir></dir><file name="Observer.php" hash="8e30a2d92db5a99ac3fd2ddb8ccb5eea"/><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="05bc5aa23fe494324274fc57dc7956b5"/><file name="ProductController.php" hash="ead7f325b147e80e4ca06c0f0cde713d"/><dir name="Rss"><file name="ProductController.php" hash="777ab9eaa50ff3179b45bdcca8140e39"/></dir></dir><dir name="etc"><file name="config.xml" hash="bfaa9652ad0e76ca40c95579824574b5"/><file name="jstranslator.xml" hash="b6553078458f63a4d4a68193bf75ffea"/><file name="system.xml" hash="aa1b3e7a0187490f1d7ee0b6e935fcba"/><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="c1ee89cd9608911869e256ccbe46a35c"/></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></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="abb48de7fa51fa6358bd5b2b4407915e"/></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="40e9e1590d28490c80fc3e45e6435576"/></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>
|
53 |
+
<compatible/>
|
54 |
+
<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>
|
55 |
+
</package>
|
skin/adminhtml/default/default/productivity.css
ADDED
@@ -0,0 +1,22 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
/**
|
2 |
+
* NOTICE OF LICENSE
|
3 |
+
*
|
4 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
5 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
6 |
+
* It is also available through the world-wide-web at this URL:
|
7 |
+
* http://opensource.org/licenses/osl-3.0.php
|
8 |
+
*
|
9 |
+
* @package MVentory/Productivity
|
10 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
11 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
12 |
+
*/
|
13 |
+
|
14 |
+
.frontshop-button{
|
15 |
+
text-align:right;
|
16 |
+
margin-bottom: 5px;
|
17 |
+
}
|
18 |
+
button.frontshop {
|
19 |
+
opacity: .8;
|
20 |
+
border-color: #777 #505050 #505050 #777;
|
21 |
+
background: #919191 url(images/btn_bg-disabled.gif) 0 0 repeat-x;
|
22 |
+
}
|
skin/frontend/base/default/productivity/css/styles.css
ADDED
@@ -0,0 +1,436 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
/**
|
2 |
+
* NOTICE OF LICENSE
|
3 |
+
*
|
4 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
5 |
+
* that is bundled with this package in the file LICENSE-OSL.
|
6 |
+
* It is also available through the world-wide-web at this URL:
|
7 |
+
* http://opensource.org/licenses/osl-3.0.php
|
8 |
+
*
|
9 |
+
* @package MVentory/Productivity
|
10 |
+
* @copyright Copyright (c) 2014 mVentory Ltd. (http://mventory.com)
|
11 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
12 |
+
*/
|
13 |
+
|
14 |
+
#productivity-panel {
|
15 |
+
background-color: white;
|
16 |
+
text-align: left;
|
17 |
+
overflow: hidden;
|
18 |
+
-webkit-transition: height 0.3s ease-in-out;
|
19 |
+
-moz-transition: height 0.3s ease-in-out;
|
20 |
+
-o-transition: height 0.3s ease-in-out;
|
21 |
+
transition: height 0.3s ease-in-out;
|
22 |
+
}
|
23 |
+
|
24 |
+
.productivity,
|
25 |
+
.productivity * {
|
26 |
+
margin: 0;
|
27 |
+
padding: 0;
|
28 |
+
}
|
29 |
+
|
30 |
+
.productivity input.input-text,
|
31 |
+
.productivity textarea {
|
32 |
+
padding: 2px;
|
33 |
+
}
|
34 |
+
|
35 |
+
.productivity select {
|
36 |
+
padding: 1px;
|
37 |
+
}
|
38 |
+
|
39 |
+
.productivity select option {
|
40 |
+
padding-right: 10px;
|
41 |
+
}
|
42 |
+
|
43 |
+
.productivity select.multiselect option {
|
44 |
+
padding: 2px 5px;
|
45 |
+
}
|
46 |
+
|
47 |
+
#productivity-panel .clearer:after,
|
48 |
+
#productivity-edit-form .field-row:after {
|
49 |
+
clear: both;
|
50 |
+
content: ".";
|
51 |
+
display: block;
|
52 |
+
font-size: 0;
|
53 |
+
height: 0;
|
54 |
+
line-height: 0;
|
55 |
+
overflow: hidden;
|
56 |
+
}
|
57 |
+
|
58 |
+
#productivity-panel-menu {
|
59 |
+
background: linear-gradient(to top, #373737 0px, #464646 5px) repeat scroll 0 0 #464646;
|
60 |
+
}
|
61 |
+
|
62 |
+
#productivity-panel-menu * {
|
63 |
+
color: #ccc;
|
64 |
+
font: 13px/28px sans-serif;
|
65 |
+
height: 28px;
|
66 |
+
}
|
67 |
+
|
68 |
+
.productivity-set {
|
69 |
+
list-style: none outside none;
|
70 |
+
}
|
71 |
+
|
72 |
+
#productivity-context {
|
73 |
+
float: left;
|
74 |
+
}
|
75 |
+
|
76 |
+
#productivity-tasks {
|
77 |
+
float: right;
|
78 |
+
}
|
79 |
+
|
80 |
+
.productivity-set li {
|
81 |
+
border-left: 1px solid #555555;
|
82 |
+
float: left;
|
83 |
+
}
|
84 |
+
|
85 |
+
.productivity-set li:first-child {
|
86 |
+
border: none;
|
87 |
+
}
|
88 |
+
|
89 |
+
.productivity-set li:hover {
|
90 |
+
background: linear-gradient(to top, #3a3a3a, #222) repeat scroll 0 0 #222;
|
91 |
+
}
|
92 |
+
|
93 |
+
.productivity-set a {
|
94 |
+
display: block;
|
95 |
+
padding: 0 12px;
|
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;
|
113 |
+
}
|
114 |
+
|
115 |
+
#productivity-task-close {
|
116 |
+
font-size: 17px;
|
117 |
+
font-weight: bold;
|
118 |
+
height: 29px;
|
119 |
+
margin-top: -1px;
|
120 |
+
}
|
121 |
+
|
122 |
+
#productivity-panel-content {
|
123 |
+
height: 0;
|
124 |
+
overflow: hidden;
|
125 |
+
}
|
126 |
+
|
127 |
+
#productivity-panel-content-inner {
|
128 |
+
padding: 10px;
|
129 |
+
}
|
130 |
+
|
131 |
+
/* Image options block */
|
132 |
+
|
133 |
+
.box-store .store-map {
|
134 |
+
height: 300px;
|
135 |
+
}
|
136 |
+
|
137 |
+
.box-store pre.store-address {
|
138 |
+
margin: 0 0 10px;
|
139 |
+
}
|
140 |
+
|
141 |
+
.rotate-90 {
|
142 |
+
-moz-transform: rotate(-90deg);
|
143 |
+
-o-transform: rotate(-90deg);
|
144 |
+
-webkit-transform: rotate(-90deg);
|
145 |
+
-ms-transform: rotate(-90deg);
|
146 |
+
transform: rotate(-90deg);
|
147 |
+
filter: progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=6.123031769111886e-17, M12=1, M21=-1, M22=6.123031769111886e-17);
|
148 |
+
zoom: 1;
|
149 |
+
}
|
150 |
+
|
151 |
+
.rotate90 {
|
152 |
+
-moz-transform: rotate(90deg);
|
153 |
+
-o-transform: rotate(90deg);
|
154 |
+
-webkit-transform: rotate(90deg);
|
155 |
+
-ms-transform: rotate(90deg);
|
156 |
+
transform: rotate(90deg);
|
157 |
+
filter: progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=6.123031769111886e-17, M12=-1, M21=1, M22=6.123031769111886e-17);
|
158 |
+
zoom: 1;
|
159 |
+
}
|
160 |
+
|
161 |
+
.tm-image-editor-menu {
|
162 |
+
display: none;
|
163 |
+
position: absolute;
|
164 |
+
background-color: white;
|
165 |
+
border: 1px solid #C4C6C8;
|
166 |
+
padding: 4px 2px;
|
167 |
+
width: 104px;
|
168 |
+
z-index: 10;
|
169 |
+
}
|
170 |
+
|
171 |
+
.tm-image-editor-menu .rotate-image,
|
172 |
+
.tm-image-editor-menu .remove-image,
|
173 |
+
.tm-image-editor-menu .set-main-image {
|
174 |
+
display: block;
|
175 |
+
float: left;
|
176 |
+
width: 20px;
|
177 |
+
height: 20px;
|
178 |
+
border: 1px solid #C4C6C8;
|
179 |
+
margin: 0 2px;
|
180 |
+
cursor: pointer;
|
181 |
+
}
|
182 |
+
|
183 |
+
.tm-image-editor-menu .rotate-image:hover,
|
184 |
+
.tm-image-editor-menu .remove-image:hover,
|
185 |
+
.tm-image-editor-menu .set-main-image:hover {
|
186 |
+
border-color: #DE5400;
|
187 |
+
}
|
188 |
+
|
189 |
+
.tm-image-editor-menu .rotate-image.rotate-left {
|
190 |
+
background: url('../images/rotate-left-icon.png') no-repeat center;
|
191 |
+
}
|
192 |
+
|
193 |
+
.tm-image-editor-menu .rotate-image.rotate-right {
|
194 |
+
background: url('../images/rotate-right-icon.png') no-repeat center;
|
195 |
+
}
|
196 |
+
|
197 |
+
.tm-image-editor-menu .remove-image {
|
198 |
+
background: url('../images/remove-icon.png') no-repeat center;
|
199 |
+
}
|
200 |
+
|
201 |
+
.tm-image-editor-menu .set-main-image {
|
202 |
+
background: url('../images/main-image-icon.png') no-repeat center;
|
203 |
+
}
|
204 |
+
|
205 |
+
#productivity-image-edit-panel.productivity-state-main-image {
|
206 |
+
width: 78px;
|
207 |
+
}
|
208 |
+
|
209 |
+
#productivity-image-edit-panel.productivity-scope-uploader {
|
210 |
+
background: rgba(0, 0, 0, 0.6);
|
211 |
+
border: none;
|
212 |
+
padding: 0;
|
213 |
+
width: 100px;
|
214 |
+
height: 100px;
|
215 |
+
}
|
216 |
+
|
217 |
+
.productivity-scope-uploader .rotate-image.rotate-left,
|
218 |
+
.productivity-scope-uploader .rotate-image.rotate-right,
|
219 |
+
.productivity-scope-uploader .remove-image,
|
220 |
+
.productivity-scope-uploader .set-main-image {
|
221 |
+
background-color: #fff;
|
222 |
+
width: 36px;
|
223 |
+
height: 36px;
|
224 |
+
margin: 8px 0 0 8px;
|
225 |
+
}
|
226 |
+
|
227 |
+
.productivity-state-main-image .set-main-image {
|
228 |
+
display: none;
|
229 |
+
}
|
230 |
+
|
231 |
+
.productivity-state-warning {
|
232 |
+
border: 2px solid red !important;
|
233 |
+
}
|
234 |
+
|
235 |
+
.image-editor-loader{
|
236 |
+
display:none;
|
237 |
+
/* !!!FIX: add image to the extension */
|
238 |
+
background: url(/skin/frontend/default/default/images/loading.gif) no-repeat;
|
239 |
+
width: 32px;
|
240 |
+
height: 32px;
|
241 |
+
position: absolute;
|
242 |
+
top: 50%;
|
243 |
+
margin-top: -16px;
|
244 |
+
left: 50%;
|
245 |
+
margin-left: -16px;
|
246 |
+
}
|
247 |
+
|
248 |
+
#productivity-uploader {
|
249 |
+
display: none;
|
250 |
+
}
|
251 |
+
|
252 |
+
#productivity-uploader-notice {
|
253 |
+
display: none;
|
254 |
+
}
|
255 |
+
|
256 |
+
.productivity-state-uploaded #productivity-uploader-notice {
|
257 |
+
display: block;
|
258 |
+
-moz-animation: blink 1s 250ms 2;
|
259 |
+
-webkit-animation: blink 1s 250ms 2;
|
260 |
+
-o-animation: blink 1s 250ms 2;
|
261 |
+
-ms-animation: blink 1s 250ms 2;
|
262 |
+
animation: blink 1s 250ms 2;
|
263 |
+
}
|
264 |
+
|
265 |
+
#productivity-uploader-notice a {
|
266 |
+
background: url(../images/icon-attention.png) no-repeat 12px 7px;
|
267 |
+
padding: 0 12px 0 34px;
|
268 |
+
}
|
269 |
+
|
270 |
+
#productivity-uploader-notice span {
|
271 |
+
text-decoration: underline;
|
272 |
+
}
|
273 |
+
|
274 |
+
.productivity-task-edit-form-on #productivity-uploader {
|
275 |
+
float: left;
|
276 |
+
width: 104px;
|
277 |
+
margin: 0 20px 0 0;
|
278 |
+
}
|
279 |
+
|
280 |
+
#productivity-uploader-element {
|
281 |
+
display: none;
|
282 |
+
}
|
283 |
+
|
284 |
+
#productivity-uploader-dropzone,
|
285 |
+
#productivity-uploader-previews li {
|
286 |
+
width: 100px;
|
287 |
+
height: 100px;
|
288 |
+
border: 2px solid lightgray;
|
289 |
+
margin: 0 10px 7px 0;
|
290 |
+
}
|
291 |
+
|
292 |
+
#productivity-uploader-dropzone-wrapper {
|
293 |
+
float: left;
|
294 |
+
}
|
295 |
+
|
296 |
+
#productivity-uploader-dropzone {
|
297 |
+
border-style: dashed;
|
298 |
+
margin: 0 0 10px 0;
|
299 |
+
background: url('../images/uploader/add.png') 37px 5px no-repeat;
|
300 |
+
}
|
301 |
+
|
302 |
+
#productivity-uploader-dropzone span {
|
303 |
+
display: block;
|
304 |
+
margin: 37px 0 0;
|
305 |
+
padding: 0 5px 5px;
|
306 |
+
text-align: center;
|
307 |
+
}
|
308 |
+
|
309 |
+
#productivity-uploader-previews {
|
310 |
+
display: block;
|
311 |
+
margin: 0 0 0 114px;
|
312 |
+
}
|
313 |
+
|
314 |
+
.productivity-task-edit-form-on #productivity-uploader-previews {
|
315 |
+
margin: 0;
|
316 |
+
}
|
317 |
+
|
318 |
+
#productivity-uploader-previews li {
|
319 |
+
display: inline-block;
|
320 |
+
background: none center no-repeat;
|
321 |
+
background-size: cover;
|
322 |
+
position: relative;
|
323 |
+
}
|
324 |
+
|
325 |
+
#productivity-uploader-previews .qq-upload-file,
|
326 |
+
#productivity-uploader-previews .qq-upload-size,
|
327 |
+
#productivity-uploader-previews .qq-upload-delete,
|
328 |
+
#productivity-uploader-previews .qq-upload-retry,
|
329 |
+
#productivity-uploader-previews .qq-upload-status-text {
|
330 |
+
display: none !important;
|
331 |
+
}
|
332 |
+
|
333 |
+
#productivity-uploader-previews .qq-upload-fail {
|
334 |
+
border-color: green;
|
335 |
+
}
|
336 |
+
|
337 |
+
#productivity-uploader-previews .qq-upload-fail {
|
338 |
+
border-color: red;
|
339 |
+
}
|
340 |
+
|
341 |
+
#productivity-uploader-previews .qq-upload-success {
|
342 |
+
border-color: greenyellow;
|
343 |
+
}
|
344 |
+
|
345 |
+
#productivity-uploader-previews .qq-upload-success:before {
|
346 |
+
background: url("../images/icon-edit.png") no-repeat 4px 3px rgba(255, 255, 255, 0.35);
|
347 |
+
border-radius: 0 0 3px 0;
|
348 |
+
content: "";
|
349 |
+
display: block;
|
350 |
+
height: 23px;
|
351 |
+
width: 23px;
|
352 |
+
}
|
353 |
+
|
354 |
+
#productivity-uploader-previews .qq-progress-bar {
|
355 |
+
background: -moz-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%); /* FF3.6+ */
|
356 |
+
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(30,87,153,1)), color-stop(50%,rgba(41,137,216,1)), color-stop(51%,rgba(32,124,202,1)), color-stop(100%,rgba(125,185,232,1))); /* Chrome,Safari4+ */
|
357 |
+
background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* Chrome10+,Safari5.1+ */
|
358 |
+
background: -o-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* Opera 11.10+ */
|
359 |
+
background: -ms-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* IE10+ */
|
360 |
+
background: linear-gradient(to bottom, rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* W3C */
|
361 |
+
width: 0%;
|
362 |
+
height: 5px;
|
363 |
+
border-radius: 6px;
|
364 |
+
margin: 0 0 3px 0;
|
365 |
+
display: none;
|
366 |
+
position: absolute;
|
367 |
+
bottom: 0;
|
368 |
+
}
|
369 |
+
|
370 |
+
#productivity-uploader-previews .qq-upload-spinner {
|
371 |
+
display: block;
|
372 |
+
background: url('../images/uploader/loading.gif');
|
373 |
+
width: 15px;
|
374 |
+
height: 15px;
|
375 |
+
position: absolute;
|
376 |
+
top: 50%;
|
377 |
+
left: 50%;
|
378 |
+
margin: -7.5px 0 0 -7.5px;
|
379 |
+
}
|
380 |
+
|
381 |
+
#productivity-uploader-previews .qq-upload-cancel {
|
382 |
+
display: block;
|
383 |
+
background: url('../images/uploader/cancel.png');
|
384 |
+
width: 16px;
|
385 |
+
height: 16px;
|
386 |
+
position: absolute;
|
387 |
+
right: -8px;
|
388 |
+
top: -8px;
|
389 |
+
}
|
390 |
+
|
391 |
+
#productivity-edit-attributes {
|
392 |
+
float: left;
|
393 |
+
margin: 0 0 0 10px;
|
394 |
+
display: none;
|
395 |
+
}
|
396 |
+
|
397 |
+
#productivity-edit-attributes h3 {
|
398 |
+
margin: 0 0 5px 0;
|
399 |
+
}
|
400 |
+
|
401 |
+
#productivity-edit-attributes .field-row {
|
402 |
+
display: block;
|
403 |
+
margin: 0 0 10px;
|
404 |
+
}
|
405 |
+
|
406 |
+
#productivity-edit-attributes .field-row label {
|
407 |
+
display: block;
|
408 |
+
float: left;
|
409 |
+
width: 100px;
|
410 |
+
}
|
411 |
+
|
412 |
+
#productivity-edit-attributes .field-row input,
|
413 |
+
#productivity-edit-attributes .field-row textarea {
|
414 |
+
width: 500px;
|
415 |
+
}
|
416 |
+
|
417 |
+
#productivity-edit-attributes .field-row select {
|
418 |
+
/* selects do not obey padding in the same way so add the extra width here */
|
419 |
+
width: 506px;
|
420 |
+
}
|
421 |
+
|
422 |
+
#productivity_edit_form_cancel,
|
423 |
+
#productivity_edit_form_submit {
|
424 |
+
float: right;
|
425 |
+
margin: 0 0 0 5px;
|
426 |
+
padding: 2px 10px;
|
427 |
+
font-weight: bold;
|
428 |
+
}
|
429 |
+
|
430 |
+
/* Animations */
|
431 |
+
|
432 |
+
@-webkit-keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.3; } 100% { opacity: 1; } }
|
433 |
+
@-moz-keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.3; } 100% { opacity: 1; } }
|
434 |
+
@-o-keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.3; } 100% { opacity: 1; } }
|
435 |
+
@-ms-keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.3; } 100% { opacity: 1; } }
|
436 |
+
@keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.3; } 100% { opacity: 1; } }
|
skin/frontend/base/default/productivity/images/icon-attention.png
ADDED
Binary file
|
skin/frontend/base/default/productivity/images/icon-edit.png
ADDED
Binary file
|
skin/frontend/base/default/productivity/images/main-image-icon.png
ADDED
Binary file
|
skin/frontend/base/default/productivity/images/remove-icon.png
ADDED
Binary file
|
skin/frontend/base/default/productivity/images/rotate-left-icon.png
ADDED
Binary file
|
skin/frontend/base/default/productivity/images/rotate-right-icon.png
ADDED
Binary file
|
skin/frontend/base/default/productivity/images/uploader/add.png
ADDED
Binary file
|
skin/frontend/base/default/productivity/images/uploader/cancel.png
ADDED
Binary file
|
skin/frontend/base/default/productivity/images/uploader/loading.gif
ADDED
Binary file
|