BothInteract_CleanProductTexts - Version 1.0.0

Version Notes

Initial public release.

Download this release

Release Info

Developer Matthias Kerstner
Extension BothInteract_CleanProductTexts
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

app/code/community/BothInteract/CleanProductTexts/Model/Observer.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Handles product cleaning based on configuration set in backend.
5
+ *
6
+ * This class writes log messages to a custom log file specified by
7
+ * @see self::$LOG_FILE.
8
+ *
9
+ * @author Matthias Kerstner <matthias@both-interact.com>
10
+ * @version 1.0.0
11
+ * @copyright (c) 2015, Both Interact GmbH
12
+ */
13
+ class BothInteract_CleanProductTexts_Model_Observer {
14
+
15
+ /** @var boolean flag to avoid recursion when saving products in this observer */
16
+ private $_isProcessed = false;
17
+
18
+ /** @var string this module's namespace */
19
+ private static $_MODULE_NAMESPACE = 'bothinteract_cleanproducttexts';
20
+
21
+ /**
22
+ * Logs $msg to logfile specified in configuration.
23
+ * @param string $msg
24
+ */
25
+ private function logToFile($msg) {
26
+ Mage::log($msg, null, Mage::getStoreConfig(
27
+ self::$_MODULE_NAMESPACE
28
+ . '/general/log_file', Mage::app()->getStore()));
29
+ }
30
+
31
+ /**
32
+ * Handles product based on $cleaningOptions specified.
33
+ * @param Mage_Catalog_Model_Product $product
34
+ * @var array $cleaningOptions
35
+ */
36
+ private function handleProduct(Mage_Catalog_Model_Product $product, $cleaningOptions) {
37
+ $this->logToFile('Handling '
38
+ . mb_strtoupper($product->getTypeId())
39
+ . ' product ' . $product->getId());
40
+
41
+ foreach ($cleaningOptions as $cleaningOption) {
42
+ $this->logToFile('Checking option ' . $cleaningOption);
43
+
44
+ // remove control characters for description and short description
45
+ if ($cleaningOption == BothInteract_CleanProductTexts_Model_System_Config_Source_View::$VALUE_CLEANING_TYPE_CONTROL_CHARACTERS) {
46
+ // @see http://unicode-table.com/en/
47
+ $this->logToFile('Cleaning product ' . $product->getId());
48
+
49
+ $regexp = '/[^\PC\s]/u'; //i.e. /[\x00—\x1F\x80-\x9f]
50
+ $product->setDescription(preg_replace('/\x0b/', '', preg_replace($regexp, '', $product->getDescription())));
51
+ $product->setShortDescription(preg_replace('/\x0b/', '', preg_replace($regexp, '', $product->getShortDescription())));
52
+ }
53
+ }
54
+
55
+ if (Mage::getStoreConfig(self::$_MODULE_NAMESPACE
56
+ . '/general/is_simulation')) {
57
+ $this->logToFile('************************************');
58
+ $this->logToFile('SIMULATION: Not saving product '
59
+ . $product->getId());
60
+ $this->logToFile('************************************');
61
+ } else {
62
+ $this->logToFile('Saving product ' . $product->getId());
63
+ $product->save();
64
+ }
65
+
66
+ $this->logToFile('Successfully handled product ' . $product->getId());
67
+ }
68
+
69
+ /**
70
+ * Handles product save event calls by checking product type.
71
+ * @param Varien_Event_Observer $observer
72
+ */
73
+ public function catalog_product_save_after(Varien_Event_Observer $observer) {
74
+ try {
75
+ if (!Mage::getStoreConfig(self::$_MODULE_NAMESPACE
76
+ . '/general/is_active', Mage::app()->getStore())) {
77
+ $this->logToFile('Extension INACTIVE - Quitting...');
78
+ return;
79
+ }
80
+
81
+ if (!$this->_isProcessed) {
82
+ $this->_isProcessed = true; // avoid recursion on save()
83
+ $this->processProduct($observer->getProduct());
84
+ } else {
85
+ $this->logToFile('Product already processed '
86
+ . $observer->getProduct()->getId());
87
+ }
88
+ } catch (Exception $e) {
89
+ $this->logToFile('ERROR: ' . $e->getMessage());
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Can be of any product type, e.g. configurable, grouped, simple,
95
+ * @param Mage_Catalog_Model_Product $product Can be of any valid product
96
+ * type, e.g. configurable, grouped, simple, ...
97
+ */
98
+ public function processProduct(Mage_Catalog_Model_Product $product) {
99
+ try {
100
+ $this->logToFile('==================================================');
101
+ $this->logToFile('Checking product ' . $product->getId()
102
+ . ' of type ' . mb_strtoupper($product->getTypeId())
103
+ . '...');
104
+
105
+ /**
106
+ * @var array cleaning options selected in configuration.
107
+ *
108
+ * Options are taken from system config source view.
109
+ */
110
+ $cleaningOptions = explode(',', Mage::getStoreConfig(self::$_MODULE_NAMESPACE
111
+ . '/general/cleaning_options', Mage::app()->getStore()));
112
+
113
+ $this->logToFile('Cleaning options: ['
114
+ . implode(',', $cleaningOptions) . ']');
115
+
116
+ $this->handleProduct($product, $cleaningOptions);
117
+
118
+ $this->logToFile('Done processing product ' . $product->getId() . '!');
119
+ } catch (Exception $e) {
120
+ $this->logToFile('ERROR: ' . $e->getMessage());
121
+ }
122
+ }
123
+
124
+ }
app/code/community/BothInteract/CleanProductTexts/Model/System/Config/Source/View.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @author Matthias Kerstner <matthias@both-interact.com>
5
+ * @version 1.0.0
6
+ * @copyright (c) 2015, Both Interact GmbH
7
+ */
8
+ class BothInteract_CleanProductTexts_Model_System_Config_Source_View {
9
+
10
+ public static $VALUE_CLEANING_TYPE_CONTROL_CHARACTERS = 0;
11
+
12
+ /**
13
+ * Options getter
14
+ *
15
+ * @return array
16
+ */
17
+ public function toOptionArray() {
18
+ return array(
19
+ array('value' => self::$VALUE_CLEANING_TYPE_CONTROL_CHARACTERS, 'label' => Mage::helper('adminhtml')->__('Control characters')),
20
+ );
21
+ }
22
+
23
+ /**
24
+ * Get options in "key-value" format
25
+ *
26
+ * @return array
27
+ */
28
+ public function toArray() {
29
+ return array(
30
+ self::$VALUE_CLEANING_TYPE_CONTROL_CHARACTERS => Mage::helper('adminhtml')->__('Control characters')
31
+ );
32
+ }
33
+
34
+ }
app/code/community/BothInteract/CleanProductTexts/etc/adminhtml.xml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" ?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <all>
6
+ <title>Allow Everything</title>
7
+ </all>
8
+ <admin>
9
+ <children>
10
+ <system>
11
+ <children>
12
+ <config>
13
+ <children>
14
+ <bothinteract_cleanproducttexts translate="title" module="bothinteract_cleanproducttexts">
15
+ <title>General</title>
16
+ <sort_order>100</sort_order>
17
+ </bothinteract_cleanproducttexts>
18
+ </children>
19
+ </config>
20
+ </children>
21
+ </system>
22
+ </children>
23
+ </admin>
24
+ </resources>
25
+ </acl>
26
+ </config>
app/code/community/BothInteract/CleanProductTexts/etc/config.xml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+
3
+ <config>
4
+
5
+ <modules>
6
+ <BothInteract_CleanProductTexts>
7
+ <version>1.0.0</version>
8
+ </BothInteract_CleanProductTexts>
9
+ </modules>
10
+
11
+ <global>
12
+ <!-- inform Magento of our new model class-->
13
+ <models>
14
+ <bothinteract_cleanproducttexts>
15
+ <class>BothInteract_CleanProductTexts_Model</class>
16
+ </bothinteract_cleanproducttexts>
17
+ </models>
18
+ <!-- attach our observer class to catalog_product_save_after event-->
19
+ <events>
20
+ <catalog_product_save_after>
21
+ <observers>
22
+ <bothinteract_cleanproducttexts_model_observer>
23
+ <type>singleton</type>
24
+ <class>BothInteract_CleanProductTexts_Model_Observer</class>
25
+ <method>catalog_product_save_after</method>
26
+ </bothinteract_cleanproducttexts_model_observer>
27
+ </observers>
28
+ </catalog_product_save_after>
29
+ </events>
30
+ </global>
31
+
32
+ <default>
33
+ <bothinteract_cleanproducttexts>
34
+ <general>
35
+ <is_active>0</is_active>
36
+ <is_simulation>1</is_simulation>
37
+ <required_image_types></required_image_types>
38
+ <log_file>cleanproducttexts.log</log_file>
39
+ </general>
40
+ </bothinteract_cleanproducttexts>
41
+ </default>
42
+ </config>
app/code/community/BothInteract/CleanProductTexts/etc/system.xml ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+
3
+ <config>
4
+
5
+ <tabs>
6
+ <bothinteract translate="label">
7
+ <label>Both Interact GmbH</label>
8
+ <sort_order>100</sort_order>
9
+ </bothinteract>
10
+ </tabs>
11
+
12
+ <sections>
13
+ <bothinteract_cleanproducttexts translate="label" module="adminhtml">
14
+ <label>Clean Product Texts</label>
15
+ <tab>bothinteract</tab>
16
+ <frontend_type>text</frontend_type>
17
+ <sort_order>1000</sort_order>
18
+ <show_in_default>1</show_in_default>
19
+ <show_in_website>1</show_in_website>
20
+ <show_in_store>1</show_in_store>
21
+
22
+ <groups>
23
+ <general translate="label">
24
+ <label>General</label>
25
+ <frontend_type>text</frontend_type>
26
+ <sort_order>50</sort_order>
27
+ <show_in_default>1</show_in_default>
28
+ <show_in_website>1</show_in_website>
29
+ <show_in_store>1</show_in_store>
30
+
31
+ <fields>
32
+ <is_active translate="label">
33
+ <label>Active</label>
34
+ <comment>
35
+ <![CDATA[Check this box to <b>activate</b> automatic cleaning when adding/saving your products
36
+ and enable the shell script (optional).]]>
37
+ </comment>
38
+ <frontend_type>select</frontend_type>
39
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
40
+ <sort_order>1</sort_order>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>1</show_in_website>
43
+ <show_in_store>1</show_in_store>
44
+ </is_active>
45
+ <is_simulation translate="label">
46
+ <label>Simulate</label>
47
+ <comment>
48
+ <![CDATA[Check this box to <b>simulate</b> product cleaning. Your products will <b>not</b> be changed.
49
+ Please refer to log for more information.]]>
50
+ </comment>
51
+ <frontend_type>select</frontend_type>
52
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
53
+ <sort_order>2</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>1</show_in_website>
56
+ <show_in_store>1</show_in_store>
57
+ </is_simulation>
58
+ <cleaning_options translate="label">
59
+ <label>Cleaning options</label>
60
+ <comment>
61
+ <![CDATA[Please select desired cleaning option(s) for your products.]]>
62
+ </comment>
63
+ <frontend_type>multiselect</frontend_type>
64
+ <source_model>BothInteract_CleanProductTexts_Model_System_Config_Source_View</source_model>
65
+ <sort_order>4</sort_order>
66
+ <show_in_default>1</show_in_default>
67
+ <show_in_website>1</show_in_website>
68
+ <show_in_store>1</show_in_store>
69
+ </cleaning_options>
70
+ <log_file translate="label">
71
+ <label>Log file</label>
72
+ <comment>
73
+ <![CDATA[Please specify a name for your custom <b>log file</b>.]]>
74
+ </comment>
75
+ <frontend_type>text</frontend_type>
76
+ <sort_order>5</sort_order>
77
+ <show_in_default>1</show_in_default>
78
+ <show_in_website>1</show_in_website>
79
+ <show_in_store>1</show_in_store>
80
+ </log_file>
81
+ </fields>
82
+ </general>
83
+ </groups>
84
+ </bothinteract_cleanproducttexts>
85
+ </sections>
86
+ </config>
app/etc/modules/BothInteract_CleanProductTexts.xml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+
3
+ <config>
4
+ <modules>
5
+ <BothInteract_CleanProductTexts>
6
+ <active>true</active>
7
+ <codePool>community</codePool>
8
+ </BothInteract_CleanProductTexts>
9
+ </modules>
10
+ </config>
package.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>BothInteract_CleanProductTexts</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://www.opensource.org/licenses/mit-license.php">MIT License (MITL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>This extension helps you to automatically clean product texts.</summary>
10
+ <description>&lt;p&gt;This extension helps you to automatically clean your product texts (description and short description) by removing unwanted (invisible) control characters that might cause problems with other extensions or when exporting products.&lt;/p&gt;&#xD;
11
+ &#xD;
12
+ &lt;p&gt;Oftentimes, unwanted characters are copied into product descriptions when copying texts from PDF documents. Since these control characters are not displayed by browsers they cannot be removed manually from Magento's editor.&lt;/p&gt;&#xD;
13
+ &#xD;
14
+ &lt;p&gt;This extension will check your product texts and automatically removed unwanted characters.&lt;/p&gt;&#xD;
15
+ &#xD;
16
+ &lt;p&gt;Thus, your employees can still copy texts from e.g. PDFs directly into Magento - this extension will take care of removing unwanted characters when saving products.&lt;/p&gt;&#xD;
17
+ &#xD;
18
+ &lt;h3&gt;Simulate Product Cleaning&lt;/h3&gt;&#xD;
19
+ &lt;p&gt;Furthermore, you can also &lt;b&gt;simulate&lt;/b&gt; the process of cleaning product texts by activating the corresponding option in the configuration under &lt;i&gt;General&lt;/i&gt; / &lt;i&gt;Simulate&lt;/i&gt;.&lt;/p&gt;&#xD;
20
+ &#xD;
21
+ &lt;h3&gt;Log File&lt;/h3&gt;&#xD;
22
+ &lt;p&gt;In addition this extension enabled you to logs messages to a custom log file that can be specified in the configuration options to your log directory under &lt;i&gt;General&lt;/i&gt; / &lt;i&gt;Log File&lt;/i&gt;.&lt;/p&gt; &#xD;
23
+ &#xD;
24
+ &lt;p&gt;So you have the option to easily track events handled by this extension and check for possible problems.&lt;/p&gt;</description>
25
+ <notes>Initial public release.</notes>
26
+ <authors><author><name>Matthias Kerstner</name><user>mkbothinteract</user><email>matthias@both-interact.com</email></author></authors>
27
+ <date>2015-03-06</date>
28
+ <time>12:52:21</time>
29
+ <contents><target name="magecommunity"><dir name="BothInteract"><dir name="CleanProductTexts"><dir name="Model"><file name="Observer.php" hash="fa5e9b0483e429093f7ed413727f99bb"/><dir name="System"><dir name="Config"><dir name="Source"><file name="View.php" hash="06c8cab69af1427591ccd80a5ff84b85"/></dir></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="09afe6511e6b0c1ee544c2ca87d59474"/><file name="config.xml" hash="8b3dceb0487024d8822a504af9c0241e"/><file name="system.xml" hash="9250f6bd8e3089b823c46138e1d6622f"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="BothInteract_CleanProductTexts.xml" hash="c685308779c1427921191dd9860627a1"/></dir></target></contents>
30
+ <compatible/>
31
+ <dependencies><required><php><min>5.3.0</min><max>5.6.6</max></php></required></dependencies>
32
+ </package>