Zero1_Seoredirects - Version 1.1.1

Version Notes

Upgrade from 1.0.X
- Add From Types
- Added the ability to persist query
- Add the ability to automatically ignore query variables
- Reworked import process.
- Add the ability to log 404s automatically
- Made the redirect key global
- Import files are now locked to store scope.
- Added redirection summary to view page.
- Added reporting options
- Added url caching feature, to improve performance.
- Added the ability to import a google doc as HTML or CSV
- Added the ability to manage redirects from a gid page (add, edit, delete, mass delete, export)
- Added Hit counter.

Download this release

Release Info

Developer Arron Moss
Extension Zero1_Seoredirects
Version 1.1.1
Comparing to
See all releases


Code changes from version 1.0.17 to 1.1.1

Files changed (60) hide show
  1. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Edit.php +68 -0
  2. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Edit/Form.php +129 -0
  3. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Import.php +37 -0
  4. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Import/Report.php +43 -0
  5. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage.php +99 -0
  6. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage/Grid.php +225 -0
  7. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage/Grid/Renderer/Options.php +14 -0
  8. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage/Grid/Renderer/Url.php +17 -0
  9. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage/Report.php +41 -0
  10. app/code/community/Zero1/Seoredirects/Block/Adminhtml/Settings/Params.php +88 -0
  11. app/code/community/Zero1/Seoredirects/Block/Adminhtml/System/Config/Form.php +23 -0
  12. app/code/community/Zero1/Seoredirects/Block/Adminhtml/System/Config/Form/Field.php +94 -0
  13. app/code/community/Zero1/Seoredirects/Block/Adminhtml/System/Config/Form/Field/File.php +135 -0
  14. app/code/community/Zero1/Seoredirects/Block/Manage.php +0 -21
  15. app/code/community/Zero1/Seoredirects/Block/Manage/Grid.php +0 -61
  16. app/code/community/Zero1/Seoredirects/Exception.php +18 -0
  17. app/code/community/Zero1/Seoredirects/Helper/Data.php +239 -1
  18. app/code/community/Zero1/Seoredirects/Helper/Files.php +94 -0
  19. app/code/community/Zero1/Seoredirects/Helper/Hints.php +27 -0
  20. app/code/community/Zero1/Seoredirects/Helper/License.php +26 -5
  21. app/code/community/Zero1/Seoredirects/Helper/Urls.php +91 -0
  22. app/code/community/Zero1/Seoredirects/Model/Adminhtml/System/Config/Backend/File.php +99 -0
  23. app/code/community/Zero1/Seoredirects/Model/Adminhtml/System/Config/Backend/Number.php +55 -0
  24. app/code/community/Zero1/Seoredirects/Model/Adminhtml/System/Config/Source/LogLevels.php +33 -0
  25. app/code/community/Zero1/Seoredirects/Model/File.php +15 -0
  26. app/code/community/Zero1/Seoredirects/Model/Importer.php +604 -0
  27. app/code/community/Zero1/Seoredirects/Model/Mysql4/Redirection.php +0 -5
  28. app/code/community/Zero1/Seoredirects/Model/Mysql4/Redirection/Collection.php +0 -6
  29. app/code/community/Zero1/Seoredirects/Model/Observer.php +15 -250
  30. app/code/community/Zero1/Seoredirects/Model/Redirection.php +295 -1
  31. app/code/community/Zero1/Seoredirects/Model/Redirection/Cache.php +17 -0
  32. app/code/community/Zero1/Seoredirects/Model/Redirector.php +254 -0
  33. app/code/community/Zero1/Seoredirects/Model/Resource/Redirection.php +19 -1
  34. app/code/community/Zero1/Seoredirects/Model/Resource/Redirection/Cache.php +12 -0
  35. app/code/community/Zero1/Seoredirects/Model/Resource/Redirection/Cache/Collection.php +15 -0
  36. app/code/community/Zero1/Seoredirects/Model/Resource/Redirection/Collection.php +12 -1
  37. app/code/community/Zero1/Seoredirects/Model/Source/Files.php +0 -33
  38. app/code/community/Zero1/Seoredirects/TODO.txt +48 -0
  39. app/code/community/Zero1/Seoredirects/controllers/Adminhtml/Seoredirects/ConfigController.php +24 -0
  40. app/code/community/Zero1/Seoredirects/controllers/Adminhtml/Seoredirects/ImportController.php +35 -0
  41. app/code/community/Zero1/Seoredirects/controllers/Adminhtml/Seoredirects/ManageController.php +146 -9
  42. app/code/community/Zero1/Seoredirects/etc/adminhtml.xml +9 -4
  43. app/code/community/Zero1/Seoredirects/etc/config.xml +29 -30
  44. app/code/community/Zero1/Seoredirects/etc/system.xml +149 -27
  45. app/code/community/Zero1/Seoredirects/sql/seoredirects_setup/install-1.0.0.php +0 -19
  46. app/code/community/Zero1/Seoredirects/sql/seoredirects_setup/install-1.0.1.php +0 -19
  47. app/code/community/Zero1/Seoredirects/sql/seoredirects_setup/mysql4-install-1.0.0.php +0 -19
  48. app/code/community/Zero1/Seoredirects/sql/seoredirects_setup/mysql4-install-1.0.1.php +0 -19
  49. app/code/community/Zero1/Seoredirects/sql/zero1_seoredirects_setup/install-1.1.0.php +45 -0
  50. app/code/community/Zero1/Seoredirects/sql/zero1_seoredirects_setup/upgrade-1.1.0-1.1.1.php +101 -0
  51. app/design/adminhtml/default/default/layout/seoredirects.xml +0 -13
  52. app/design/adminhtml/default/default/layout/zero1/seoredirects.xml +37 -0
  53. app/design/adminhtml/default/default/template/zero1/seoredirects/edit.phtml +44 -0
  54. app/design/adminhtml/default/default/template/zero1/seoredirects/import/container.phtml +11 -0
  55. app/design/adminhtml/default/default/template/zero1/seoredirects/import/report.phtml +90 -0
  56. app/design/adminhtml/default/default/template/zero1/seoredirects/manage.phtml +18 -0
  57. app/design/adminhtml/default/default/template/zero1/seoredirects/manage/report.phtml +25 -0
  58. app/etc/modules/Zero1_Seoredirects.xml +7 -9
  59. package.xml +20 -8
  60. var/Zero1/SeoRedirects/data/template.csv +1 -0
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Edit.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ /**
29
+ * Sitemap edit form container
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Adminhtml
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Zero1_Seoredirects_Block_Adminhtml_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
36
+ {
37
+
38
+ /**
39
+ * Init container
40
+ */
41
+ public function __construct()
42
+ {
43
+ $this->_controller = 'seoredirects_manage';
44
+ $this->_mode = false;
45
+ parent::__construct();
46
+ }
47
+
48
+ /**
49
+ * Get edit form container header text
50
+ *
51
+ * @return string
52
+ */
53
+ public function getHeaderText()
54
+ {
55
+ if (Mage::registry('zero1_seo_redirect')->getId()) {
56
+ return Mage::helper('zero1_seo_redirects')->__('Edit Seo Redirect');
57
+ }
58
+ else {
59
+ return Mage::helper('zero1_seo_redirects')->__('New Seo Redirect');
60
+ }
61
+ }
62
+
63
+ protected function _prepareLayout()
64
+ {
65
+ $this->setChild('form', $this->getLayout()->createBlock('zero1_seo_redirects/adminhtml_edit_form'));
66
+ return parent::_prepareLayout();
67
+ }
68
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Edit/Form.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ /**
29
+ * Sitemap edit form
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Adminhtml
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Zero1_Seoredirects_Block_Adminhtml_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
36
+ {
37
+ /**
38
+ * Init form
39
+ */
40
+ public function __construct()
41
+ {
42
+ parent::__construct();
43
+ $this->setId('redirection_form');
44
+ $this->setTitle(Mage::helper('adminhtml')->__('Redirection Information'));
45
+ }
46
+
47
+
48
+ protected function _prepareForm()
49
+ {
50
+ $model = Mage::registry('zero1_seo_redirect');
51
+
52
+ $form = new Varien_Data_Form(array(
53
+ 'id' => 'edit_form',
54
+ 'action' => $this->getData('action'),
55
+ 'method' => 'post'
56
+ ));
57
+
58
+ $fieldset = $form->addFieldset('add_seo_redirect_form', array('legend' => Mage::helper('zero1_seo_redirects')->__('Seo Redirection')));
59
+
60
+ if ($model->getId()) {
61
+ $fieldset->addField('redirection_id', 'hidden', array(
62
+ 'name' => 'redirection_id',
63
+ ));
64
+ }
65
+
66
+ $fieldset->addField('source', 'hidden', array(
67
+ 'name' => 'source',
68
+ ));
69
+ if(!$model->getSource()){
70
+ $model->setSource(Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_MANUAL_VALUE);
71
+ }
72
+
73
+ $fieldset->addField('store_id', 'select', array(
74
+ 'label' => Mage::helper('adminhtml')->__('Store'),
75
+ 'title' => Mage::helper('adminhtml')->__('Store'),
76
+ 'name' => 'store_id',
77
+ 'required' => true,
78
+ 'options' => Mage::helper('zero1_seo_redirects')->getStoreUrls(),
79
+ ));
80
+
81
+ $fieldset->addField('from_url_path', 'text', array(
82
+ 'label' => Mage::helper('zero1_seo_redirects')->__('From URL'),
83
+ 'name' => 'from_url_path',
84
+ 'required' => true,
85
+ 'note' => Mage::helper('zero1_seo_redirects')->__('example: example/b/?foo=bar'),
86
+ 'value' => $model->getFromUrlPath()
87
+ ));
88
+
89
+ $fieldset->addField('from_type', 'select', array(
90
+ 'label' => Mage::helper('adminhtml')->__('From Type'),
91
+ 'title' => Mage::helper('adminhtml')->__('From Type'),
92
+ 'name' => 'from_type',
93
+ 'required' => true,
94
+ 'options' => Mage::helper('zero1_seo_redirects')->getFromTypes(),
95
+ ));
96
+ if($model->getFromType() == null){
97
+ $model->setFromType(Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_VALUE);
98
+ }
99
+
100
+ $hidden = false;
101
+ // if($model->getFromType() == Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_VALUE){
102
+ // $hidden = true;
103
+ // }
104
+
105
+ $fieldset->addField('persist_query', 'select', array(
106
+ 'label' => Mage::helper('adminhtml')->__('Persist Query'),
107
+ 'title' => Mage::helper('adminhtml')->__('Persist Query'),
108
+ 'name' => 'persist_query',
109
+ 'required' => false,
110
+ 'options' => array(0 => 'No', 1 => 'Yes'),
111
+ 'note' => 'Only applicable if from type is '.Zero1_Seoredirects_Model_Redirection::FROM_TYPE_OPEN_ENDED_QUERY_LABEL
112
+ ));
113
+
114
+ $fieldset->addField('to_url', 'text', array(
115
+ 'label' => Mage::helper('zero1_seo_redirects')->__('To URL'),
116
+ 'name' => 'to_url',
117
+ 'required' => true,
118
+ 'note' => Mage::helper('zero1_seo_redirects')->__('example: moved/here/?b=a'),
119
+ 'value' => $model->getFromUrl()
120
+ ));
121
+
122
+ $form->setValues($model->getData());
123
+ $form->setUseContainer(true);
124
+ $this->setForm($form);
125
+
126
+ return parent::_prepareForm();
127
+ }
128
+
129
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Import.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Block_Adminhtml_Import extends Mage_Adminhtml_Block_Widget_Container
3
+ {
4
+ public function __construct()
5
+ {
6
+ //$this->_controller = 'system_store';
7
+ $this->_headerText = Mage::helper('adminhtml')->__('Import Redirects');
8
+ $this->setTemplate('zero1/seoredirects/import/container.phtml');
9
+ parent::__construct();
10
+ }
11
+
12
+ protected function _prepareLayout()
13
+ {
14
+ $this->_addButton('run', array(
15
+ 'label' => Mage::helper('core')->__('Run Import'),
16
+ 'onclick' =>
17
+ 'new Ajax.Request(\''.$this->getUrl('*/*/run').'\', {
18
+ onSuccess: function(transport){
19
+ $(\'report-container\').update(transport.responseText);
20
+ }
21
+ });',
22
+ 'class' => 'add',
23
+ ));
24
+
25
+ return parent::_prepareLayout();
26
+ }
27
+
28
+ /**
29
+ * Retrieve grid
30
+ *
31
+ * @return string
32
+ */
33
+ public function getGridHtml()
34
+ {
35
+ return $this->getLayout()->createBlock('zero1_seo_redirects/adminhtml_import_grid')->toHtml();
36
+ }
37
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Import/Report.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Block_Adminhtml_Import_Report extends Mage_Adminhtml_Block_Template{
3
+
4
+ protected $_template = 'zero1/seoredirects/import/report.phtml';
5
+
6
+ public function getSeverityLabel($sev){
7
+ switch($sev){
8
+ case Zend_Log::DEBUG:
9
+ return 'Debug';
10
+ break;
11
+ case Zend_Log::INFO:
12
+ return 'Info';
13
+ break;
14
+ case Zend_Log::WARN:
15
+ return 'Warning';
16
+ break;
17
+ case Zend_Log::NOTICE:
18
+ return 'Notice';
19
+ break;
20
+ default:
21
+ return 'Not setup: '.$sev;
22
+ }
23
+ }
24
+
25
+ public function getSeverityColor($sev){
26
+ switch($sev){
27
+ case Zend_Log::DEBUG:
28
+ return '#00b0b8';
29
+ break;
30
+ case Zend_Log::INFO:
31
+ return '#ffffff';
32
+ break;
33
+ case Zend_Log::WARN:
34
+ return '#f6602e';
35
+ break;
36
+ case Zend_Log::NOTICE:
37
+ return '#ee7f5a';
38
+ break;
39
+ default:
40
+ return '#fff68f';
41
+ }
42
+ }
43
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Catalog manage products block
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Adminhtml
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Zero1_Seoredirects_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_Widget_Container
35
+ {
36
+ /**
37
+ * Set template
38
+ */
39
+ public function __construct()
40
+ {
41
+ parent::__construct();
42
+ $this->setTemplate('zero1/seoredirects/manage.phtml');
43
+ }
44
+
45
+ /**
46
+ * Prepare button and grid
47
+ *
48
+ * @return Zero1_Seoredirects_Block_Adminhtml_Manage
49
+ */
50
+ protected function _prepareLayout()
51
+ {
52
+ $this->_addButton('add_new', array(
53
+ 'label' => Mage::helper('catalog')->__('Add Redirect'),
54
+ 'onclick' => "setLocation('".$this->getUrl('*/*/new')."')",
55
+ 'class' => 'add'
56
+ ));
57
+ // $this->_addButton('refresh', array(
58
+ // 'label' => Mage::helper('catalog')->__('Refresh URLs'),
59
+ // 'onclick' => "setLocation('{$this->getUrl('*/*/update')}')",
60
+ // 'class' => 'refresh'
61
+ // ));
62
+
63
+ $this->setChild('grid', $this->getLayout()->createBlock('zero1_seo_redirects/adminhtml_manage_grid', 'redirect.grid'));
64
+ return parent::_prepareLayout();
65
+ }
66
+
67
+ /**
68
+ * Deprecated since 1.3.2
69
+ *
70
+ * @return string
71
+ */
72
+ public function getAddNewButtonHtml()
73
+ {
74
+ return $this->getChildHtml('add_new_button');
75
+ }
76
+
77
+ /**
78
+ * Render grid
79
+ *
80
+ * @return string
81
+ */
82
+ public function getGridHtml()
83
+ {
84
+ return $this->getChildHtml('grid');
85
+ }
86
+
87
+ /**
88
+ * Check whether it is single store mode
89
+ *
90
+ * @return bool
91
+ */
92
+ public function isSingleStoreMode()
93
+ {
94
+ if (!Mage::app()->isSingleStoreMode()) {
95
+ return false;
96
+ }
97
+ return true;
98
+ }
99
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage/Grid.php ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Adminhtml customer grid block
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Adminhtml
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Zero1_Seoredirects_Block_Adminhtml_Manage_Grid extends Mage_Adminhtml_Block_Widget_Grid
35
+ {
36
+
37
+ public function __construct()
38
+ {
39
+ parent::__construct();
40
+ $this->setId('manageGrid');
41
+ $this->setDefaultSort('entity_id');
42
+ $this->setDefaultDir('DESC');
43
+ $this->setSaveParametersInSession(true);
44
+ $this->setUseAjax(true);
45
+ //$this->setVarNameFilter('product_filter');
46
+ }
47
+
48
+ protected function _getStore()
49
+ {
50
+ $storeId = (int) $this->getRequest()->getParam('store', 0);
51
+ return Mage::app()->getStore($storeId);
52
+ }
53
+
54
+ protected function _prepareCollection()
55
+ {
56
+ /* @var $collection Zero1_Seoredirects_Model_Resource_Redirection_Collection */
57
+ $store = $this->_getStore();
58
+ $collection = Mage::getModel('zero1_seo_redirects/redirection')->getCollection();
59
+ $collection->addExpressionFieldToSelect(
60
+ 'from_url',
61
+ 'CONCAT({{from_url_path}}, IF({{from_url_query}}=\'\', \'\', \'?\'), {{from_url_query}})',
62
+ array('from_url_path'=>'from_url_path', 'from_url_query'=>'from_url_query')
63
+ );
64
+
65
+ if ($store->getId()) {
66
+ $collection->addFieldToFilter('store_id', $store->getId());
67
+ }
68
+
69
+ $this->setCollection($collection);
70
+
71
+ parent::_prepareCollection();
72
+
73
+ return $this;
74
+ }
75
+
76
+ protected function _prepareColumns()
77
+ {
78
+ $this->addColumn('redirection_id',
79
+ array(
80
+ 'header'=> Mage::helper('catalog')->__('ID'),
81
+ 'width' => '50px',
82
+ 'type' => 'number',
83
+ 'index' => 'redirection_id',
84
+ 'is_system' => true,
85
+ ));
86
+
87
+ $this->addColumn('from_url', array(
88
+ 'header' => Mage::helper('catalog')->__('From'),
89
+ 'header_export' => 'from-url',
90
+ 'index' => 'from_url',
91
+ 'filter_index' => 'CONCAT(from_url_path, IF(from_url_query=\'\', \'\', \'?\'), from_url_query)',
92
+ 'renderer' => 'zero1_seo_redirects/adminhtml_manage_grid_renderer_url',
93
+ ));
94
+
95
+ $this->addColumn('to_url', array(
96
+ 'header' => Mage::helper('catalog')->__('To'),
97
+ 'header_export' => 'to-url',
98
+ 'index' => 'to_url',
99
+ 'renderer' => 'zero1_seo_redirects/adminhtml_manage_grid_renderer_url',
100
+ ));
101
+
102
+ $this->addColumn('from_type',
103
+ array(
104
+ 'header'=> Mage::helper('catalog')->__('From Type'),
105
+ 'header_export' => 'type',
106
+ 'width' => '125px',
107
+ 'index' => 'from_type',
108
+ 'type' => 'options',
109
+ 'options' => Mage::helper('zero1_seo_redirects')->getFromTypes(),
110
+ 'renderer' => 'zero1_seo_redirects/adminhtml_manage_grid_renderer_options',
111
+
112
+ ));
113
+
114
+ $this->addColumn('persist_query',
115
+ array(
116
+ 'header'=> Mage::helper('catalog')->__('Persist Query'),
117
+ 'header_export' => 'persist-query',
118
+ 'width' => '75px',
119
+ 'index' => 'persist_query',
120
+ 'type' => 'options',
121
+ 'options' => array(0 => 'No', 1 => 'Yes'),
122
+ 'renderer' => 'zero1_seo_redirects/adminhtml_manage_grid_renderer_options',
123
+ ));
124
+
125
+ $this->addColumn('source',
126
+ array(
127
+ 'header'=> Mage::helper('catalog')->__('Source'),
128
+ 'width' => '100px',
129
+ 'index' => 'source',
130
+ 'type' => 'options',
131
+ 'options' => Mage::helper('zero1_seo_redirects')->getSources(),
132
+ 'is_system' => true,
133
+ ));
134
+
135
+ $this->addColumn('status',
136
+ array(
137
+ 'header'=> Mage::helper('catalog')->__('Status'),
138
+ 'width' => '75px',
139
+ 'index' => 'status',
140
+ 'type' => 'options',
141
+ 'options' => Mage::helper('zero1_seo_redirects')->getStatuses(),
142
+ 'is_system' => true,
143
+ ));
144
+
145
+ $this->addColumn('hits',
146
+ array(
147
+ 'header'=> Mage::helper('catalog')->__('Hits'),
148
+ 'width' => '75px',
149
+ 'index' => 'hits',
150
+ 'type' => 'number',
151
+ 'is_system' => true,
152
+ ));
153
+
154
+ $this->addColumn('action',
155
+ array(
156
+ 'header' => Mage::helper('catalog')->__('Action'),
157
+ 'width' => '50px',
158
+ 'type' => 'action',
159
+ 'getter' => 'getId',
160
+ 'actions' => array(
161
+ array(
162
+ 'caption' => Mage::helper('catalog')->__('Edit'),
163
+ 'url' => array(
164
+ 'base'=>'*/*/edit',
165
+ 'params'=>array('store'=>$this->getRequest()->getParam('store'))
166
+ ),
167
+ 'field' => 'id'
168
+ )
169
+ ),
170
+ 'filter' => false,
171
+ 'sortable' => false,
172
+ 'index' => 'stores',
173
+ 'is_system' => true,
174
+ ));
175
+ $this->addExportType('*/*/exportCsv', Mage::helper('sales')->__('CSV'));
176
+
177
+ return parent::_prepareColumns();
178
+ }
179
+
180
+ protected function _prepareMassaction()
181
+ {
182
+ $this->setMassactionIdField('redirection_id');
183
+ $this->getMassactionBlock()->setFormFieldName('redirection_id'); //<<??
184
+
185
+ $this->getMassactionBlock()->addItem('delete', array(
186
+ 'label'=> Mage::helper('catalog')->__('Delete'),
187
+ 'url' => $this->getUrl('*/*/massDelete'),
188
+ 'confirm' => Mage::helper('catalog')->__('Are you sure?')
189
+ ));
190
+
191
+ Mage::dispatchEvent('adminhtml_catalog_product_grid_prepare_massaction', array('block' => $this));
192
+ return $this;
193
+ }
194
+
195
+ public function getGridUrl()
196
+ {
197
+ return $this->getUrl('*/*/grid', array('_current'=>true));
198
+ }
199
+
200
+ public function getRowUrl($row)
201
+ {
202
+ return $this->getUrl('*/*/edit', array(
203
+ 'store'=>$this->getRequest()->getParam('store'),
204
+ 'id'=>$row->getId())
205
+ );
206
+ }
207
+
208
+ /**
209
+ * Write item data to csv export file
210
+ *
211
+ * @param Varien_Object $item
212
+ * @param Varien_Io_File $adapter
213
+ */
214
+ protected function _exportCsvItem(Varien_Object $item, Varien_Io_File $adapter)
215
+ {
216
+ $row = array();
217
+ /* @var $column Mage_Adminhtml_Block_Widget_Grid_Column:: */
218
+ foreach ($this->_columns as $column) {
219
+ if (!$column->getIsSystem()) {
220
+ $row[] = $column->getRowFieldExport($item);
221
+ }
222
+ }
223
+ $adapter->streamWriteCsv($row);
224
+ }
225
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage/Grid/Renderer/Options.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Block_Adminhtml_Manage_Grid_Renderer_Options extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Options {
3
+
4
+ /**
5
+ * Render column for export
6
+ *
7
+ * @param Varien_Object $row
8
+ * @return string
9
+ */
10
+ public function renderExport(Varien_Object $row)
11
+ {
12
+ return $row->getData($this->getColumn()->getIndex());
13
+ }
14
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage/Grid/Renderer/Url.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Block_Adminhtml_Manage_Grid_Renderer_Url extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Text {
3
+
4
+ /**
5
+ * Render column for export
6
+ *
7
+ * @param Varien_Object $row
8
+ * @return string
9
+ */
10
+ public function renderExport(Varien_Object $row)
11
+ {
12
+ return
13
+ preg_replace('/\/$/','',Mage::app()->getStore($row->getStoreId())->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, false))
14
+ .'/'.
15
+ preg_replace('/^\//','',$row->getData($this->getColumn()->getIndex()));
16
+ }
17
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Manage/Report.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Block_Adminhtml_Manage_Report extends Mage_Adminhtml_Block_Template{
3
+
4
+ public function __construct()
5
+ {
6
+ parent::__construct();
7
+ $this->setTemplate('zero1/seoredirects/manage/report.phtml');
8
+ }
9
+
10
+ public function getLicenseCounts(){
11
+ /* @var $redirection Zero1_Seoredirects_Model_Redirection */
12
+ $redirection = Mage::getModel('zero1_seo_redirects/redirection');
13
+ $resource = $redirection->getResource();
14
+ $con = $resource->getReadConnection();
15
+
16
+ $select = $con->select();
17
+ $select->from('core_store as store_table', array(
18
+ 'store_table.store_id',
19
+ 'store_table.name',
20
+ new Zend_Db_Expr('IF(store_table.store_id = 0,
21
+ (SELECT
22
+ COUNT(*)
23
+ FROM
24
+ zero1_seoredirects_redirection
25
+ where
26
+ status = 1),
27
+ (SELECT
28
+ COUNT(*)
29
+ FROM
30
+ zero1_seoredirects_redirection
31
+ where
32
+ store_id = store_table.store_id and status = 1)) as count')));
33
+
34
+ return $res = $con->fetchAssoc($select);
35
+ }
36
+
37
+ public function getLicenseLimit(){
38
+ return Mage::helper('zero1_seo_redirects/license')->getLicenceLimit();
39
+ }
40
+
41
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/Settings/Params.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Block_Adminhtml_Settings_Params
3
+ extends Mage_Adminhtml_Block_System_Config_Form_Field
4
+ {
5
+ protected $_addRowButtonHtml = array();
6
+ protected $_removeRowButtonHtml = array();
7
+
8
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
9
+ {
10
+ $this->setElement($element);
11
+
12
+ $html = '<div id="params_template" style="display:none">';
13
+ $html .= $this->_getRowTemplateHtml();
14
+ $html .= '</div>';
15
+
16
+ $html .= '<ul id="params_container">';
17
+ if ($this->_getValue('params')) {
18
+ foreach ($this->_getValue('params') as $i => $f) {
19
+ if ($i) {
20
+ $html .= $this->_getRowTemplateHtml($i);
21
+ }
22
+ }
23
+ }
24
+ $html .= '</ul>';
25
+
26
+ $html .= $this->_getAddRowButtonHtml('params_container', 'params_template', $this->__('Add Query Variable'));
27
+
28
+ return $html;
29
+ }
30
+
31
+ protected function _getRowTemplateHtml($rowIndex = 0)
32
+ {
33
+ $html = '<li>';
34
+ $html .= '<div style="margin:5px 0 10px;">';
35
+ $html .= '<input class="input-text" style="width:200px;" name="'
36
+ . $this->getElement()->getName() . '[params][]" value="'
37
+ . $this->_getValue('params/' . $rowIndex) . '" ' . $this->_getDisabled() . '/> ';
38
+
39
+ $html .= $this->_getRemoveRowButtonHtml();
40
+ $html .= '</div>';
41
+ $html .= '</li>';
42
+
43
+ return $html;
44
+ }
45
+
46
+ protected function _getDisabled()
47
+ {
48
+ return $this->getElement()->getDisabled() ? ' disabled' : '';
49
+ }
50
+
51
+ protected function _getValue($key)
52
+ {
53
+ return $this->getElement()->getData('value/' . $key);
54
+ }
55
+
56
+ protected function _getSelected($key, $value)
57
+ {
58
+ return $this->getElement()->getData('value/' . $key) == $value ? 'selected="selected"' : '';
59
+ }
60
+
61
+ protected function _getAddRowButtonHtml($container, $template, $title='Add')
62
+ {
63
+ if (!isset($this->_addRowButtonHtml[$container])) {
64
+ $this->_addRowButtonHtml[$container] = $this->getLayout()->createBlock('adminhtml/widget_button')
65
+ ->setType('button')
66
+ ->setClass('add ')
67
+ ->setLabel($this->__($title))
68
+ ->setOnClick("Element.insert($('" . $container . "'), {bottom: $('" . $template . "').innerHTML})")
69
+ ->setDisabled($this->_getDisabled())
70
+ ->toHtml();
71
+ }
72
+ return $this->_addRowButtonHtml[$container];
73
+ }
74
+
75
+ protected function _getRemoveRowButtonHtml($selector = 'li', $title = 'Remove')
76
+ {
77
+ if (!$this->_removeRowButtonHtml) {
78
+ $this->_removeRowButtonHtml = $this->getLayout()->createBlock('adminhtml/widget_button')
79
+ ->setType('button')
80
+ ->setClass('delete v-middle ')
81
+ ->setLabel($this->__($title))
82
+ ->setOnClick("Element.remove($(this).up('" . $selector . "'))")
83
+ ->setDisabled($this->_getDisabled())
84
+ ->toHtml();
85
+ }
86
+ return $this->_removeRowButtonHtml;
87
+ }
88
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/System/Config/Form.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * System config form block
5
+ *
6
+ * @category Mage
7
+ * @package Mage_Adminhtml
8
+ * @author Magento Core Team <core@magentocommerce.com>
9
+ */
10
+ class Zero1_Seoredirects_Block_Adminhtml_System_Config_Form extends Mage_Adminhtml_Block_System_Config_Form
11
+ {
12
+ /**
13
+ * Enter description here...
14
+ *
15
+ * @return array
16
+ */
17
+ protected function _getAdditionalElementTypes()
18
+ {
19
+ $array = parent::_getAdditionalElementTypes();
20
+ $array['zero1_seo_redirects_file'] = Mage::getConfig()->getBlockClassName('zero1_seo_redirects/adminhtml_system_config_form_field_file');
21
+ return $array;
22
+ }
23
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/System/Config/Form/Field.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ /**
29
+ * Abstract config form element renderer
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Adminhtml
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Zero1_Seoredirects_Block_Adminhtml_System_Config_Form_Field
36
+ extends Mage_Adminhtml_Block_System_Config_Form_Field
37
+ implements Varien_Data_Form_Element_Renderer_Interface
38
+ {
39
+
40
+ /**
41
+ * Enter description here...
42
+ *
43
+ * @param Varien_Data_Form_Element_Abstract $element
44
+ * @return string
45
+ */
46
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
47
+ {
48
+ return parent::_getElementHtml($element);
49
+ }
50
+
51
+ public function render(Varien_Data_Form_Element_Abstract $element)
52
+ {
53
+ $id = $element->getHtmlId();
54
+
55
+ $html = '<td class="label"><label for="'.$id.'">'.$element->getLabel().'</label></td>';
56
+
57
+ //$isDefault = !$this->getRequest()->getParam('website') && !$this->getRequest()->getParam('store');
58
+ $isMultiple = $element->getExtType()==='multiple';
59
+
60
+ // replace [value] with [inherit]
61
+ $namePrefix = preg_replace('#\[value\](\[\])?$#', '', $element->getName());
62
+
63
+ $options = $element->getValues();
64
+
65
+ if ($element->getTooltip()) {
66
+ $html .= '<td class="value with-tooltip">';
67
+ $html .= $this->_getElementHtml($element);
68
+ $html .= '<div class="field-tooltip"><div>' . $element->getTooltip() . '</div></div>';
69
+ } else {
70
+ $html .= '<td class="value">';
71
+ $html .= $this->_getElementHtml($element);
72
+ };
73
+ if ($element->getComment()) {
74
+ $html.= '<p class="note"><span>'.$element->getComment().'</span></p>';
75
+ }
76
+ $html.= '</td>';
77
+
78
+ $html.= '<td class="scope-label">';
79
+ if ($element->getScope()) {
80
+ $html .= $element->getScopeLabel();
81
+ }
82
+ $html.= '</td>';
83
+
84
+ $html.= '<td class="">';
85
+ if ($element->getHint()) {
86
+ $html.= '<div class="hint" >';
87
+ $html.= '<div style="display: none;">' . $element->getHint() . '</div>';
88
+ $html.= '</div>';
89
+ }
90
+ $html.= '</td>';
91
+
92
+ return $this->_decorateRowHtml($element, $html);
93
+ }
94
+ }
app/code/community/Zero1/Seoredirects/Block/Adminhtml/System/Config/Form/Field/File.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ /**
29
+ * File config field renderer
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Adminhtml
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Zero1_Seoredirects_Block_Adminhtml_System_Config_Form_Field_File extends Varien_Data_Form_Element_File
36
+ {
37
+ /* @var $file Zero1_Seoredirects_Model_File */
38
+ private $file;
39
+ /**
40
+ * Get element html
41
+ *
42
+ * @return string
43
+ */
44
+ public function getElementHtml()
45
+ {
46
+ $website = Mage::app()->getRequest()->getParam('website', null);
47
+ if($website !== null){
48
+ $website = Mage::app()->getWebsite($website)->getId();
49
+ }
50
+ $store = Mage::app()->getRequest()->getParam('store', null);
51
+ if($store !== null){
52
+ $store = Mage::app()->getstore($store)->getId();
53
+ }
54
+ $this->file = Mage::helper('zero1_seo_redirects/files')->getFile($store, $website);
55
+
56
+
57
+ if($this->file->getFileName() !== null){
58
+ $html = $this->getFileLinkHTML();
59
+ }else{
60
+ $html = $this->getTemplateFileLinkHTML();
61
+ }
62
+ $html .= $this->getNewFileHTML();
63
+ $html .= $this->getButtonsHTML();
64
+
65
+ $this->setData('onchange', 'update'.$this->getHtmlId().'value(this.value)');
66
+ $this->setData('style', 'display: none;');
67
+
68
+ $html .= parent::getElementHtml();
69
+ $html .='<script>
70
+ function update'.$this->getHtmlId().'value(value){
71
+ document.getElementById(\''.$this->getHtmlId().'_new_file_label\').innerHTML = \'New File: \'+value;
72
+ document.getElementById(\''.$this->getHtmlId().'_new_file_container\').style.display = \'block\';
73
+ document.getElementById(\''.$this->getHtmlId().'_delete\').disabled = \'disabled\';
74
+ document.getElementById(\''.$this->getHtmlId().'_change_button\').disabled = \'disabled\';
75
+ }
76
+ function '.$this->getHtmlId().'delete_onchange(element){
77
+ if(element.checked){
78
+ document.getElementById(\''.$this->getHtmlId().'_change_button\').disabled = \'disabled\';
79
+ }else{
80
+ document.getElementById(\''.$this->getHtmlId().'_change_button\').removeAttribute(\'disabled\');
81
+ }
82
+ }
83
+ </script>';
84
+ return $html;
85
+ }
86
+
87
+ protected function getButtonsHTML(){
88
+ $html = '<div>';
89
+ $html .= $this->getChangeButtonHTML();
90
+ if($this->file->getFileName() !== null){
91
+ $html .= $this->getDeleteCheckboxHTML();
92
+ }
93
+ $html .= '<div style="clear: both;"></div>';
94
+ $html .= '</div>';
95
+ return $html;
96
+ }
97
+
98
+ protected function getDeleteCheckboxHTML()
99
+ {
100
+ $html = '';
101
+ $label = Mage::helper('adminhtml')->__('Delete File');
102
+ $html .= '<div style="display: inline-block; float: right; margin-right: 30px;">';
103
+ $html .= '<input type="checkbox" name="'.parent::getName().'[delete]" value="1" class="checkbox" id="'.$this->getHtmlId().'_delete" onchange="'.$this->getHtmlId().'delete_onchange(this);"/>';
104
+ $html .= '<label for="'.$this->getHtmlId().'_delete"'.'> '.$label.'</label>';
105
+ $html .= '</div>';
106
+ return $html;
107
+ }
108
+
109
+ protected function getChangeButtonHTML(){
110
+ if($this->file->getFileName() != null){
111
+ $changeButtonText = 'Change File...';
112
+ }else{
113
+ $changeButtonText = 'Add File...';
114
+ }
115
+ $html = '<input type="button" id="'.$this->getHtmlId().'_change_button" value="'.$changeButtonText.'" onclick="document.getElementById(\''.$this->getHtmlId().'\').click();" />';
116
+ return $html;
117
+ }
118
+
119
+ protected function getNewFileHTML(){
120
+ $html = '<div id="'.$this->getHtmlId().'_new_file_container" style="display:none;">';
121
+ $html .= '<div id="'.$this->getHtmlId().'_new_file_label">New File: </div>';
122
+ $html .= '</div>';
123
+ return $html;
124
+ }
125
+
126
+ protected function getFileLinkHTML(){
127
+ return 'Current File: <a href="'.$this->file->getExternalPath().'">'.$this->file->getFileName().'</a><br />';
128
+ }
129
+
130
+ protected function getTemplateFileLinkHTML(){
131
+ /* @var $templateFile Zero1_Seoredirects_Model_File */
132
+ $templateFile = Mage::helper('zero1_seo_redirects/files')->getTemplateFile();
133
+ return 'No File Set: <a href="'.$templateFile->getExternalPath().'">'.$templateFile->getFileName().'</a><br />';
134
+ }
135
+ }
app/code/community/Zero1/Seoredirects/Block/Manage.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
- class Zero1_Seoredirects_Block_Manage extends Mage_Adminhtml_Block_Widget_Grid_Container
3
- {
4
- protected $_controller = 'seoredirects';
5
-
6
- public function __construct()
7
- {
8
- $this->_controller = 'manage';
9
- $this->_blockGroup = 'seoredirects';
10
-
11
- $this->_headerText = Mage::helper('seoredirects')->__('SEO Redirection Management');
12
- $this->_addButton('refresh', array(
13
- 'label' => $this->__('Refresh URLs'),
14
- 'onclick' => "setLocation('{$this->getUrl('*/*/update')}')",
15
- 'class' => 'refresh'
16
- ));
17
-
18
- parent::__construct();
19
- $this->_removeButton('add');
20
- }
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Zero1/Seoredirects/Block/Manage/Grid.php DELETED
@@ -1,61 +0,0 @@
1
- <?php
2
- class Zero1_Seoredirects_Block_Manage_Grid extends Mage_Adminhtml_Block_Widget_Grid
3
- {
4
- public function __construct()
5
- {
6
- parent::__construct();
7
- $this->setId('manageGrid');
8
- $this->setDefaultSort('entity_id');
9
- }
10
-
11
- protected function _getStore()
12
- {
13
- $storeId = (int)$this->getRequest()->getParam('store', 0);
14
- return Mage::app()->getStore($storeId);
15
- }
16
-
17
- protected function _prepareCollection()
18
- {
19
- $store = $this->_getStore();
20
-
21
- $collection = Mage::getModel('seoredirects/redirection')->getCollection();
22
-
23
- if($store->getId())
24
- {
25
- $collection->addFieldToFilter('store', $store->getId());
26
- }
27
-
28
- $this->setCollection($collection);
29
-
30
- return parent::_prepareCollection();
31
- }
32
-
33
- protected function _prepareColumns()
34
- {
35
- $this->addColumn('entity_id', array(
36
- 'header' => Mage::helper('catalog')->__('ID'),
37
- 'sortable' => true,
38
- 'width' => '60',
39
- 'index' => 'entity_id'
40
- ));
41
-
42
- $this->addColumn('redirect_from', array(
43
- 'header' => Mage::helper('catalog')->__('From'),
44
- 'index' => 'redirect_from'
45
- ));
46
-
47
- $this->addColumn('redirect_to', array(
48
- 'header' => Mage::helper('catalog')->__('To'),
49
- 'index' => 'redirect_to'
50
- ));
51
-
52
- $this->addColumn('store', array(
53
- 'header' => Mage::helper('newsletter')->__('Store'),
54
- 'index' => 'store',
55
- 'type' => 'options',
56
- 'options' => Mage::getModel('adminhtml/system_store')->getStoreOptionHash()
57
- ));
58
-
59
- return parent::_prepareColumns();
60
- }
61
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Zero1/Seoredirects/Exception.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Exception extends Exception//Mage_Core_Exception
3
+ {
4
+ protected $_messages = array();
5
+
6
+ public function getErrorsAsString($seperator = '<br />'){
7
+ return implode($seperator, $this->_messages);
8
+ }
9
+ // overiding superclass method cos not needed
10
+ public function addMessage($msg = ''){
11
+ $this->_messages[] = $msg;
12
+ }
13
+
14
+ public function getMessages(){
15
+ return $this->_messages;
16
+ }
17
+
18
+ }
app/code/community/Zero1/Seoredirects/Helper/Data.php CHANGED
@@ -1,5 +1,243 @@
1
  <?php
2
  class Zero1_Seoredirects_Helper_Data extends Mage_Core_Helper_Abstract
3
  {
4
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  }
1
  <?php
2
  class Zero1_Seoredirects_Helper_Data extends Mage_Core_Helper_Abstract
3
  {
4
+ const INGNOREABLES_CONFIG_PATH = 'seoredirects/redirection_settings/params';
5
+ const ENABLED_CONFIG_PATH = 'seoredirects/settings/enabled';
6
+ const USE_LOCAL_FILE_CONFIG_PATH = 'seoredirects/settings/use_local_file';
7
+ const LOCAL_FILE_NAME_CONFIG_PATH = 'seoredirects/settings/local_file';
8
+ const GOOGLE_DOC_URL_CONFIG_PATH = 'seoredirects/settings/url';
9
+ const USE_GOOGLE_DOC_CONFIG_PATH = 'seoredirects/settings/use_google_docs';
10
+ const LOG_404S_CONFIG_PATH = 'seoredirects/advanced_settings/log_404s';
11
+ const LOG_404S_LIMIT_CONFIG_PATH = 'seoredirects/advanced_settings/log_404s_limit';
12
+ const ENABLED_DEBUG_CONFIG_PATH = 'seoredirects/debug_settings/enable_debug';
13
+ const DEBUG_IPS_CONFIG_PATH = 'seoredirects/debug_settings/debug_ips';
14
+
15
+ const CONFIG_PATH_IMPORT_LOG_LEVEL = 'seoredirects/advanced_settings/import_log_level';
16
+
17
+ public function getStoreUrls(){
18
+ $stores = array();
19
+ $s = Mage::app()->getStores();
20
+ foreach($s as $id => $store){
21
+ /* @var $store Mage_Core_Model_Store */
22
+ $stores[$store->getId()] = $store->getBaseUrl();
23
+ }
24
+ return $stores;
25
+ }
26
+
27
+ public function getFromTypes(){
28
+ return array(
29
+ Zero1_Seoredirects_Model_Redirection::FROM_TYPE_OPEN_ENDED_QUERY_VALUE => Zero1_Seoredirects_Model_Redirection::FROM_TYPE_OPEN_ENDED_QUERY_LABEL,
30
+ Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_VALUE => Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_LABEL,
31
+ );
32
+ }
33
+
34
+ public function getStatuses(){
35
+ return array(
36
+ Zero1_Seoredirects_Model_Redirection::REDIRECTION_STATUS_DISABLED_VALUE => Zero1_Seoredirects_Model_Redirection::REDIRECTION_STATUS_DISABLED_LABEL,
37
+ Zero1_Seoredirects_Model_Redirection::REDIRECTION_STATUS_ENABLED_VALUE => Zero1_Seoredirects_Model_Redirection::REDIRECTION_STATUS_ENABLED_LABEL,
38
+ );
39
+ }
40
+
41
+ public function getSources(){
42
+ return array(
43
+ Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_IMPORT_VALUE => Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_IMPORT_LABEL,
44
+ Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_LOGGED_VALUE => Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_LOGGED_LABEL,
45
+ Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_MANUAL_VALUE => Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_MANUAL_LABEL,
46
+ );
47
+ }
48
+
49
+ public function getIsLog404Enabled($storeId = null){
50
+ return (bool)Mage::getStoreConfig(self::LOG_404S_CONFIG_PATH, $storeId);
51
+ }
52
+
53
+ public function getIsDebugEnabled($storeId = null){
54
+ return (bool)Mage::getStoreConfig(self::ENABLED_DEBUG_CONFIG_PATH, $storeId);
55
+ }
56
+
57
+ public function getDebugIps($storeId = null){
58
+ $ips = Mage::getStoreConfig(self::DEBUG_IPS_CONFIG_PATH, $storeId);
59
+ if(!$ips){
60
+ $ips = array();
61
+ }else{
62
+ $ips = explode(',', $ips);
63
+ }
64
+ return $ips;
65
+ }
66
+
67
+ public function canDebug($store = null, $ip = null){
68
+ if(!$this->getIsDebugEnabled($store)){
69
+ return false;
70
+ }
71
+ if(!$ip){
72
+ $ip = Mage::app()->getRequest()->getClientIp();
73
+ }
74
+ $debugIps = $this->getDebugIps($store);
75
+ if(!empty($debugIps) && array_search($ip, $debugIps) === false){
76
+ return false;
77
+ }
78
+
79
+ return true;
80
+ }
81
+
82
+ public function getLog404Limit($storeId = null){
83
+ return (int)Mage::getStoreConfig(self::LOG_404S_LIMIT_CONFIG_PATH, $storeId);
84
+ }
85
+
86
+ public function stripIgnoreables($storeId = null, $args = array()){
87
+ if(!$storeId){
88
+ $storeId = Mage::app()->getStore()->getId();
89
+ }
90
+
91
+ $ignoreables = Mage::getStoreConfig(self::INGNOREABLES_CONFIG_PATH, $storeId);
92
+ if($ignoreables === null){
93
+ return $args;
94
+ }
95
+
96
+ $ignoreables = unserialize($ignoreables);
97
+ $ignoreables = $ignoreables['params'];
98
+ foreach($ignoreables as $param){
99
+ if(isset($args[$param])){
100
+ unset($args[$param]);
101
+ }
102
+ }
103
+ return $args;
104
+ }
105
+
106
+ public function getIsEnabled($store = null, $website = null){
107
+ if($store !== null){
108
+ return Mage::app()->getStore($store)->getConfig(self::ENABLED_CONFIG_PATH);
109
+ }
110
+ return Mage::app()->getWebsite($website)->getConfig(self::ENABLED_CONFIG_PATH);
111
+ }
112
+
113
+ /**
114
+ * @param int
115
+ * @param int
116
+ * @return bool
117
+ */
118
+ public function getHasLocalFile($store = null, $website = null){
119
+
120
+ //first check if enabled at this level
121
+ if($website !== null){
122
+ $localFile = (bool)Mage::app()->getWebsite($website)->getConfig(self::USE_LOCAL_FILE_CONFIG_PATH);
123
+ }else{
124
+ $localFile = (bool)Mage::app()->getStore($store)->getConfig(self::USE_LOCAL_FILE_CONFIG_PATH);
125
+ }
126
+
127
+ if(!$localFile){
128
+ return false;
129
+ }
130
+
131
+ /* @var $fileHelper Zero1_Seoredirects_Helper_Files */
132
+ $fileHelper = Mage::helper('zero1_seo_redirects/files');
133
+ $file = $fileHelper->getFile($store, $website);
134
+
135
+ if($file->getFileName() === null){
136
+ return false;
137
+ }else{
138
+ return true;
139
+ }
140
+ }
141
+
142
+ public function getFileName($store = null, $website = null){
143
+ $params = array();
144
+ if($store !== null){
145
+ $params['scope'] = 'stores';
146
+ $params['scope_id'] = $store;
147
+ }elseif($website !== null){
148
+ $params['scope'] = 'websites';
149
+ $params['scope_id'] = $website;
150
+ }else{
151
+ $params['scope'] = 'default';
152
+ $params['scope_id'] = 0;
153
+ }
154
+ $params['path'] = self::LOCAL_FILE_NAME_CONFIG_PATH;
155
+ $config = $this->_getConfig($params);
156
+ if(empty($config)){
157
+ return false;
158
+ }else{
159
+ return $config[0]['value'];
160
+ }
161
+ }
162
+
163
+ public function getIsGoogleDocEnabled($store = null, $website = null){
164
+ if($website === null){
165
+ $useGoogleDoc = (bool)Mage::app()->getStore($store)->getConfig(self::USE_GOOGLE_DOC_CONFIG_PATH);
166
+ }else{
167
+ $useGoogleDoc = (bool)Mage::app()->getWebsite($website)->getConfig(self::USE_GOOGLE_DOC_CONFIG_PATH);
168
+ }
169
+ return $useGoogleDoc;
170
+ }
171
+
172
+ public function getIsLocalFileEnabled($store = null, $website = null){
173
+ if($website === null){
174
+ $useGoogleDoc = (bool)Mage::app()->getStore($store)->getConfig(self::USE_LOCAL_FILE_CONFIG_PATH);
175
+ }else{
176
+ $useGoogleDoc = (bool)Mage::app()->getWebsite($website)->getConfig(self::USE_LOCAL_FILE_CONFIG_PATH);
177
+ }
178
+ return $useGoogleDoc;
179
+ }
180
+
181
+ public function getHasRemoteFile($store = null, $website = null){
182
+ //first check if enabled at this level
183
+ $useGoogleDoc = $this->getIsGoogleDocEnabled($store, $website);
184
+
185
+ if(!$useGoogleDoc){
186
+ return false;
187
+ }
188
+
189
+ $params = array();
190
+ if($website !== null){
191
+ $params['scope'] = 'websites';
192
+ $params['scope_id'] = $website;
193
+ }else{
194
+ if($store == 0){
195
+ $params['scope'] = 'default';
196
+ $params['scope_id'] = 0;
197
+ }else{
198
+ $params['scope'] = 'stores';
199
+ $params['scope_id'] = $store;
200
+ }
201
+ }
202
+ $params['path'] = self::GOOGLE_DOC_URL_CONFIG_PATH;
203
+ $config = $this->_getConfig($params);
204
+ if(empty($config) || !isset($config[0]['value'])){
205
+ return false;
206
+ }else{
207
+ return true;
208
+ }
209
+ }
210
+
211
+ public function getRemoteFileUrl($store = null, $website = null){
212
+ $url = null;
213
+ if($website !== null){
214
+ $url = Mage::app()->getWebsite($website)->getConfig(self::GOOGLE_DOC_URL_CONFIG_PATH);
215
+ }else{
216
+ $url = Mage::app()->getStore($store)->getConfig(self::GOOGLE_DOC_URL_CONFIG_PATH);
217
+ }
218
+ return $url;
219
+ }
220
+
221
+ protected function _getConfig($params){
222
+ /* @var $configCollection Mage_Core_Model_Resource_Config */
223
+ $configCollection = Mage::getModel('core_resource/config');
224
+ $read = $configCollection->getReadConnection();
225
+
226
+ /* @var $select Varien_Db_Select */
227
+ $select = $read->select()
228
+ ->from($configCollection->getMainTable())
229
+ ->where('path = :path')
230
+ ->where('scope = :scope')
231
+ ->where('scope_id = :scope_id');
232
+
233
+ return $read->fetchAll($select, $params);
234
+ }
235
+
236
+ public function debug($message){
237
+ if(!$this->canDebug()){return;}
238
+ }
239
+
240
+ public function getImportLogLevel($store = null){
241
+ return (int)Mage::getStoreConfig(self::CONFIG_PATH_IMPORT_LOG_LEVEL, $store);
242
+ }
243
  }
app/code/community/Zero1/Seoredirects/Helper/Files.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Helper_Files extends Mage_Core_Helper_Abstract
3
+ {
4
+ const CONFIG_FILE_PATH = 'seoredirects/settings/local_file';
5
+ const CONFIG_SECTION = 'seoredirects';
6
+
7
+ protected function getFilePathPrefix($getTemplatePath = false){
8
+ $path = 'var'.DS.'Zero1'.DS.'SeoRedirects'.DS;
9
+ if(!$getTemplatePath){
10
+ $path .= 'data'.DS;
11
+ }
12
+ return $path;
13
+ }
14
+
15
+ public function getRelativeImportPath($store = null, $website = null){
16
+ $path = $this->getFilePathPrefix();
17
+
18
+ if($store != null){
19
+ $store = Mage::app()->getStore($store);
20
+ $path .= $store->getWebsite()->getCode().DS;
21
+ $path .= $store->getCode().DS;
22
+ }elseif($website != null){
23
+ $path .= Mage::app()->getWebsite($website)->getCode().DS;
24
+ }
25
+
26
+ return $path;
27
+ }
28
+
29
+ public function getUrlPathToFile($path = null, $name= null){
30
+ return Mage::helper('adminhtml')->getUrl('adminhtml/seoredirects_config/index', array('_query' => array('path'=>urlencode($path), 'name'=>urlencode($name))));
31
+ }
32
+
33
+ /**
34
+ * @param int
35
+ * @param int
36
+ * @return Zero1_Seoredirects_Model_File
37
+ */
38
+ public function getFile($store = null, $website = null){
39
+ /* @var $file Zero1_Seoredirects_Model_File */
40
+ $file = Mage::getModel('zero1_seo_redirects/file');
41
+ $fileName = Mage::helper('zero1_seo_redirects')->getFileName($store, $website);
42
+ if(!$fileName){
43
+ return $file;
44
+ }
45
+ $internalPath = Mage::getBaseDir('base').DS.$this->getRelativeImportPath($store, $website).$fileName;
46
+ if(file_exists($internalPath)){
47
+ $file->setFileName($fileName);
48
+ $file->setExternalPath($this->getUrlPathToFile($internalPath, $fileName));
49
+ $file->setInternalPath($internalPath);
50
+ }else{
51
+ //do this as someone has deleted the file
52
+ //TODO move this into helper
53
+ $this->_removeConfigOption($website, $store);
54
+ }
55
+
56
+ return $file;
57
+ }
58
+
59
+ public function getTemplateFile(){
60
+ /* @var $file Zero1_Seoredirects_Model_File */
61
+ $file = Mage::getModel('zero1_seo_redirects/file');
62
+ $file->setFileName('template.csv');
63
+ $internalPath = Mage::getBaseDir('base').DS.$this->getRelativeImportPath().$file->getFileName();
64
+ $file->setExternalPath($this->getUrlPathToFile($internalPath, $file->getFileName()));
65
+ $file->setInternalPath($internalPath);
66
+ return $file;
67
+ }
68
+
69
+ protected function _removeConfigOption($website = null, $store = null){
70
+
71
+ if ($store) {
72
+ $scope = 'stores';
73
+ $scopeId = (int)Mage::getConfig()->getNode('stores/' . $store . '/system/store/id');
74
+ } elseif ($website) {
75
+ $scope = 'websites';
76
+ $scopeId = (int)Mage::getConfig()->getNode('websites/' . $website . '/system/website/id');
77
+ } else {
78
+ $scope = 'default';
79
+ $scopeId = 0;
80
+ }
81
+
82
+ /* @var $configData Mage_Core_Model_Resource_Config_Data_Collection */
83
+ $configData = Mage::getModel('core/config_data')
84
+ ->getCollection()
85
+ ->addFieldToFilter('scope', $scope)
86
+ ->addFieldToFilter('scope_id', $scopeId)
87
+ ->addFieldToFilter('path', array('like' => self::CONFIG_FILE_PATH));
88
+
89
+ if($configData->count() > 0){
90
+ $configData->getFirstItem()->delete();
91
+ }
92
+ return;
93
+ }
94
+ }
app/code/community/Zero1/Seoredirects/Helper/Hints.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Helper_Hints extends Mage_Core_Helper_Abstract
3
+ {
4
+ //TODO: sort out correct url
5
+ public function getFromTypeHintHtml(){
6
+ $html = '<a'
7
+ . ' href="'. $this->escapeUrl('http://www.google.co.uk') . '"'
8
+ . ' onclick="this.target=\'_blank\'"'
9
+ . ' title="' . $this->__('What is this?') . '"'
10
+ . ' class="link-store-scope">'
11
+ . $this->__('What is this?')
12
+ . '</a>';
13
+ return $html;
14
+ }
15
+
16
+ //TODO: sort out correct url
17
+ public function getToTypeHintHtml(){
18
+ $html = '<a'
19
+ . ' href="'. $this->escapeUrl('http://www.google.co.uk') . '"'
20
+ . ' onclick="this.target=\'_blank\'"'
21
+ . ' title="' . $this->__('What is this?') . '"'
22
+ . ' class="link-store-scope">'
23
+ . $this->__('What is this?')
24
+ . '</a>';
25
+ return $html;
26
+ }
27
+ }
app/code/community/Zero1/Seoredirects/Helper/License.php CHANGED
@@ -3,6 +3,9 @@ class Zero1_Seoredirects_Helper_License extends Mage_Core_Helper_Abstract
3
  {
4
  private $_license_required_for_community = true;
5
  private $_license_required_for_enterprise = true;
 
 
 
6
 
7
  public function isEnterprise()
8
  {
@@ -22,10 +25,10 @@ class Zero1_Seoredirects_Helper_License extends Mage_Core_Helper_Abstract
22
  return false;
23
  }
24
 
25
- public function isValid($store = null)
26
  {
27
- $data = $this->getData($store);
28
-
29
  if($this->isEnterprise())
30
  {
31
  if($this->_license_required_for_enterprise && !isset($data['enterprise']))
@@ -38,9 +41,9 @@ class Zero1_Seoredirects_Helper_License extends Mage_Core_Helper_Abstract
38
  return true;
39
  }
40
 
41
- public function getData($store = null)
42
  {
43
- $store = ($store === null) ? Mage::app()->getStore() : $store;
44
 
45
  $data = array();
46
  $module_name = preg_replace('/^Zero1_([^_]*)_Helper_License$/si', '$1', get_class($this));
@@ -70,4 +73,22 @@ class Zero1_Seoredirects_Helper_License extends Mage_Core_Helper_Abstract
70
 
71
  return 'http://www.zero1.co.uk/licence/index.php?'.http_build_query($params);
72
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
3
  {
4
  private $_license_required_for_community = true;
5
  private $_license_required_for_enterprise = true;
6
+ protected $_licenceLimit = null;
7
+
8
+ const DEFAULT_LIMIT = 50;
9
 
10
  public function isEnterprise()
11
  {
25
  return false;
26
  }
27
 
28
+ public function isValid()
29
  {
30
+ $data = $this->getData();
31
+
32
  if($this->isEnterprise())
33
  {
34
  if($this->_license_required_for_enterprise && !isset($data['enterprise']))
41
  return true;
42
  }
43
 
44
+ public function getData()
45
  {
46
+ $store = Mage::app()->getStore(0);
47
 
48
  $data = array();
49
  $module_name = preg_replace('/^Zero1_([^_]*)_Helper_License$/si', '$1', get_class($this));
73
 
74
  return 'http://www.zero1.co.uk/licence/index.php?'.http_build_query($params);
75
  }
76
+
77
+ public function getLicenceLimit()
78
+ {
79
+ if(isset($this->_licenceLimit)) {
80
+ $this->_licenceLimit;
81
+ }
82
+
83
+ $this->_licenceLimit = self::DEFAULT_LIMIT;
84
+ if($this->isValid()) {
85
+ $license_data = $this->getData();
86
+
87
+ if(isset($license_data['limit'])) {
88
+ $this->_licenceLimit = $license_data['limit'];
89
+ }
90
+ }
91
+
92
+ return $this->_licenceLimit;
93
+ }
94
  }
app/code/community/Zero1/Seoredirects/Helper/Urls.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Helper_Urls extends Mage_Core_Helper_Abstract
3
+ {
4
+ /**
5
+ * Parses url and orders query string
6
+ * @param string $url
7
+ * @param $storeId
8
+ * @return array
9
+ */
10
+ public function parseUrl($url = '', $storeId = null){
11
+ $this->_getHelper()->debug('parseUrl');
12
+ $parsed = parse_url($url);
13
+
14
+ //sort out issue where BASE PATH is domain.com/a/b
15
+ $this->stripHostFromPath($parsed, $storeId);
16
+
17
+ if(!isset($parsed['query'])){
18
+ return $parsed;
19
+ }
20
+ //sort alphabetically
21
+ $q = explode('&', $parsed['query']);
22
+ $args = array();
23
+ foreach($q as $kvPair){
24
+ list($k, $v) = explode('=', $kvPair);
25
+ $args[$k] = $v;
26
+ }
27
+ ksort($args);
28
+
29
+ //strip ignoreables
30
+ $stripped = $this->_getHelper()->stripIgnoreables($storeId, $args);
31
+
32
+ if(empty($stripped)){
33
+ unset($parsed['query']);
34
+ }else{
35
+ $parsed['query'] = http_build_query($stripped);
36
+ }
37
+
38
+ return $parsed;
39
+ }
40
+
41
+ protected function stripHostFromPath(&$parsed, $storeId = null){
42
+ $baseUrl = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
43
+ if(!isset($parsed['host'])){ return; }
44
+
45
+ //remove protocol
46
+ $pos = strpos($baseUrl, $parsed['host']);
47
+ if($pos !== false){
48
+ $baseUrl = substr($baseUrl, $pos);
49
+ }
50
+
51
+ $stringLengthDifference = (strlen($baseUrl) - strlen($parsed['host']));
52
+ if($stringLengthDifference > 0){
53
+ $extraPartOfHost = substr($baseUrl, (strlen($baseUrl) - $stringLengthDifference));
54
+ if(strpos($parsed['path'], $extraPartOfHost) === 0){
55
+ $parsed['host'] = $baseUrl;
56
+ $parsed['path'] = substr($parsed['path'], $stringLengthDifference);
57
+ }
58
+ }
59
+ $this->_getHelper()->debug('base url: '.$baseUrl.PHP_EOL.'parsed: '.json_encode($parsed));
60
+ }
61
+
62
+ public function getAssocQuery($query){
63
+ $urlParams = array();
64
+ if($query == null || $query == ''){
65
+ return $urlParams;
66
+ }
67
+ if($query[0] == '?'){
68
+ $query = substr($query, 1);
69
+ }
70
+ if(strpos($query, '&') !== false){
71
+ $params = explode('&', $query);
72
+ }else{
73
+ $params = array($query);
74
+ }
75
+ if(empty($params)){
76
+ return $urlParams;
77
+ }
78
+ foreach($params as $pair){
79
+ list($key, $value) = explode('=', $pair);
80
+ $urlParams[$key] = $value;
81
+ }
82
+ return $urlParams;
83
+ }
84
+
85
+ /**
86
+ * @return Zero1_Seoredirects_Helper_Data
87
+ */
88
+ protected function _getHelper(){
89
+ return Mage::helper('zero1_seo_redirects');
90
+ }
91
+ }
app/code/community/Zero1/Seoredirects/Model/Adminhtml/System/Config/Backend/File.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Model_Adminhtml_System_Config_Backend_File extends Mage_Core_Model_Config_Data
3
+ {
4
+ /**
5
+ * Upload max file size in kilobytes
6
+ *
7
+ * @var int
8
+ */
9
+ protected $_maxFileSize = 0;
10
+ protected $uploadPath;
11
+ /**
12
+ * Save uploaded file before saving config value
13
+ *
14
+ * @return Mage_Adminhtml_Model_System_Config_Backend_File
15
+ */
16
+ protected function _beforeSave()
17
+ {
18
+ $this->uploadPath = Mage::helper('zero1_seo_redirects/files')->getRelativeImportPath($this->getStoreCode(), $this->getWebsiteCode());
19
+ $value = $this->getValue();
20
+ if(is_array($value) && isset($value['delete'])){
21
+ $this->deleteFile($this->getOldValue());
22
+ $this->delete();
23
+ }else{
24
+ $this->saveFile();
25
+ }
26
+
27
+ return $this;
28
+ }
29
+
30
+ protected function deleteFile($oldFileName){
31
+ $this->setValue('');
32
+ if($oldFileName != null && file_exists($this->uploadPath.$oldFileName)){
33
+ try{
34
+ unlink($this->uploadPath.$oldFileName);
35
+ }catch(Exception $e){
36
+ Mage::throwException($e->getMessage());
37
+ return $this;
38
+ }
39
+ }
40
+ return $this;
41
+ }
42
+
43
+ protected function saveFile(){
44
+ if ($_FILES['groups']['tmp_name'][$this->getGroupId()]['fields'][$this->getField()]['value']){
45
+ $uploadDir = $this->uploadPath;
46
+ try {
47
+ $file = array();
48
+ $tmpName = $_FILES['groups']['tmp_name'];
49
+ $file['tmp_name'] = $tmpName[$this->getGroupId()]['fields'][$this->getField()]['value'];
50
+ $name = $_FILES['groups']['name'];
51
+ $file['name'] = $name[$this->getGroupId()]['fields'][$this->getField()]['value'];
52
+ $uploader = new Mage_Core_Model_File_Uploader($file);
53
+ $uploader->setAllowedExtensions($this->_getAllowedExtensions());
54
+ //delete the old file before saving the new one
55
+ if(!$uploader->checkAllowedExtension($uploader->getFileExtension())){
56
+ Mage::throwException('File extension ('.$uploader->getFileExtension().') not allowed, .csv only.');
57
+ }else{
58
+ $this->deleteFile($this->getOldValue());
59
+ }
60
+ $uploader->setAllowRenameFiles(false);
61
+ $uploader->addValidateCallback('size', $this, 'validateMaxSize');
62
+ $result = $uploader->save($uploadDir);
63
+
64
+ } catch (Exception $e) {
65
+ Mage::throwException($e->getMessage());
66
+ return $this;
67
+ }
68
+
69
+ $filename = $result['file'];
70
+ if ($filename) {
71
+ $this->setValue($filename);
72
+ }
73
+ }
74
+ return $this;
75
+ }
76
+
77
+ /**
78
+ * Validation callback for checking max file size
79
+ *
80
+ * @param string $filePath Path to temporary uploaded file
81
+ * @throws Mage_Core_Exception
82
+ */
83
+ public function validateMaxSize($filePath)
84
+ {
85
+ if ($this->_maxFileSize > 0 && filesize($filePath) > ($this->_maxFileSize * 1024)) {
86
+ throw Mage::exception('Mage_Core', Mage::helper('adminhtml')->__('Uploaded file is larger than %.2f kilobytes allowed by server', $this->_maxFileSize));
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Getter for allowed extensions of uploaded files
92
+ *
93
+ * @return array
94
+ */
95
+ protected function _getAllowedExtensions()
96
+ {
97
+ return array('csv');
98
+ }
99
+ }
app/code/community/Zero1/Seoredirects/Model/Adminhtml/System/Config/Backend/Number.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ class Zero1_Seoredirects_Model_Adminhtml_System_Config_Backend_Number extends Mage_Core_Model_Config_Data
29
+ {
30
+ protected function _beforeSave()
31
+ {
32
+ $fieldConfig = $this->getFieldConfig();
33
+ $value = $this->getValue();
34
+ if($value == null){
35
+ Mage::getSingleton('core/session')->addNotice($fieldConfig->label.': No input, defaulted to 100.');
36
+ $this->setValue('100');
37
+ }else{
38
+ if(!is_numeric($value)){
39
+ Mage::throwException($fieldConfig->label.': Entry must be numberic.');
40
+ }
41
+ if($value < 0){
42
+ Mage::throwException('Entry must be greater than 0');
43
+ }
44
+ }
45
+ return parent::_beforeSave();
46
+ }
47
+
48
+ protected function _afterSave(){
49
+ $value = $this->getValue();
50
+ if($value == 0){
51
+ Mage::getSingleton('core/session')->addNotice('Now logging all 404\'s requests');
52
+ }
53
+ return parent::_afterSave();
54
+ }
55
+ }
app/code/community/Zero1/Seoredirects/Model/Adminhtml/System/Config/Source/LogLevels.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Model_Adminhtml_System_Config_Source_LogLevels
3
+ {
4
+
5
+ /**
6
+ * Options getter
7
+ * @return array
8
+ */
9
+ public function toOptionArray()
10
+ {
11
+ return array(
12
+ array('value' => Zend_Log::WARN, 'label'=>Mage::helper('adminhtml')->__('Warning')),
13
+ array('value' => Zend_Log::NOTICE, 'label'=>Mage::helper('adminhtml')->__('Notice')),
14
+ array('value' => Zend_Log::INFO, 'label'=>Mage::helper('adminhtml')->__('Info')),
15
+ array('value' => Zend_Log::DEBUG, 'label'=>Mage::helper('adminhtml')->__('Debug')),
16
+ );
17
+ }
18
+
19
+ /**
20
+ * Get options in "key-value" format
21
+ * @return array
22
+ */
23
+ public function toArray()
24
+ {
25
+ return array(
26
+ Zend_Log::WARN => Mage::helper('adminhtml')->__('Warning'),
27
+ Zend_Log::NOTICE => Mage::helper('adminhtml')->__('Notice'),
28
+ Zend_Log::INFO => Mage::helper('adminhtml')->__('Info'),
29
+ Zend_Log::DEBUG => Mage::helper('adminhtml')->__('Debug'),
30
+ );
31
+ }
32
+
33
+ }
app/code/community/Zero1/Seoredirects/Model/File.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Zero1_Seoredirects_Model_File
5
+ *
6
+ * @method String getInternalPath()
7
+ * @method setInternalPath(String $path)
8
+ * @method String getExternalPath()
9
+ * @method setExternalPath(String $path)
10
+ * @method String getFileName()
11
+ * @method setFileName(String $filename)
12
+ *
13
+ */
14
+ class Zero1_Seoredirects_Model_File extends Varien_Object{
15
+ }
app/code/community/Zero1/Seoredirects/Model/Importer.php ADDED
@@ -0,0 +1,604 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Zero1_Seoredirects_Model_Importer
5
+ *
6
+ * @method Mage_Core_Model_Store getStore()
7
+ * @method Mage_Core_Model_Website getWebsite();
8
+ */
9
+ class Zero1_Seoredirects_Model_Importer extends Varien_Object{
10
+
11
+ protected $_log = array();
12
+ protected $_columns = array();
13
+ protected $_lineNumber = 1;
14
+ protected $_allowedUrls = null;
15
+ protected $_model = null;
16
+ protected $_zendHttpClient;
17
+ protected $_usedIds = array();
18
+
19
+ const COLUMN_PARTICIPATION_MANDATORY = 0;
20
+ const COLUMN_PARTICIPATION_OPTIONAL = 1;
21
+ const LOCATION_STORE = 0;
22
+ const LOCATION_WEBSITE = 1;
23
+ const LOCATION_DEFAULT = 2;
24
+
25
+ public function _construct(){
26
+ $this->_log = array();
27
+ $this->_columns = array('from' => array('index' => 0, 'participation' => self::COLUMN_PARTICIPATION_MANDATORY),
28
+ 'to' => array('index' => 1, 'participation' => self::COLUMN_PARTICIPATION_MANDATORY),
29
+ 'type' => array('index' => 2, 'participation' => self::COLUMN_PARTICIPATION_OPTIONAL),
30
+ 'persist_query' => array('index' => 3, 'participation' => self::COLUMN_PARTICIPATION_OPTIONAL),
31
+ );
32
+ }
33
+
34
+ protected function _log($msg = '', $lineNumber = null, $severity = Zend_Log::DEBUG, $force = false){
35
+ if($severity > Mage::helper('zero1_seo_redirects')->getImportLogLevel()&& !$force){
36
+ return $this;
37
+ }
38
+ $log = array(
39
+ 'line_number' => (($lineNumber === null)? $this->_lineNumber : $lineNumber),
40
+ 'message' => $msg,
41
+ 'severity' => $severity
42
+ );
43
+
44
+ switch($this->_getLocation()){
45
+ case self::LOCATION_STORE:
46
+ if(!isset($this->_log[$this->getWebsite()->getCode()])){
47
+ $this->_log[$this->getWebsite()->getCode()] = array();
48
+ $this->_log[$this->getWebsite()->getCode()]['log'] = array();
49
+ $this->_log[$this->getWebsite()->getCode()]['stores'] = array();
50
+ }
51
+ if(!isset($this->_log[$this->getWebsite()->getCode()]['stores'][$this->getStore()->getCode()])){
52
+ $this->_log[$this->getWebsite()->getCode()]['stores'][$this->getStore()->getCode()] = array();
53
+ $this->_log[$this->getWebsite()->getCode()]['stores'][$this->getStore()->getCode()]['log'] = array();
54
+ }
55
+ $this->_log[$this->getWebsite()->getCode()]['stores'][$this->getStore()->getCode()]['log'][] = $log;
56
+ break;
57
+ case self::LOCATION_WEBSITE:
58
+ if(!isset($this->_log[$this->getWebsite()->getCode()])){
59
+ $this->_log[$this->getWebsite()->getCode()] = array();
60
+ $this->_log[$this->getWebsite()->getCode()]['log'] = array();
61
+ $this->_log[$this->getWebsite()->getCode()]['stores'] = array();
62
+ }
63
+ $this->_log[$this->getWebsite()->getCode()]['log'][] = $log;
64
+ break;
65
+ case self::LOCATION_DEFAULT:
66
+ if(!isset($this->_log['default'])){
67
+ $this->_log['default'] = array();
68
+ $this->_log['default']['log'] = array();
69
+ }
70
+ $this->_log['default']['log'][] = $log;
71
+ }
72
+ return $this;
73
+ }
74
+
75
+ protected function _getLocation(){
76
+ if($this->getStore() !== null){
77
+ return self::LOCATION_STORE;
78
+ }
79
+ if($this->getWebsite() !== null){
80
+ return self::LOCATION_WEBSITE;
81
+ }
82
+ return self::LOCATION_DEFAULT;
83
+ }
84
+
85
+ /**
86
+ * @return Zero1_Seoredirects_Helper_Data
87
+ */
88
+ protected function _helper(){
89
+ return Mage::helper('zero1_seo_redirects');
90
+ }
91
+
92
+ /**
93
+ * @param bool $reset
94
+ * @return Zero1_Seoredirects_Model_Redirection
95
+ */
96
+ protected function _getModel($reset = false){
97
+ if($this->_model === null){
98
+ $this->_model = Mage::getModel('zero1_seo_redirects/redirection');
99
+ }
100
+ if($reset){
101
+ $this->_model->setData(array());
102
+ }
103
+ return $this->_model;
104
+ }
105
+
106
+ /**
107
+ * @return Zend_Http_Client
108
+ */
109
+ protected function _getZendClient(){
110
+ if (!$this->_zendHttpClient instanceof Zend_Http_Client) {
111
+ $this->_zendHttpClient = new Zend_Http_Client();
112
+ }
113
+ return $this->_zendHttpClient;
114
+ }
115
+
116
+ public function import($store = null, $website = null){
117
+ //get all ids of redirects type 'import'
118
+ /* @var $website Mage_Core_Model_Website */
119
+ foreach(Mage::app()->getWebsites(false) as $websiteId => $website){
120
+ $this->setWebsite($website);
121
+ $this->checkAndImportEnableds(null, $website->getId());
122
+ /* @var $store Mage_Core_Model_Store */
123
+ foreach($website->getStores(false) as $storeId => $store){
124
+ $this->setStore($store);
125
+ $this->checkAndImportEnableds($store->getId(), null);
126
+
127
+ $this->setStore(null);
128
+ $this->_allowedUrls = null;
129
+ }
130
+ $this->setWebsite(null);
131
+ $this->_allowedUrls = null;
132
+ }
133
+ //do default to finish
134
+ $this->checkAndImportEnableds();
135
+
136
+ //delete now unused urls, and refresh license count
137
+ $this->_clearUrls();
138
+
139
+ return $this->_log;
140
+ }
141
+
142
+ protected function checkAndImportEnableds($storeId = null, $websiteId = null){
143
+ if($this->_helper()->getIsEnabled($storeId, $websiteId)){
144
+ $this->_log('Is Enabled', 'N/A', Zend_Log::INFO, true);
145
+ if($this->_helper()->getIsGoogleDocEnabled($storeId, $websiteId)){
146
+ $this->_log('Google Docs Is Enabled', 'N/A', Zend_Log::INFO, true);
147
+ if($this->_helper()->getHasRemoteFile($storeId, $websiteId)){
148
+ $this->_importRemote($this->_helper()->getRemoteFileUrl($storeId, $websiteId));
149
+ }else{
150
+ $this->_log('No remote file found', 'N/A', Zend_Log::INFO, true);
151
+ }
152
+ }else{
153
+ $this->_log('Google Docs Is Not Enabled', 'N/A', Zend_Log::INFO, true);
154
+ }
155
+
156
+ if($this->_helper()->getIsLocalFileEnabled($storeId, $websiteId)){
157
+ $this->_log('Local File Is Enabled', 'N/A', Zend_Log::INFO, true);
158
+ if($this->_helper()->getHasLocalFile($storeId, $websiteId)){
159
+ $this->_importLocal(Mage::helper('zero1_seo_redirects/files')->getFile($storeId, $websiteId));
160
+ }else{
161
+ $this->_log('Not local file found', 'N/A', Zend_Log::INFO, true);
162
+ }
163
+ }else{
164
+ $this->_log('Local File Is Not Enabled', 'N/A', Zend_Log::INFO, true);
165
+ }
166
+
167
+ }else{
168
+ $this->_log('Not enabled', 'N/A', Zend_Log::INFO, true);
169
+ }
170
+ }
171
+
172
+ /**
173
+ * @param $file Zero1_Seoredirects_Model_File
174
+ */
175
+ protected function _importLocal($file){
176
+ $this->_log('Importing local file: '.$file->getInternalPath(),'N/A', Zend_Log::INFO, true);
177
+ $handle = fopen($file->getInternalPath(), 'r');
178
+ $this->_lineNumber = 0;
179
+
180
+ while(!feof($handle)){
181
+ $line = fgetcsv($handle);
182
+ if($this->_lineNumber == 0){
183
+ if(!$this->_checkHeaders($line)){
184
+ $this->_importRow($line);
185
+ }
186
+ }else{
187
+ $this->_importRow($line);
188
+ }
189
+ $this->_lineNumber++;
190
+ }
191
+ $this->_log('Total number of lines parsed: '.$this->_lineNumber, 'N/A', Zend_Log::INFO, true);
192
+ fclose($handle);
193
+ }
194
+
195
+ protected function _importRemote($url = ''){
196
+ $this->_log('Importing remote file: "'.$url.'"','N/A', Zend_Log::INFO, true);
197
+ preg_match('/output=csv/', $url, $results, PREG_OFFSET_CAPTURE);
198
+ if(!empty($results)){
199
+ return $this->_importRemoteCsv($url);
200
+ }else{
201
+ preg_match('/pubhtml/', $url, $results, PREG_OFFSET_CAPTURE);
202
+ if(!empty($results)){
203
+ return $this->_importRemoteHtml($url);
204
+ }else{
205
+ $this->_log('File type could not be verified, aborting.','N/A', Zend_Log::WARN);
206
+ return;
207
+ }
208
+ }
209
+ }
210
+
211
+ protected function _importRemoteHtml($url){
212
+ $this->_log('Importing remote html: "'.$url.'"','N/A', Zend_Log::INFO, true);
213
+ $content = '';
214
+ try {
215
+ $this->_getZendClient()->setUri($url);
216
+ $content = $this->_getZendClient()->request()->getBody();
217
+ } catch(Exception $e) {
218
+ $this->_log('Failed to retrieve content from remote document "'.$url.'" Error: '.$e->getMessage(), 'N/A', Zend_Log::WARN);
219
+ return;
220
+ }
221
+ if(preg_match('~<!DOCTYPE html>~', $content) != 1){
222
+ $this->_log('Content from remote url, does not appear to html "'.$url.'"', 'N/A', Zend_Log::WARN);
223
+ }
224
+
225
+ $this->_lineNumber = 1;
226
+ $doc = new DOMDocument();
227
+ $doc->loadHTML($content);
228
+ /* @var $tables DOMNodeList */
229
+ $tables = $doc->getElementsByTagName('table');
230
+ $table = $tables->item(0);
231
+
232
+ /* @var $child DOMElement */
233
+ foreach($table->childNodes as $child){
234
+ if($child->nodeName !== 'tbody'){
235
+ continue;
236
+ }else{
237
+ /* @var $row DOMElement */
238
+ /* @var $cell DOMElement */
239
+ foreach($child->childNodes as $row){
240
+ $data = array();
241
+ foreach($row->childNodes as $cell){
242
+ if($cell->nodeName === 'td'){
243
+ $data[] = $cell->textContent;
244
+ }
245
+ }
246
+ if($this->_lineNumber == 1){
247
+ if(!$this->_checkHeaders($data)){
248
+ $this->_importRow($data);
249
+ }
250
+ }else{
251
+ $this->_importRow($data);
252
+ }
253
+ $this->_lineNumber++;
254
+ }
255
+ $this->_log('Total number of lines parsed: '.$this->_lineNumber, 'N/A', Zend_Log::NOTICE, true);
256
+ return;
257
+ }
258
+ }
259
+ }
260
+
261
+ protected function _importRemoteCsv($url){
262
+ $this->_log('Importing remote csv: "'.$url.'"','N/A', Zend_Log::INFO, true);
263
+ try {
264
+ $this->_getZendClient()->setUri($url);
265
+ $content = $this->_getZendClient()->request()->getBody();
266
+ } catch(Exception $e) {
267
+ $this->_log('Failed to retrieve content from remote document "'.$url.'" Error: '.$e->getMessage(), 'N/A', Zend_Log::WARN);
268
+ return;
269
+ }
270
+
271
+ $this->_lineNumber = 1;
272
+ foreach (explode(PHP_EOL, $content) as $line) {
273
+ $data = str_getcsv($line);
274
+ if($this->_lineNumber == 1){
275
+ if(!$this->_checkHeaders($data)){
276
+ $this->_importRow($data);
277
+ }
278
+ }else{
279
+ $this->_importRow($data);
280
+ }
281
+ $this->_lineNumber++;
282
+ }
283
+ $this->_log('Total number of lines parsed: '.$this->_lineNumber, 'N/A', Zend_Log::NOTICE, true);
284
+ return;
285
+ }
286
+
287
+ protected function _checkHeaders($data){
288
+ $from = array_search('from-url', $data);
289
+ $to = array_search('to-url', $data);
290
+ $type = array_search('type', $data);
291
+ $persistQuery = array_search('persist-query', $data);
292
+ if($from === false || $to === false){
293
+ $this->_log('No headers found, for headers to be found, you should at least specify \'from-url\' and \'to-url\' columns. You may also specify \'type\' and \'persist-query\'', null, Zend_Log::WARN);
294
+ if($from === false){
295
+ $this->_columns['from']['index'] = 0;
296
+ }else{
297
+ $this->_columns['from']['index'] = $from;
298
+ }
299
+ if($to === false){
300
+ $this->_columns['to']['index'] = 1;
301
+ }else{
302
+ $this->_columns['to']['index'] = $to;
303
+ }
304
+ return false;
305
+ }
306
+ $this->_columns['from']['index'] = $from;
307
+ $this->_columns['to']['index'] = $to;
308
+ if($type !== false){
309
+ $this->_columns['type']['index'] = $type;
310
+ }
311
+ if($persistQuery !== false){
312
+ $this->_columns['persist_query']['index'] = $persistQuery;
313
+ }
314
+ $this->_log('Headers found ('.json_encode(array_keys($this->_columns)).')', null, Zend_Log::INFO);
315
+ return true;
316
+ }
317
+
318
+ protected function _importRow($data){
319
+ $this->_log('_importRow: '.json_encode($data), null, Zend_Log::DEBUG);
320
+ $from = $this->_getCell('from', $this->_columns['from'], $data);
321
+ $to = $this->_getCell('to', $this->_columns['to'], $data);
322
+ if($from === false || $to === false){ return; }
323
+
324
+ $type = $this->_parseType($this->_getCell('type', $this->_columns['type'], $data));
325
+ $persistQuery = $this->_parsePersistQuery($this->_getCell('persist-query', $this->_columns['persist_query'], $data));
326
+
327
+ $allowedUrls = $this->_getAllowedUrls();
328
+
329
+ //check that there is a match in the allowed urls
330
+ $storeMatched = false;
331
+ $currentMatch = '';
332
+ foreach($allowedUrls as $storeUrl => $data){
333
+ if(strpos($from, $storeUrl) === 0){
334
+ if(strlen($storeUrl) > strlen($currentMatch)){
335
+ $storeMatched = true;
336
+ $currentMatch = $storeUrl;
337
+ }
338
+ }
339
+ }
340
+
341
+ if($storeMatched){
342
+ $storeId = $allowedUrls[$currentMatch]['store_id'];
343
+ }else{
344
+
345
+ if(strpos($from, '://') !== false || $from[0] !== '/'){
346
+ $this->_log('Skipped as from url location did not match any of the allowed stores.', null, Zend_Log::WARN);
347
+ return;
348
+ }
349
+
350
+ $this->_log('Relative path found, prepending both \'from\' and \'to\' with current scope url', null, Zend_Log::NOTICE);
351
+
352
+ switch($this->_getLocation()){
353
+ case self::LOCATION_STORE:
354
+ $storeId = $this->getStore()->getId();
355
+ break;
356
+ case self::LOCATION_WEBSITE:
357
+ $storeId = $this->getWebsite()->getId();
358
+ break;
359
+ default:
360
+ $storeId = 0;
361
+ }
362
+ $from = $this->getBaseUrl().substr($from, 1);
363
+ $to = $this->getBaseUrl().substr($to, 1);
364
+ }
365
+
366
+ $from = Mage::helper('zero1_seo_redirects/urls')->parseUrl($from, $storeId);
367
+ $to = Mage::helper('zero1_seo_redirects/urls')->parseUrl($to, $storeId);
368
+
369
+ if(!isset($from['scheme'], $from['host'], $from['path'], $to['scheme'], $to['host'], $to['path']) ||
370
+ $from['scheme'] != $to['scheme'] || $from['host'] != $to['host']
371
+ ){
372
+ $this->_log('Skipped as to url location did not match the domain as the from url', null, Zend_Log::WARN);
373
+ return;
374
+ }
375
+
376
+ //has this redirect previously been imported?
377
+ /* @var $redirectCollection Zero1_Seoredirects_Model_Resource_Redirection_Collection */
378
+ $redirectCollection = Mage::getModel('zero1_seo_redirects/redirection')->getCollection()
379
+ ->addFieldToFilter('from_url_path', $from['path'])
380
+ ->addFieldToFilter('from_url_query', (isset($from['query'])? $from['query'] : null))
381
+ ->addFieldToFilter('store_id', $storeId);
382
+
383
+ //the redirect has already imported/created so just make sure that it has a IMPORT source
384
+ if($redirectCollection->count()){
385
+ $redirect = $redirectCollection->getFirstItem();
386
+ //check if redirect has already been used.
387
+ if($this->_checkId($redirect->getId()) !== false){
388
+ $redirect = $this->_getModel(true);
389
+ $redirect->setFromUrlPath($from['path'])
390
+ ->setFromUrlQuery((isset($from['query'])? $from['query'] : null))
391
+ ->setStoreId($storeId)
392
+ ->setFromType($type)
393
+ ->setPersistQuery($persistQuery);
394
+ }
395
+ }else{
396
+ //no redirect exists
397
+ $redirect = $this->_getModel(true);
398
+ $redirect->setFromUrlPath($from['path'])
399
+ ->setFromUrlQuery((isset($from['query'])? $from['query'] : null))
400
+ ->setStoreId($storeId)
401
+ ->setFromType($type)
402
+ ->setPersistQuery($persistQuery);
403
+ }
404
+ $redirect->setSource(Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_IMPORT_VALUE)
405
+ ->setToUrl($this->_buildUrl($to));
406
+ try{
407
+ $redirect->save();
408
+ $this->_removeId($redirect->getId());
409
+ }
410
+ catch(Zero1_Seoredirects_Exception $e){
411
+ $messages = $e->getMessages();
412
+ foreach($messages as $err){
413
+ $this->_log($err.' Redirect was not imported.', null, Zend_Log::WARN);
414
+ }
415
+ }
416
+ catch(Exception $e){
417
+ //TODO maybe just throw this?
418
+ $this->_log($e->getMessage(), null, Zend_Log::CRIT);
419
+ }
420
+
421
+ }
422
+
423
+ protected function _getCell($colName, $col, $data){
424
+ if(isset($data[$col['index']])){
425
+ $result = $data[$col['index']];
426
+ }else{
427
+ if($col['participation'] == self::COLUMN_PARTICIPATION_MANDATORY){
428
+ $this->_log('Could not find column "'.$colName.'", skipping this row', null, Zend_Log::WARN);
429
+ }else{
430
+ $this->_log('Could not find column "'.$colName.'"', null, Zend_Log::NOTICE);
431
+ }
432
+ return false;
433
+ }
434
+ if($result == ''){
435
+ if($col['participation'] == self::COLUMN_PARTICIPATION_MANDATORY){
436
+ $this->_log('Empty cell in column "'.$colName.'", skipping this row', null, Zend_Log::WARN);
437
+ }else{
438
+ $this->_log('Empty cell in column "'.$colName.'"', null, Zend_Log::NOTICE);
439
+ }
440
+ $result = false;
441
+ }
442
+ return $result;
443
+ }
444
+
445
+ /**
446
+ * returns an array of urls that are allowed for the current location
447
+ * @return array
448
+ */
449
+ protected function _getAllowedUrls(){
450
+ if($this->_allowedUrls !== null){
451
+ return $this->_allowedUrls;
452
+ }
453
+ $this->_allowedUrls = array();
454
+ switch($this->_getLocation()){
455
+ case self::LOCATION_STORE:
456
+ $this->_addToAlloweds($this->getStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, false), $this->getStore());
457
+ $this->_addToAlloweds($this->getStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, true), $this->getStore());
458
+ break;
459
+ case self::LOCATION_WEBSITE:
460
+ foreach($this->getWebsite()->getStores(false) as $storeId => $store){
461
+ $this->_addToAlloweds($store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, false), $store);
462
+ $this->_addToAlloweds($store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, true), $store);
463
+ }
464
+ break;
465
+ case self::LOCATION_DEFAULT:
466
+ foreach(Mage::app()->getWebsites(false) as $websiteId => $website){
467
+ foreach($website->getStores(false) as $storeId => $store){
468
+ $this->_addToAlloweds($store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, false), $store);
469
+ $this->_addToAlloweds($store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, true), $store);
470
+ }
471
+ }
472
+ }
473
+ return $this->_allowedUrls;
474
+ }
475
+ protected function getBaseUrl(){
476
+ switch($this->_getLocation()){
477
+ case self::LOCATION_STORE:
478
+ $url = Mage::app()->getStore($this->getStore()->getId())->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, false);
479
+ break;
480
+ case self::LOCATION_WEBSITE:
481
+ $url = Mage::app()->getWebsite($this->getWebsite()->getId())->getConfig('web/unsecure/base_link_url');
482
+ if(strpos($url, '{{unsecure_base_url}}') !== false){
483
+ $url = Mage::app()->getStore(0)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, false);
484
+ }
485
+ break;
486
+ case self::LOCATION_DEFAULT:
487
+ default:
488
+ $url = Mage::app()->getStore(0)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, false);
489
+ break;
490
+ }
491
+ return $url;
492
+ }
493
+ protected function _addToAlloweds($url, $store){
494
+ $this->_allowedUrls[$url] = array(
495
+ 'store_id' => $store->getId(),
496
+ 'url' => parse_url($url),
497
+ );
498
+ }
499
+ protected function _parseType($type = null){
500
+ switch($type){
501
+ case Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_LABEL:
502
+ $t = Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_VALUE;
503
+ break;
504
+ case Zero1_Seoredirects_Model_Redirection::FROM_TYPE_OPEN_ENDED_QUERY_LABEL:
505
+ $t = Zero1_Seoredirects_Model_Redirection::FROM_TYPE_OPEN_ENDED_QUERY_VALUE;
506
+ break;
507
+ default:
508
+ $t = Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_VALUE;
509
+ $this->_log('No type found defaulting to fixed, options are: '.Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_LABEL.', '.Zero1_Seoredirects_Model_Redirection::FROM_TYPE_OPEN_ENDED_QUERY_LABEL, null, Zend_Log::INFO);
510
+ }
511
+ return $t;
512
+ }
513
+
514
+ protected function _parsePersistQuery($persistQuery = null){
515
+ switch($persistQuery){
516
+ case 'No':
517
+ $t = 0;
518
+ break;
519
+ case 'Yes':
520
+ $t = 1;
521
+ break;
522
+ default:
523
+ $t = 0;
524
+ $this->_log('No matching value found for persist query, options are: \'Yes\' or \'No\'. Defaulting to No', null, Zend_Log::INFO);
525
+ }
526
+ return $t;
527
+ }
528
+
529
+ /**
530
+ * Remove id from the pool of allowed ids
531
+ * @param $id
532
+ */
533
+ protected function _removeId($id){
534
+ $this->_usedIds[] = $id;
535
+ }
536
+
537
+ /**
538
+ * check if the redirect has been imported already
539
+ * @param $id
540
+ */
541
+ protected function _checkId($id){
542
+ return array_search($id, $this->_usedIds);
543
+ }
544
+
545
+ /**
546
+ * Any url that is of type import and wasn't imported this run, remove.
547
+ */
548
+ protected function _clearUrls(){
549
+ if(empty($this->_usedIds)){
550
+ return;
551
+ }
552
+ //delete all imported urls for this store that are of type import
553
+ /* @var $redirectionCollection Zero1_Seoredirects_Model_Resource_Redirection_Collection */
554
+ $redirectionCollection = Mage::getModel('zero1_seo_redirects/redirection')->getCollection();
555
+ $redirectionCollection
556
+ ->addFieldToFilter('source', Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_IMPORT_VALUE)
557
+ ->addFieldToFilter('redirection_id', array('nin' => array($this->_usedIds)));
558
+ $this->_log('Deleting: '.$redirectionCollection->count().' redirects', 'N/A', Zend_Log::INFO);
559
+ $redirectionCollection->delete();
560
+ $this->_recalculateStatuses();
561
+ }
562
+
563
+ /**
564
+ * If the number of enabled redirects is lower than the limit, and there are disabled redirects, enable all up to limit
565
+ * this occurs because a clean down of the urls occurs last.
566
+ */
567
+ protected function _recalculateStatuses(){
568
+ /* @var $redirectionCollection Zero1_Seoredirects_Model_Resource_Redirection_Collection */
569
+ $enabledRedirectionCount = Mage::getModel('zero1_seo_redirects/redirection')->getCollection()
570
+ ->addFieldToFilter('status', Zero1_Seoredirects_Model_Redirection::REDIRECTION_STATUS_ENABLED_VALUE)
571
+ ->count();
572
+
573
+ /* @var $licenseHelper Zero1_SeoRedirects_Helper_License */
574
+ $licenseHelper = Mage::helper('zero1_seo_redirects/license');
575
+ $licenseLimit = $licenseHelper->getLicenceLimit();
576
+
577
+ if($enabledRedirectionCount < $licenseLimit || $licenseLimit == 0){
578
+ $redirectionCollection = Mage::getModel('zero1_seo_redirects/redirection')->getCollection()
579
+ ->addFieldToFilter('source', array('neq' => Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_LOGGED_VALUE))
580
+ ->addFieldToFilter('status', Zero1_Seoredirects_Model_Redirection::REDIRECTION_STATUS_DISABLED_VALUE);
581
+
582
+ if($licenseLimit > 0){
583
+ $redirectionCollection->setPageSize($licenseLimit - $enabledRedirectionCount);
584
+ $redirectionCollection->setCurPage(1);
585
+ }
586
+ /* @var $redirect Zero1_Seoredirects_Model_Redirection */
587
+ foreach($redirectionCollection as $redirect){
588
+ $redirect->setStatus(Zero1_Seoredirects_Model_Redirection::REDIRECTION_STATUS_ENABLED_VALUE);
589
+ $redirect->save();
590
+ }
591
+ }
592
+ }
593
+
594
+ protected function _buildUrl($parsedUrl){
595
+ $url = $parsedUrl['path'];
596
+ if(isset($parsedUrl['query'])){
597
+ $url .= '?'.$parsedUrl['query'];
598
+ }
599
+ return $url;
600
+ }
601
+
602
+
603
+
604
+ }
app/code/community/Zero1/Seoredirects/Model/Mysql4/Redirection.php DELETED
@@ -1,5 +0,0 @@
1
- <?php
2
- class Zero1_Seoredirects_Model_Mysql4_Redirection extends Zero1_Seoredirects_Model_Resource_Redirection
3
- {
4
-
5
- }
 
 
 
 
 
app/code/community/Zero1/Seoredirects/Model/Mysql4/Redirection/Collection.php DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
- class Zero1_Seoredirects_Model_Mysql4_Redirection_Collection
3
- extends Zero1_Seoredirects_Model_Resource_Redirection_Collection
4
- {
5
-
6
- }
 
 
 
 
 
 
app/code/community/Zero1/Seoredirects/Model/Observer.php CHANGED
@@ -4,79 +4,23 @@
4
  */
5
  class Zero1_Seoredirects_Model_Observer
6
  {
7
- /**
8
- * The default licence limit
9
- */
10
- const DEFAULT_LIMIT = 50;
11
-
12
- /**
13
- * Stores the current Google URL to download the document from
14
- *
15
- * @var string
16
- */
17
- protected $_url;
18
-
19
- /**
20
- * Stores the current file to import from
21
- *
22
- * @var string
23
- */
24
- protected $_file;
25
 
26
- /**
27
- * Strip "http://www.domain.com/" from the URL
28
- *
29
- * @var bool
30
- */
31
- protected $_strip_domain;
32
 
33
- /**
34
- * Strip "/" from the URL
35
- *
36
- * @var bool
37
- */
38
- protected $_strip_slash;
39
 
40
- /**
41
- * @param Varien_Event_Observer $observer
42
- */
43
- protected function checkForRedirection(Varien_Event_Observer $observer)
44
- {
45
- $request = $observer->getFront()->getRequest();
46
-
47
- if($request->getActionName() != 'noRoute')
48
- return; // There is a valid route, nothing to do
49
-
50
- // First search for the URI with query strings
51
- $requestUri = preg_replace('/^'.preg_quote($request->getBasePath(), '/').'/', '', $request->getRequestUri());
52
- $requestUri = str_replace('?', '_', $requestUri); // Zend does not support "?", replace them with "_" wildcard and use LIKE
53
- $redirections = Mage::getModel('seoredirects/redirection')->getCollection();
54
- $redirections->addFieldToFilter('store', Mage::app()->getStore()->getId());
55
- $redirections->addFieldToFilter('redirect_from', array('like' => $requestUri));
56
-
57
- foreach($redirections as $redirection)
58
- {
59
- header('HTTP/1.1 301 Moved Permanently');
60
- header('Location: '.$request->getBasePath().$redirection->getRedirectTo());
61
- die();
62
- }
63
-
64
- // Then search for the URI without query strings
65
- $requestUri = preg_replace('/^'.preg_quote($request->getBasePath(), '/').'/', '', $request->getRequestString());
66
- $redirections = Mage::getModel('seoredirects/redirection')->getCollection();
67
- $redirections->addFieldToFilter('store', Mage::app()->getStore()->getId());
68
- $redirections->addFieldToFilter('redirect_from', $requestUri);
69
-
70
- foreach($redirections as $redirection)
71
- {
72
- header('HTTP/1.1 301 Moved Permanently');
73
- header('Location: '.$request->getBasePath().$redirection->getRedirectTo());
74
- die();
75
- }
76
-
77
- // No redirections
78
- return;
79
- }
80
 
81
  /**
82
  * @param Varien_Event_Observer $observer
@@ -94,186 +38,7 @@ class Zero1_Seoredirects_Model_Observer
94
  $this->checkForRedirection($observer);
95
  }
96
 
97
- /**
98
- * Clean the URL bu removing domain and trailing slashes
99
- *
100
- * @param $url
101
- * @return string
102
- */
103
- protected function _cleanUrl($url)
104
- {
105
- // Strip the domain name from the FROM / TO URL's if it exists
106
- if($this->_strip_domain) {
107
- $url = preg_replace('/^[^:]+:\\/\\/[^\\/]+(.*)$/si', '$1', $url);
108
- }
109
 
110
- // Strip the prefix slash from the FROM / TO URL's if it exists
111
- if($this->_strip_slash) {
112
- $url = preg_replace('/^\\/(.*)$/si', '$1', $url);
113
- }
114
-
115
- return $url;
116
  }
117
-
118
- /**
119
- * Update the redirection(s) from Google and import files
120
- *
121
- */
122
- public function updateRedirectionsCronJob()
123
- {
124
- clearstatcache();
125
-
126
- $stores = Mage::getResourceModel('core/store_collection');
127
- $results = array();
128
-
129
- foreach($stores as $store) {
130
- $this->_url = Mage::getStoreConfig('seoredirects/settings/url', $store->getId());
131
- $this->_strip_domain = Mage::getStoreConfig('seoredirects/settings/strip_domain', $store->getId());
132
- $this->_strip_slash = Mage::getStoreConfig('seoredirects/settings/strip_slash', $store->getId());
133
- $this->_file = Mage::getStoreConfig('seoredirects/settings/file', $store->getId());
134
-
135
- $results[$store->getId()] = array(
136
- 'updated' => 0,
137
- 'deleted' => 0,
138
- 'added' => 0,
139
- 'loops' => 0,
140
- 'limitation' => '',
141
- );
142
-
143
- $redirections = Mage::getModel('seoredirects/redirection')->getCollection();
144
- $redirections->addFieldToFilter('store', $store->getId());
145
-
146
- if(!Mage::getStoreConfig('seoredirects/settings/enabled', $store->getId()))
147
- {
148
- // Redirects are disabled for this store, delete them all
149
- foreach($redirections as $redirection)
150
- {
151
- $redirection->delete();
152
- $results[$store->getId()]['deleted']++;
153
- }
154
-
155
- continue; // Do not import anything now
156
- }
157
-
158
- $redirects = array();
159
-
160
- ////////////////////////////////////////////////
161
- // Load redirection(s) from Google
162
- if(!empty($this->_url)) {
163
- // Get the content from Google and save it in to a file
164
- $client = new Zend_Http_Client($this->_url);
165
- $lines = explode(PHP_EOL, $client->request()->getBody());
166
- foreach($lines as $line) {
167
- $data = str_getcsv($line);
168
- if(is_array($data) && count($data) >= 2) {
169
- $redirects[$this->_cleanUrl($data[0])] = $this->_cleanUrl($data[1]);
170
- }
171
- }
172
- }
173
-
174
- ////////////////////////////////////////////////
175
- // Load redirection(s) from files
176
- $import_path = Mage::getBaseDir('var').'/seoredirects/import';
177
- if(is_dir($import_path)) {
178
- if(is_file($import_path.DS.$this->_file) && is_readable($import_path.DS.$this->_file)) {
179
- $fp = fopen($import_path.DS.$this->_file, 'r');
180
- while(($data = fgetcsv($fp, 4096)) !== false) {
181
- if(is_array($data) && count($data) >= 2) {
182
- $redirects[$this->_cleanUrl($data[0])] = $this->_cleanUrl($data[1]);
183
- }
184
- }
185
- fclose($fp);
186
- }
187
- } else {
188
- mkdir($import_path, 0777, true);
189
- }
190
-
191
- // Detect the limit for this store
192
- $license_data = array();
193
- if(Mage::helper('seoredirects/license')->isValid($store))
194
- $license_data = Mage::helper('seoredirects/license')->getData($store);
195
-
196
- if(isset($license_data['limit']))
197
- {
198
- $limit = $license_data['limit'];
199
- } else {
200
- $limit = self::DEFAULT_LIMIT;
201
- }
202
-
203
- if($limit > 0)
204
- {
205
- $redirects = array_slice($redirects, 0, $limit);
206
- $results[$store->getId()]['limitation'] = 'Limited to '.$limit.' rows by your current license. <a href="'.Mage::helper('seoredirects/license')->getRequestURL($store).'" target="_blank">Click here to increase this limit</a>';
207
- }
208
-
209
- // Add / update the redirection(s)
210
- foreach($redirects as $from => $to)
211
- {
212
- $found = false;
213
-
214
- foreach($redirections as $redirection)
215
- {
216
- if($redirection->getRedirectFrom() == $from)
217
- {
218
- // Existing redirection, update
219
- $redirection->setRedirectTo($to);
220
- $redirection->setRedirectFrom($from);
221
- $redirection->setStore($store->getId());
222
- $redirection->save();
223
- $found = true;
224
- $results[$store->getId()]['updated']++;
225
-
226
- //echo 'Updated <b>'.$from.'</b> = <b>'.$to.'</b> into store ID <b>'.$store->getId().'</b><br/>';
227
- }
228
- }
229
-
230
- if(!$found)
231
- {
232
- // New redirection
233
- $redirection = Mage::getModel('seoredirects/redirection');
234
- $redirection->setRedirectTo($to);
235
- $redirection->setRedirectFrom($from);
236
- $redirection->setStore($store->getId());
237
- $redirection->save();
238
- $results[$store->getId()]['added']++;
239
-
240
- //echo 'Added <b>'.$from.'</b> = <b>'.$to.'</b> into store ID <b>'.$store->getId().'</b><br/>';
241
- }
242
- }
243
-
244
- // Remove all the unused redirection(s)
245
- $redirections = Mage::getModel('seoredirects/redirection')->getCollection();
246
- $redirections->addFieldToFilter('store', $store->getId());
247
- foreach($redirections as $redirection)
248
- {
249
- if(!array_key_exists($redirection->getRedirectFrom(), $redirects))
250
- {
251
- //echo 'Removed <b>'.$redirection->getRedirectFrom().'</b> from store ID <b>'.$store->getId().'</b><br/>';
252
- $redirection->delete();
253
- $results[$store->getId()]['deleted']++;
254
- }
255
- }
256
-
257
- // Make sure there are no redirection(s) loops
258
- $redirections = Mage::getModel('seoredirects/redirection')->getCollection();
259
- $redirections->addFieldToFilter('store', $store->getId());
260
- foreach($redirections as $redirectionA)
261
- {
262
- foreach($redirections as $redirectionB)
263
- {
264
- if(!$redirectionA || !$redirectionB)
265
- continue; // Invalid rediection, been deleted?
266
-
267
- if($redirectionA->getRedirectTo() == $redirectionB->getRedirectFrom())
268
- {
269
- //echo 'Removed loop <b>'.$redirection->getRedirectFrom().'</b> from store ID <b>'.$store->getId().'</b><br/>';
270
- $redirectionA->delete();
271
- $results[$store->getId()]['loops']++;
272
- }
273
- }
274
- }
275
- }
276
-
277
- Mage::register('seoredirects_results', $results);
278
- }
279
  }
4
  */
5
  class Zero1_Seoredirects_Model_Observer
6
  {
7
+ protected function checkForRedirection($observer)
8
+ {
9
+ // There is a valid route, nothing to do
10
+ if(Mage::app()->getRequest()->getActionName() != 'noRoute'){ return; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ /* @var $redirector Zero1_Seoredirects_Model_Redirector */
13
+ $redirector = Mage::getModel('zero1_seo_redirects/redirector');
 
 
 
 
14
 
15
+ $result = $redirector->redirect(
16
+ Mage::app()->getStore()->getId(),
17
+ Mage::helper('core/url')->getCurrentUrl()
18
+ );
 
 
19
 
20
+ if(Mage::helper('zero1_seo_redirects')->canDebug()){
21
+ Mage::helper('zero1_seo_redirects')->debug('Result: '.json_encode($result));
22
+ }
23
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  /**
26
  * @param Varien_Event_Observer $observer
38
  $this->checkForRedirection($observer);
39
  }
40
 
41
+ public function cronImport(){
 
 
 
 
 
 
 
 
 
 
 
42
 
 
 
 
 
 
 
43
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
app/code/community/Zero1/Seoredirects/Model/Redirection.php CHANGED
@@ -1,8 +1,302 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  class Zero1_Seoredirects_Model_Redirection extends Mage_Core_Model_Abstract
3
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  protected function _construct()
5
  {
6
- $this->_init('seoredirects/redirection');
7
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
1
  <?php
2
+
3
+ /**
4
+ * Class Zero1_Seoredirects_Model_Redirection
5
+ * @method Zero1_Seoredirects_Model_Redirection setHits(int $hits)
6
+ * @method int getHits()
7
+ * @method string getToUrl()
8
+ * @method Zero1_Seoredirects_Model_Redirection setToUrl(string $toUrl)
9
+ * @method Zero1_Seoredirects_Model_Redirection setStoreId(int $storeId)
10
+ * @method Zero1_Seoredirects_Model_Redirection setSource(int $source)
11
+ * @method int getSource()
12
+ * @method Zero1_Seoredirects_Model_Redirection setStatus(int $status)
13
+ * @method Zero1_Seoredirects_Model_Redirection setFromType(int $fromType)
14
+ * @method int getFromType()
15
+ * @method Zero1_Seoredirects_Model_Redirection setFromUrlQuery(string $query)
16
+ * @method string getFromUrlQuery()
17
+ * @method int getPersistQuery()
18
+ * @method Zero1_Seoredirects_Model_Redirection setFromUrlPath(string $path)
19
+ * @method string getFromUrlPath()
20
+ */
21
  class Zero1_Seoredirects_Model_Redirection extends Mage_Core_Model_Abstract
22
  {
23
+ const FROM_TYPE_OPEN_ENDED_QUERY_VALUE = 0;
24
+ const FROM_TYPE_OPEN_ENDED_QUERY_LABEL = 'Open Ended Query';
25
+ const FROM_TYPE_FIXED_QUERY_VALUE = 1;
26
+ const FROM_TYPE_FIXED_QUERY_LABEL = 'Fixed Query';
27
+
28
+ const SOURCE_TYPE_LOGGED_VALUE = 0;
29
+ const SOURCE_TYPE_LOGGED_LABEL = 'Logged';
30
+ const SOURCE_TYPE_IMPORT_VALUE = 1;
31
+ const SOURCE_TYPE_IMPORT_LABEL = 'Import';
32
+ const SOURCE_TYPE_MANUAL_VALUE = 2;
33
+ const SOURCE_TYPE_MANUAL_LABEL = 'Manual';
34
+
35
+ const REDIRECTION_STATUS_DISABLED_VALUE = 0;
36
+ const REDIRECTION_STATUS_DISABLED_LABEL = 'Disabled';
37
+ const REDIRECTION_STATUS_ENABLED_VALUE = 1;
38
+ const REDIRECTION_STATUS_ENABLED_LABEL = 'Enabled';
39
+
40
  protected function _construct()
41
  {
42
+ $this->_init('zero1_seo_redirects/redirection');
43
  }
44
+
45
+ protected function _afterLoad(){
46
+ $this->setFromUrl($this->getFromUrlPath().(($this->getFromUrlQuery() != '')? '?'.$this->getFromUrlQuery() : ''));
47
+ }
48
+
49
+ /**
50
+ * @param $storeId
51
+ * @param $urlPath
52
+ * @param null $query
53
+ * @return $this|Mage_Core_Model_Abstract
54
+ */
55
+ public function loadFixed($storeId, $urlPath, $query = null)
56
+ {
57
+ $id = $this->_getResource()->loadFixed($storeId, $urlPath, $query);
58
+ if($id === false){
59
+ return $this;
60
+ }else{
61
+ return $this->load($id);
62
+ }
63
+ }
64
+
65
+ public function save(){
66
+ if (!$this->_hasModelChanged()) {
67
+ return parent::save();
68
+ }
69
+ $validation = $this->validate();
70
+ if(!$validation['result']){
71
+ /* @var $ex Zero1_Seoredirects_Exception */
72
+ $ex = Mage::exception('Zero1_Seoredirects', implode('<br />', $validation['errors']));
73
+ foreach($validation['errors'] as $er){ $ex->addMessage($er); }
74
+ throw $ex;
75
+ }
76
+ //if its not new and anything other than just hits has changed clear cache for this redirect
77
+ $diff = array_diff_assoc((($this->getOrigData() == null)? array() : $this->getOrigData()), $this->getData());
78
+ if(count($diff) > 1 || !isset($diff['hits'])){
79
+ /* @var $cacheCollection Zero1_Seoredirects_Model_Resource_Redirection_Cache_Collection */
80
+ $cacheCollection = Mage::getModel('zero1_seo_redirects/redirection_cache')->getCollection();
81
+ $cacheCollection->addFieldToFilter('redirection_id', $this->getId());
82
+ $cacheCollection->delete();
83
+
84
+ //clear all cached redirects with the same path if the is/was an open ended redirection
85
+ if($this->getFromType() == self::FROM_TYPE_FIXED_QUERY_VALUE || $this->getOrigData('from_type') == self::FROM_TYPE_OPEN_ENDED_QUERY_VALUE){
86
+ $redirectionIds = Mage::getModel('zero1_seo_redirects/redirection')->getCollection()
87
+ ->addFieldToFilter('from_url_path', $this->getFromUrlPath())
88
+ ->getAllIds();
89
+
90
+ if(!empty($redirectionIds)){
91
+ Mage::getModel('zero1_seo_redirects/redirection_cache')->getCollection()
92
+ ->addFieldToFilter('redirection_id', array('in'=> array($redirectionIds)))
93
+ ->delete();
94
+ }
95
+ }
96
+ }
97
+ return parent::save();
98
+ }
99
+
100
+ public function validate(){
101
+ $v = array(
102
+ 'result' => true,
103
+ 'errors' => array(),
104
+ );
105
+ //check urls and order the query strings
106
+ $v = $this->_validateURLs($v);
107
+ //check if from url exists
108
+ $v = $this->_checkFrom($v);
109
+ //check if to url exists
110
+ $v = $this->_checkTo($v);
111
+ //check to and from
112
+ $v = $this->_checkToAndFrom($v);
113
+ $v = $this->_checkPersistQuery($v);
114
+
115
+ //TODO check license
116
+ $v = $this->_checkStatus($v);
117
+
118
+ return $v;
119
+ }
120
+
121
+ protected function _validateURLs($v){
122
+ //do from url
123
+ $url = preg_replace('/\/$/','',$this->getStoreUrl())
124
+ .'/'.preg_replace('/^\//','',$this->getFromUrlPath());
125
+
126
+ list($url, $v) = $this->_parseAndValidateUrl($url, $v);
127
+
128
+ if($v['result']){
129
+ $this->setFromUrlPath($url['path']);
130
+ if(isset($url['query'])){
131
+ $this->setFromUrlQuery($url['query']);
132
+ }else{
133
+ $this->setFromUrlQuery(null);
134
+ }
135
+ }
136
+
137
+ //do to url
138
+ //default logged urls to homepage
139
+ $url = preg_replace('/\/$/','',$this->getStoreUrl()).'/';
140
+ if($this->getSource() != self::SOURCE_TYPE_LOGGED_VALUE){
141
+ $url .= preg_replace('/^\//','',$this->getToUrl());
142
+ }
143
+
144
+ list($url, $v) = $this->_parseAndValidateUrl($url, $v);
145
+ if($v['result']){
146
+ $this->setToUrl($url['path'].(isset($url['query'])? '?'.$url['query'] : ''));
147
+ }
148
+
149
+ return $v;
150
+ }
151
+ protected function _parseAndValidateUrl($url, $result){
152
+ if(!filter_var($url, FILTER_VALIDATE_URL)){
153
+ $result['result'] = false;
154
+ $result['errors'][] = $this->getHelper()->__('Failed to validate url. '.$url);
155
+ }
156
+ if(!$u = parse_url($url)){
157
+ $result['result'] = false;
158
+ $result['errors'][] = $this->getHelper()->__('Failed to parse url.'.$url);
159
+ }elseif(isset($u['query']) && substr_count($u['query'], '=') == 0){
160
+ $result['result'] = false;
161
+ $result['errors'][] = $this->getHelper()->__('Failed to validate url, could not find \'=\' in query string. '.$url);
162
+ }else{
163
+ $url = $this->_getUrlHelper()->parseUrl($url, $this->getStoreId());
164
+ }
165
+ return array($url, $result);
166
+ }
167
+
168
+ protected function _checkFrom($v){
169
+ /* @var $redirector Zero1_Seoredirects_Model_Redirector */
170
+ $redirector = Mage::getModel('zero1_seo_redirects/redirector');
171
+ $result = $redirector->redirect(
172
+ $this->getStoreId(),
173
+ $this->getFromUrl(),
174
+ true
175
+ );
176
+
177
+ if($result && $result != $this->getId()){
178
+ $v['result'] = false;
179
+ $v['errors'][] = $this->getHelper()->__('A redirect for this location already exists ('.$result.').');
180
+ }
181
+
182
+ return $v;
183
+ }
184
+
185
+ protected function _checkTo($v){
186
+ /* @var $redirector Zero1_Seoredirects_Model_Redirector */
187
+ $redirector = Mage::getModel('zero1_seo_redirects/redirector');
188
+ $result = $redirector->redirect(
189
+ $this->getStoreId(),
190
+ $this->getToUrl(),
191
+ true
192
+ );
193
+
194
+ if($result){
195
+ $v['result'] = false;
196
+ $v['errors'][] = $this->getHelper()->__('A redirect for the location you are redirecting to already exists ('.$result.').');
197
+ }
198
+
199
+ return $v;
200
+ }
201
+
202
+ protected function _checkToAndFrom($v){
203
+ if($this->getToUrl() == $this->getFromUrlPath().((!$this->getFromUrlQuery())? '' : '?'.$this->getFromUrlQuery())){
204
+ $v['result'] = false;
205
+ $v['errors'][] = $this->getHelper()->__('A redirect cannot have a to and from that are the same');
206
+ }
207
+ return $v;
208
+ }
209
+
210
+ protected function _checkPersistQuery($v){
211
+ if($this->getFromType() != self::FROM_TYPE_OPEN_ENDED_QUERY_VALUE){
212
+ $this->setPersistQuery(false);
213
+ }
214
+ return $v;
215
+ }
216
+
217
+ protected function _checkStatus($v){
218
+
219
+ if($this->getSource() == self::SOURCE_TYPE_LOGGED_VALUE){
220
+ $this->setStatus(self::REDIRECTION_STATUS_DISABLED_VALUE);
221
+ return $v;
222
+ }
223
+
224
+ //TODO figure out a better way to do this
225
+ $cCount = Mage::getModel('zero1_seo_redirects/redirection')->getCollection()
226
+ ->addFieldToFilter('status', self::REDIRECTION_STATUS_ENABLED_VALUE);
227
+ if($this->getRedirectionId()){
228
+ $cCount->addFieldToFilter('redirection_id', array('neq' => $this->getRedirectionId()));
229
+ }
230
+ $cCount = $cCount->count();
231
+
232
+ $lCount = $this->_getLicenseHelper()->getLicenceLimit();
233
+
234
+ if($cCount < $lCount || $lCount == 0){
235
+ $this->setStatus(self::REDIRECTION_STATUS_ENABLED_VALUE);
236
+ }else{
237
+ $this->setStatus(self::REDIRECTION_STATUS_DISABLED_VALUE);
238
+ }
239
+
240
+ return $v;
241
+ }
242
+
243
+ //helpers
244
+ public function getStoreUrl(){
245
+ if(!$this->getData('store_url')){
246
+ $this->setStoreUrl(Mage::app()->getStore($this->getStoreId())->getBaseUrl());
247
+ }
248
+ return $this->getData('store_url');
249
+ }
250
+
251
+ /**
252
+ * @return Zero1_Seoredirects_Helper_Data
253
+ */
254
+ public function getHelper(){
255
+ return Mage::helper('zero1_seo_redirects');
256
+ }
257
+
258
+ /**
259
+ * @return Zero1_Seoredirects_Helper_Urls
260
+ */
261
+ protected function _getUrlHelper(){
262
+ return Mage::helper('zero1_seo_redirects/urls');
263
+ }
264
+
265
+ /**
266
+ * @return Zero1_Seoredirects_Helper_License
267
+ */
268
+ protected function _getLicenseHelper(){
269
+ return Mage::helper('zero1_seo_redirects/license');
270
+ }
271
+
272
+
273
+ public function incrementHits(){
274
+ return $this->setHits($this->getHits() + 1);
275
+ }
276
+
277
+ public function isEnabled(){
278
+ return (bool)$this->getStatus();
279
+ }
280
+
281
+ public function shouldPersistQuery(){
282
+ return (bool)$this->getPersistQuery();
283
+ }
284
+
285
+ public function setPersistQuery($persist = false){
286
+ $this->setData('persist_query', (bool)$persist);
287
+ return $this;
288
+ }
289
+
290
+ public function getFromUrl(){
291
+ if(!$this->getData('from_url')){
292
+ $storeUrl = parse_url($this->getStoreUrl());
293
+ $this->setFromUrl(
294
+ $storeUrl['scheme'].'://'.
295
+ preg_replace('/\/$/','',$storeUrl['host']).'/'.
296
+ preg_replace('/^\//','',$this->getFromUrlPath()).
297
+ ((!$this->getFromUrlQuery())? '' : '?'.$this->getFromUrlQuery())
298
+ );
299
+ }
300
+ return $this->getData('from_url');
301
+ }
302
  }
app/code/community/Zero1/Seoredirects/Model/Redirection/Cache.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Zero1_Seoredirects_Model_Redirection_Cache
5
+ * @method string getFromUrl()
6
+ * @method Zero1_Seoredirects_Model_Redirection_Cache setFromUrl(string $fromUrl)
7
+ * @method string getToUrl()
8
+ * @method Zero1_Seoredirects_Model_Redirection_Cache setToUrl(string $toUrl)
9
+ * @method int getRedirectionId()
10
+ * @method Zero1_Seoredirects_Model_Redirection_Cache setRedirectionId(int $redirectionId)
11
+ */
12
+ class Zero1_Seoredirects_Model_Redirection_Cache extends Mage_Core_Model_Abstract
13
+ {
14
+ protected function _construct(){
15
+ $this->_init('zero1_seo_redirects/redirection_cache');
16
+ }
17
+ }
app/code/community/Zero1/Seoredirects/Model/Redirector.php ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Model_Redirector{
3
+
4
+ private $originalUrl;
5
+ private $cachedUrlModel;
6
+
7
+ /**
8
+ * @param $storeId
9
+ * @param $url
10
+ * @param bool $dryRun
11
+ * @return string | null
12
+ */
13
+ public function redirect($storeId, $url, $dryRun = false){
14
+ $this->_getHelper()->debug('redirect('.$storeId.', '.$url.', '.json_encode($dryRun).')');
15
+
16
+ $this->originalUrl = $url;
17
+ $this->cachedUrlModel = null;
18
+
19
+ //first check if there is a cached version of the $url
20
+ if($this->isCached()){
21
+ if($dryRun){
22
+ return $this->getCachedRedirect()->getId();
23
+ }else{
24
+ $this->_redirect($this->getCachedRedirect()->getId(), $this->getCachedRedirect()->getToUrl());
25
+ }
26
+ }
27
+ $this->_getHelper()->debug('No cached url found');
28
+
29
+ //sort query string alphabetically, and remove ignoreables
30
+ $parsedUrl = $this->_getUrlHelper()->parseUrl($url, $storeId);
31
+ $this->_getHelper()->debug(json_encode($parsedUrl));
32
+
33
+ /* @var $redirection Zero1_Seoredirects_Model_Redirection */
34
+ $redirection = Mage::getModel('zero1_seo_redirects/redirection');
35
+
36
+ //search for matches of type fixed
37
+ $redirection->loadFixed($storeId, $parsedUrl['path'], (isset($parsedUrl['query'])? $parsedUrl['query'] : null));
38
+ if($redirection->getId()){
39
+ if($dryRun){
40
+ return $redirection->getId();
41
+ }
42
+ $this->_getHelper()->debug('Found Url outside of cache');
43
+ if($redirection->isEnabled()){
44
+ $to = $parsedUrl['scheme'].'://'.$parsedUrl['host'].$redirection->getToUrl();
45
+ $this->_cache($redirection->getId(), $url, $to);
46
+ $this->_redirect($redirection->getId(), $to);
47
+ }else{
48
+ $this->_getHelper()->debug('Redirect disabled');
49
+ $this->_incrementHits($redirection->getId());
50
+ return false;
51
+ }
52
+ }
53
+ $this->_getHelper()->debug('No fixed matches');
54
+
55
+ //search for matches of type open ended
56
+ $queryless = !isset($parsedUrl['query']);
57
+ /* @var $redirectionCollection Zero1_Seoredirects_Model_Resource_Redirection_Collection */
58
+ $redirectionCollection = Mage::getModel('zero1_seo_redirects/redirection')->getCollection();
59
+ $redirectionCollection->addOpenEnded()
60
+ ->addFieldToFilter('store_id', 1)
61
+ ->addFieldToFilter('from_url_path', $parsedUrl['path']);
62
+ //if the input doesn't have a query string, then we are looking for an open ended with no query params
63
+ if($queryless){
64
+ $redirectionCollection->addFieldToFilter('from_url_query', null);
65
+ }
66
+ $this->_getHelper()->debug($redirectionCollection->getSelectSql(true));
67
+
68
+ $this->_getHelper()->debug('Open ended possible matches: '.$redirectionCollection->count());
69
+
70
+ if($redirectionCollection->count() == 0){
71
+ if(!$dryRun){
72
+ $this->_logNoMatch($storeId, $parsedUrl);
73
+ }
74
+ return false;
75
+ }
76
+
77
+ //just use the first result
78
+ if($queryless){
79
+ $redirection = $redirectionCollection->getFirstItem();
80
+ if($dryRun){
81
+ return $redirection->getId();
82
+ }
83
+ if($redirection->isEnabled()){
84
+ $to = $parsedUrl['scheme'].'://'.$parsedUrl['host'].$redirection->getToUrl();
85
+ $this->_cache($redirection->getId(), $url, $to);
86
+ $this->_redirect($redirection->getId(), $to);
87
+ }else{
88
+ $this->_getHelper()->debug('Redirect disabled');
89
+ $this->_incrementHits($redirection->getId());
90
+ return false;
91
+ }
92
+ }
93
+
94
+ //if its a dryRun find out if the from path is matched exactly
95
+ if($dryRun){
96
+ $match = null;
97
+ foreach($redirectionCollection as $redirection){
98
+ if($parsedUrl['query'] == $redirection->getFromUrlQuery()){
99
+ $match = $redirection;
100
+ break;
101
+ }
102
+ }
103
+ if($match){
104
+ return $match->getId();
105
+ }else{
106
+ return false;
107
+ }
108
+ }
109
+ //find the result with the highest number of matches
110
+ $highestMatching = null;
111
+ $highestCount = -1;
112
+ $inputParams = $this->_getUrlHelper()->getAssocQuery($parsedUrl['query']);
113
+ foreach($redirectionCollection as $redirection){
114
+ $redirectParams = $this->_getUrlHelper()->getAssocQuery($redirection->getFromUrlQuery());
115
+ //get the number of common k=>v params
116
+ $count = count(array_intersect_assoc($inputParams, $redirectParams));
117
+ //count needs to match params from redirect
118
+ if($count >= count($redirectParams) && $count > $highestCount){
119
+ $highestCount = $count;
120
+ $highestMatching = $redirection;
121
+ }
122
+ }
123
+
124
+ if($highestMatching == null){
125
+ $this->_logNoMatch($storeId, $parsedUrl);
126
+ return false;
127
+ }
128
+
129
+ if(!$highestMatching->isEnabled()){
130
+ $this->_getHelper()->debug('Redirect disabled');
131
+ $this->_incrementHits($highestMatching->getId());
132
+ return false;
133
+ }
134
+
135
+ $to = $parsedUrl['scheme'].'://'.$parsedUrl['host'];
136
+ $parsedMatch = parse_url($highestMatching->getToUrl());
137
+ $to .= $parsedMatch['path'];
138
+ //merge in query params if need
139
+ if($highestMatching->shouldPersistQuery()){
140
+ $to .= '?'.$parsedUrl['query'];
141
+ }else{
142
+ $to .= (isset($parsedMatch['query'])? '?'.$parsedMatch['query'] : '');
143
+ }
144
+
145
+ $this->_cache($highestMatching->getId(), $url, $to);
146
+ $this->_redirect($highestMatching->getId(), $to);
147
+
148
+ Mage::log('Zero1 SeoRedirects Error', Zend_Log::CRIT);
149
+ }
150
+
151
+ protected function isCached(){
152
+ if(!$this->getCachedRedirect()->getId()){
153
+ return false;
154
+ }else{
155
+ return true;
156
+ }
157
+ }
158
+
159
+ /* @return Zero1_Seoredirects_Model_Redirection_Cache */
160
+ protected function getCachedRedirect(){
161
+ if($this->cachedUrlModel == null){
162
+ $this->cachedUrlModel = Mage::getModel('zero1_seo_redirects/redirection_cache')->load($this->originalUrl, 'from_url');
163
+ }
164
+ return $this->cachedUrlModel;
165
+ }
166
+
167
+
168
+ protected function _redirect($redirectionId, $url){
169
+ $this->_incrementHits($redirectionId);
170
+ if($this->_getHelper()->canDebug()){
171
+ $this->_getHelper()->debug('Redirecting to: '.$url);
172
+ }
173
+ header('HTTP/1.1 301 Moved Permanently');
174
+ header('Location: '.$url);
175
+ die();
176
+ }
177
+
178
+ protected function _cache($redirectId, $from, $to){
179
+ $this->_getHelper()->debug('caching: '.$from.' => '.$to);
180
+ /* @var $cached Zero1_Seoredirects_Model_Redirection_Cache */
181
+ $cached = Mage::getModel('zero1_seo_redirects/redirection_cache');
182
+ $cached->setRedirectionId($redirectId)
183
+ ->setFromUrl($from)
184
+ ->setToUrl($to)
185
+ ->save();
186
+ return $this;
187
+ }
188
+
189
+ protected function _incrementHits($redirectionId){
190
+ $this->_getHelper()->debug('incrementing hits: ');
191
+ /* @var $r Zero1_Seoredirects_Model_Redirection */
192
+ $r = Mage::getModel('zero1_seo_redirects/redirection')->load($redirectionId);
193
+ $this->_getHelper()->debug($r->getFromUrl());
194
+ if($r->getId()){
195
+ $r->incrementHits()->save();
196
+ }
197
+ }
198
+
199
+ protected function _logNoMatch($storeId, $parsedUrl){
200
+ //check if logging is enabled
201
+ if(!$this->_getHelper()->getIsLog404Enabled($storeId)){
202
+ if($this->_getHelper()->canDebug()){
203
+ $this->_getHelper()->debug('logging 404\'s is disabled');
204
+ }
205
+ return;
206
+ }
207
+ //check if log is at limit
208
+ $limit = $this->_getHelper()->getLog404Limit($storeId);
209
+ //no point counting if limit is unlimited
210
+ if($limit != 0){
211
+ $loggedCount = Mage::getModel('zero1_seo_redirects/redirection')->getCollection()
212
+ ->addFieldToFilter('store_id', $storeId)
213
+ ->addFieldToFilter('source', Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_LOGGED_VALUE)
214
+ ->count();
215
+
216
+ if($loggedCount == $limit){
217
+ if($this->_getHelper()->canDebug()){
218
+ $this->_getHelper()->debug('logging is enabled, but limit has been reached');
219
+ }
220
+ return;
221
+ }
222
+ }
223
+
224
+ /* @var $r Zero1_Seoredirects_Model_Redirection */
225
+ $r = Mage::getModel('zero1_seo_redirects/redirection');
226
+ $r->setFromUrlPath($parsedUrl['path'])
227
+ ->setStoreId($storeId)
228
+ ->setSource(Zero1_Seoredirects_Model_Redirection::SOURCE_TYPE_LOGGED_VALUE)
229
+ ->setStatus(0)
230
+ ->setFromUrlQuery((isset($parsedUrl['query'])? $parsedUrl['query'] : null))
231
+ ->setFromType(Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_VALUE)
232
+ ->setHits(1)
233
+ ->save();
234
+
235
+ if($this->_getHelper()->canDebug()){
236
+ $this->_getHelper()->debug('logged no match');
237
+ }
238
+ return;
239
+ }
240
+
241
+ /**
242
+ * @return Zero1_Seoredirects_Helper_Urls
243
+ */
244
+ protected function _getUrlHelper(){
245
+ return Mage::helper('zero1_seo_redirects/urls');
246
+ }
247
+
248
+ /**
249
+ * @return Zero1_Seoredirects_Helper_Data
250
+ */
251
+ protected function _getHelper(){
252
+ return Mage::helper('zero1_seo_redirects');
253
+ }
254
+ }
app/code/community/Zero1/Seoredirects/Model/Resource/Redirection.php CHANGED
@@ -3,6 +3,24 @@ class Zero1_Seoredirects_Model_Resource_Redirection extends Mage_Core_Model_Mysq
3
  {
4
  protected function _construct()
5
  {
6
- $this->_init('seoredirects/redirection', 'entity_id');
7
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
3
  {
4
  protected function _construct()
5
  {
6
+ $this->_init('zero1_seo_redirects/redirection', 'redirection_id');
7
  }
8
+
9
+
10
+ public function loadFixed($storeId = null, $urlPath = '', $query = null)
11
+ {
12
+ if(is_null($storeId)){
13
+ return null;
14
+ }
15
+
16
+ $read = $this->_getReadAdapter();
17
+ $select = $read->select('id')
18
+ ->from($this->getMainTable())
19
+ ->where('from_url_path = ?', $urlPath)
20
+ ->where('store_id = ?', $storeId)
21
+ ->where('from_type = ?', Zero1_Seoredirects_Model_Redirection::FROM_TYPE_FIXED_QUERY_VALUE)
22
+ ->where('from_url_query = ?', $query);
23
+
24
+ return $read->fetchOne($select);
25
+ }
26
  }
app/code/community/Zero1/Seoredirects/Model/Resource/Redirection/Cache.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Zero1_Seoredirects_Model_Resource_Redirection_Cache
5
+ */
6
+ class Zero1_Seoredirects_Model_Resource_Redirection_Cache extends Mage_Core_Model_Mysql4_Abstract
7
+ {
8
+ protected function _construct()
9
+ {
10
+ $this->_init('zero1_seo_redirects/redirection_cache', 'redirection_cache_id');
11
+ }
12
+ }
app/code/community/Zero1/Seoredirects/Model/Resource/Redirection/Cache/Collection.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Model_Resource_Redirection_Cache_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
3
+ {
4
+ protected function _construct()
5
+ {
6
+ $this->_init('zero1_seo_redirects/redirection_cache');
7
+ }
8
+
9
+ public function delete(){
10
+ $this->load();
11
+ foreach($this->_items as $r){
12
+ $r->delete();
13
+ }
14
+ }
15
+ }
app/code/community/Zero1/Seoredirects/Model/Resource/Redirection/Collection.php CHANGED
@@ -3,6 +3,17 @@ class Zero1_Seoredirects_Model_Resource_Redirection_Collection extends Mage_Core
3
  {
4
  protected function _construct()
5
  {
6
- $this->_init('seoredirects/redirection');
7
  }
 
 
 
 
 
 
 
 
 
 
 
8
  }
3
  {
4
  protected function _construct()
5
  {
6
+ $this->_init('zero1_seo_redirects/redirection');
7
  }
8
+
9
+ public function delete(){
10
+ $this->load();
11
+ foreach($this->_items as $r){
12
+ $r->delete();
13
+ }
14
+ }
15
+
16
+ public function addOpenEnded(){
17
+ return $this->addFieldToFilter('from_type', Zero1_Seoredirects_Model_Redirection::FROM_TYPE_OPEN_ENDED_QUERY_VALUE);
18
+ }
19
  }
app/code/community/Zero1/Seoredirects/Model/Source/Files.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- class Zero1_Seoredirects_Model_Source_Files
3
- {
4
- /**
5
- * Retrieve options array
6
- *
7
- * @return array
8
- */
9
- public function toOptionArray()
10
- {
11
- $options = array();
12
-
13
- $options[] = array(
14
- 'label' => 'None',
15
- 'value' => '',
16
- );
17
-
18
- $import_path = Mage::getBaseDir('var').DS.'seoredirects'.DS.'import';
19
- if(is_dir($import_path)) {
20
- foreach(glob($import_path.DS.'*.csv') as $filename) {
21
- $filename = str_replace($import_path.DS, '', $filename);
22
- $options[] = array(
23
- 'label' => $filename,
24
- 'value' => $filename,
25
- );
26
- }
27
- } else {
28
- mkdir($import_path, 0777, true);
29
- }
30
-
31
- return $options;
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Zero1/Seoredirects/TODO.txt ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ - Add button to serial key entry to allow automated call away to us
2
+ - Make sure report email includes URL use stats
3
+ - Make 0 unlimited for URL key
4
+ - When unselecting 'use website' the options need to be enabled for adding ignorebales
5
+ - Check that license stuff still works
6
+ - Hook up hint links to correct Wiki pages
7
+ - Work persist query into import process
8
+
9
+
10
+ Done!!! :D
11
+ - Add config option to be able to declare 'ignoreables'
12
+ - Remove query type logging
13
+ - Remove from type from the module
14
+ - Remove to type from the module
15
+ - Add source field
16
+ - Remove to and from types from the manual add
17
+ - Make links to files work
18
+ - Make config check if file is actually there.
19
+ - Debug same store in manual add redirect
20
+ - Implement ignoring ingnoreables - when saving a redirect
21
+ - Fixed bug where removing ignorables would allow a url like this to be saved /a?
22
+ - Removed rouge '/' at end of from urls
23
+ - Removed bug where open ended queries would default to fixed when editing manually
24
+ - Allow different types of redirect: persist query, ignore query
25
+ - Implement ignoring ingnoreables - when finding a redirect
26
+ - Add Alias table
27
+ - Sort out manage grid, remove not needed fields
28
+ - Add validation to persistables i.e stop a=b being allowed
29
+ - Implement recursion tests when saving redirects
30
+ - Implement License count test when saving redirects
31
+ - add number of successful imported rows
32
+ - make sure on redirection update cache is cleared, Clear cache when url is deactivated
33
+ - Do license count on a global basis rather than per store
34
+ - Rework import process, so it is incremental
35
+ - Sort out import redirects page
36
+ - Make export functionality work
37
+ - Have report function to allow monitoring of how many URLs per store.
38
+ - Add a counter to config page (summary of redirects in use)
39
+ - sort out cron job
40
+
41
+
42
+
43
+
44
+ ==============================================================================
45
+ || USEFUL ||
46
+ ==============================================================================
47
+ //$url = 'https://docs.google.com/spreadsheet/pub?key=0Ajn9n2I70JS5dFFNRHRad1dhZERlRXNzUGl2eTl0akE&output=csv'; // CSV type
48
+ //$url = 'https://docs.google.com/spreadsheets/d/1_LmfnFJjxvX5X9TCwXN-EKFxOVRtegg__XTrZlPTUl4/pubhtml'; // HTML type
app/code/community/Zero1/Seoredirects/controllers/Adminhtml/Seoredirects/ConfigController.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Adminhtml_Seoredirects_ConfigController extends Mage_Adminhtml_Controller_Action
3
+ {
4
+ public function indexAction()
5
+ {
6
+ $path = urldecode($this->getRequest()->getParam('path', ''));
7
+ $name = urldecode($this->getRequest()->getParam('name', 'filename'));
8
+
9
+ if(file_exists($path) && !is_dir($path)){
10
+ header('Content-Description: File Transfer');
11
+ header('Content-Type: application/octet-stream');
12
+ header('Content-Disposition: attachment; filename='.$name);
13
+ header('Content-Length: '.filesize($path));
14
+
15
+ ob_clean();
16
+ flush();
17
+ readfile($path);
18
+ }else{
19
+ echo 'ERROR<br />';
20
+ echo $path.'<br />';
21
+ }
22
+ die;
23
+ }
24
+ }
app/code/community/Zero1/Seoredirects/controllers/Adminhtml/Seoredirects/ImportController.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Zero1_Seoredirects_Adminhtml_Seoredirects_ImportController extends Mage_Adminhtml_Controller_Action
3
+ {
4
+ public function indexAction()
5
+ {
6
+ $this->_title($this->__('SEO Redirects'))
7
+ ->_title($this->__('Import Redirects'));
8
+ $this->loadLayout();
9
+ $this->_setActiveMenu('catalog/seoredirects');
10
+ $this->renderLayout();
11
+ }
12
+
13
+ public function runAction(){
14
+ /* @var $import Zero1_Seoredirects_Model_Importer */
15
+ $import = Mage::getModel('zero1_seo_redirects/importer');
16
+ $content = '';
17
+
18
+ try{
19
+ $log = $import->import();
20
+ /* @var $b Zero1_Seoredirects_Block_Adminhtml_Manage_Report */
21
+ $b = Mage::app()->getLayout()->createBlock('zero1_seo_redirects/adminhtml_manage_report');
22
+ $content .= $b->toHtml();
23
+
24
+ /* @var $b Zero1_Seoredirects_Block_Adminhtml_Import_Report */
25
+ $b = Mage::app()->getLayout()->createBlock('zero1_seo_redirects/adminhtml_import_report');
26
+ $b->setLogData($log);
27
+ $content .= $b->toHtml();
28
+ }catch(Exception $e){
29
+ $content .= $e;
30
+ }
31
+
32
+ echo $content;
33
+
34
+ }
35
+ }
app/code/community/Zero1/Seoredirects/controllers/Adminhtml/Seoredirects/ManageController.php CHANGED
@@ -2,18 +2,144 @@
2
  class Zero1_Seoredirects_Adminhtml_Seoredirects_ManageController extends Mage_Adminhtml_Controller_Action
3
  {
4
  public function indexAction()
5
- {
6
  $this->_title($this->__('SEO Redirects'))
7
  ->_title($this->__('Manage Redirects'));
8
-
9
  $this->loadLayout();
10
  $this->_setActiveMenu('catalog/seoredirects');
11
  $this->renderLayout();
12
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  public function updateAction()
15
  {
16
- Mage::getModel('seoredirects/observer')->updateRedirectionsCronJob();
17
 
18
  $results = Mage::registry('seoredirects_results');
19
  $stores = Mage::getResourceModel('core/store_collection');
@@ -30,35 +156,46 @@ class Zero1_Seoredirects_Adminhtml_Seoredirects_ManageController extends Mage_Ad
30
  }
31
 
32
  $this->_getSession()->addSuccess(
33
- Mage::helper('seoredirects')->__($store->getName())
34
  );
35
 
36
  if($results[$store->getId()]['updated'] > 0)
37
  $this->_getSession()->addSuccess(
38
- Mage::helper('seoredirects')->__($pad.'Updated '.$results[$store->getId()]['updated'].' redirection(s).')
39
  );
40
 
41
  if($results[$store->getId()]['added'] > 0)
42
  $this->_getSession()->addSuccess(
43
- Mage::helper('seoredirects')->__($pad.'Added '.$results[$store->getId()]['added'].' redirection(s).')
44
  );
45
 
46
  if($results[$store->getId()]['deleted'] > 0)
47
  $this->_getSession()->addSuccess(
48
- Mage::helper('seoredirects')->__($pad.'Deleted '.$results[$store->getId()]['deleted'].' redirection(s).')
49
  );
50
 
51
  if($results[$store->getId()]['loops'] > 0)
52
  $this->_getSession()->addSuccess(
53
- Mage::helper('seoredirects')->__($pad.'Deleted '.$results[$store->getId()]['loops'].' looping redirection(s).')
54
  );
55
 
56
  if(!empty($results[$store->getId()]['limitation']))
57
  $this->_getSession()->addSuccess(
58
- Mage::helper('seoredirects')->__($pad.$results[$store->getId()]['limitation'])
59
  );
60
  }
61
 
62
  $this->_redirect('*/*/index');
63
  }
 
 
 
 
 
 
 
 
 
 
 
64
  }
2
  class Zero1_Seoredirects_Adminhtml_Seoredirects_ManageController extends Mage_Adminhtml_Controller_Action
3
  {
4
  public function indexAction()
5
+ {
6
  $this->_title($this->__('SEO Redirects'))
7
  ->_title($this->__('Manage Redirects'));
8
+
9
  $this->loadLayout();
10
  $this->_setActiveMenu('catalog/seoredirects');
11
  $this->renderLayout();
12
  }
13
+
14
+ public function newAction(){
15
+ $this->_forward('edit');
16
+ }
17
+
18
+ public function editAction(){
19
+ $this->_title($this->__('Catalog'))->_title($this->__('Seo Redirects'));
20
+
21
+ $id = $this->getRequest()->getParam('id');
22
+ $model = Mage::getModel('zero1_seo_redirects/redirection');
23
+
24
+ if($id){
25
+ $model->load($id);
26
+ if(!$model->getId()){
27
+ Mage::getSingleton('adminhtml/session')->addError(
28
+ Mage::helper('zero1_seo_redirects')->__('Redirect no longer exists.'));
29
+ $this->_redirect('*/*/');
30
+ return;
31
+ }
32
+ }
33
+ $this->_title($model->getId() ? $this->__('Edit Seo Redirection') : $this->__('Create New Seo Redirection'));
34
+
35
+ $data = Mage::getSingleton('adminhtml/session')->getFormData(true);
36
+ if(!empty($data)){
37
+ $model->setData($data);
38
+ }
39
+
40
+ Mage::register('zero1_seo_redirect', $model);
41
+ $this->loadLayout()->renderLayout();
42
+ }
43
+
44
+ public function saveAction(){
45
+ if($data = $this->getRequest()->getParams()){
46
+ /* @var $model Zero1_Seoredirects_Model_Redirection */
47
+ $model = Mage::getModel('zero1_seo_redirects/redirection');
48
+ //if editing load model first
49
+ if(isset($data['redirection_id'])){
50
+ $model->load($data['redirection_id']);
51
+ }
52
+ //add changes from form
53
+ $model->setData($data);
54
+ try{
55
+ $model->save();
56
+
57
+ Mage::getSingleton('adminhtml/session')->addSuccess(
58
+ Mage::helper('zero1_seo_redirects')->__('Redirection has been saved')
59
+ );
60
+ Mage::getSingleton('adminhtml/session')->setFormData(false);
61
+ $this->_redirect('*/*/');
62
+ return;
63
+ }catch(Exception $e){
64
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
65
+ Mage::getSingleton('adminhtml/session')->setFormData($data);
66
+ Mage::register('zero1_seo_redirect', $model);
67
+ $this->_redirect('*/*/edit');
68
+ return;
69
+ }
70
+ }
71
+ }
72
+
73
+ public function deleteAction(){
74
+ if(!$id = $this->getRequest()->getParam('id')){
75
+ //complete fail no ids available
76
+ Mage::getSingleton('adminhtml/session')->addError(
77
+ Mage::helper('zero1_seo_redirects')->__('Unable to find redirect.')
78
+ );
79
+ $this->_redirect('*/*/');
80
+ return;
81
+ }
82
+ try{
83
+ $model = Mage::getModel('zero1_seo_redirects/redirection');
84
+ $model->load($id);
85
+ $model->delete();
86
+
87
+ Mage::getSingleton('adminhtml/session')->addSuccess(
88
+ Mage::helper('zero1_seo_redirects')->__('The redirect has been deleted')
89
+ );
90
+ $this->_redirect('*/*/');
91
+ return;
92
+ }catch(Exception $e){
93
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
94
+ $this->_redirect('*/*/edit');
95
+ return;
96
+ }
97
+ }
98
+
99
+ public function massDeleteAction(){
100
+ if(!$ids = $this->getRequest()->getParam('redirection_id')){
101
+ Mage::getSingleton('adminhtml/session')->addError(
102
+ Mage::helper('zero1_seo_redirecs')->__('Unable to process request.')
103
+ );
104
+ }
105
+ $model = Mage::getModel('zero1_seo_redirects/redirection');
106
+ $result = array(
107
+ 'success' => 0,
108
+ 'fails' => array(),
109
+ );
110
+ foreach($ids as $id){
111
+ try{
112
+ $model->load($id);
113
+ $model->delete();
114
+ $result['success']++;
115
+ }catch(Exception $e){
116
+ $result['fails'][] = '[id:'.$id.'] '.$e->getMessage();
117
+ }
118
+ }
119
+ if(count($result['success']) > 0){
120
+ Mage::getSingleton('adminhtml/session')->addSuccess(
121
+ count($result['success']).Mage::helper('zero1_seo_redirects')->__(' redirect(s) successfully deleted.')
122
+ );
123
+ }
124
+ if(count($result['fails']) > 0){
125
+ $errorString = count($result['fails']) . Mage::helper('zero1_seo_redirects')->__(' redirect(s) failed to be deleted.<br />');
126
+ foreach($result['fails'] as $aFail){
127
+ $errorString .= $aFail . '<br />';
128
+ }
129
+ Mage::getSingleton('adminhtml/session')->addError($errorString);
130
+ }
131
+ $this->_redirect('*/*/');
132
+ return;
133
+ }
134
+
135
+ public function gridAction(){
136
+ $this->loadLayout(false);
137
+ $this->renderLayout();
138
+ }
139
 
140
  public function updateAction()
141
  {
142
+ Mage::getModel('zero1_seo_redirects/observer')->updateRedirectionsCronJob();
143
 
144
  $results = Mage::registry('seoredirects_results');
145
  $stores = Mage::getResourceModel('core/store_collection');
156
  }
157
 
158
  $this->_getSession()->addSuccess(
159
+ Mage::helper('zero1_seo_redirects')->__($store->getName())
160
  );
161
 
162
  if($results[$store->getId()]['updated'] > 0)
163
  $this->_getSession()->addSuccess(
164
+ Mage::helper('zero1_seo_redirects')->__($pad.'Updated '.$results[$store->getId()]['updated'].' redirection(s).')
165
  );
166
 
167
  if($results[$store->getId()]['added'] > 0)
168
  $this->_getSession()->addSuccess(
169
+ Mage::helper('zero1_seo_redirects')->__($pad.'Added '.$results[$store->getId()]['added'].' redirection(s).')
170
  );
171
 
172
  if($results[$store->getId()]['deleted'] > 0)
173
  $this->_getSession()->addSuccess(
174
+ Mage::helper('zero1_seo_redirects')->__($pad.'Deleted '.$results[$store->getId()]['deleted'].' redirection(s).')
175
  );
176
 
177
  if($results[$store->getId()]['loops'] > 0)
178
  $this->_getSession()->addSuccess(
179
+ Mage::helper('zero1_seo_redirects')->__($pad.'Deleted '.$results[$store->getId()]['loops'].' looping redirection(s).')
180
  );
181
 
182
  if(!empty($results[$store->getId()]['limitation']))
183
  $this->_getSession()->addSuccess(
184
+ Mage::helper('zero1_seo_redirects')->__($pad.$results[$store->getId()]['limitation'])
185
  );
186
  }
187
 
188
  $this->_redirect('*/*/index');
189
  }
190
+
191
+ /**
192
+ * Export grid to CSV format
193
+ */
194
+ public function exportCsvAction()
195
+ {
196
+ /* @var $grid Zero1_Seoredirects_Block_Adminhtml_Manage_Grid */
197
+ $fileName = 'zero1_seo_redirects.csv';
198
+ $grid = $this->getLayout()->createBlock('zero1_seo_redirects/adminhtml_manage_grid');
199
+ $this->_prepareDownloadResponse($fileName, $grid->getCsvFile());
200
+ }
201
  }
app/code/community/Zero1/Seoredirects/etc/adminhtml.xml CHANGED
@@ -3,16 +3,21 @@
3
  <menu>
4
  <catalog>
5
  <children>
6
- <seoredirects translate="title" module="seoredirects">
7
  <title>SEO Redirects</title>
8
  <sort_order>60</sort_order>
9
  <!-- action>adminhtml/seoredirects/</action -->
10
  <children>
11
- <seoredirects_manage translate="title" module="seoredirects">
12
  <title>Manage Redirections</title>
13
  <action>adminhtml/seoredirects_manage/index</action>
14
- <sort_order>0</sort_order>
15
  </seoredirects_manage>
 
 
 
 
 
16
  </children>
17
  </seoredirects>
18
  </children>
@@ -27,7 +32,7 @@
27
  <children>
28
  <config>
29
  <children>
30
- <seoredirects translate="title" module="seoredirects">
31
  <title>SEO Redirect</title>
32
  </seoredirects>
33
  </children>
3
  <menu>
4
  <catalog>
5
  <children>
6
+ <seoredirects translate="title" module="zero1_seo_redirects">
7
  <title>SEO Redirects</title>
8
  <sort_order>60</sort_order>
9
  <!-- action>adminhtml/seoredirects/</action -->
10
  <children>
11
+ <seoredirects_manage translate="title" module="zero1_seo_redirects">
12
  <title>Manage Redirections</title>
13
  <action>adminhtml/seoredirects_manage/index</action>
14
+ <sort_order>10</sort_order>
15
  </seoredirects_manage>
16
+ <import translate="title" module="zero1_seo_redirects">
17
+ <title>Import</title>
18
+ <action>adminhtml/seoredirects_import/index</action>
19
+ <sort_order>20</sort_order>
20
+ </import>
21
  </children>
22
  </seoredirects>
23
  </children>
32
  <children>
33
  <config>
34
  <children>
35
+ <seoredirects translate="title" module="zero1_seo_redirects">
36
  <title>SEO Redirect</title>
37
  </seoredirects>
38
  </children>
app/code/community/Zero1/Seoredirects/etc/config.xml CHANGED
@@ -2,47 +2,49 @@
2
  <config>
3
  <modules>
4
  <Zero1_Seoredirects>
5
- <version>1.0.17</version>
6
  </Zero1_Seoredirects>
7
  </modules>
8
 
9
  <global>
10
- <models>
11
- <seoredirects>
12
  <class>Zero1_Seoredirects_Model</class>
13
- <resourceModel>seoredirects_resource</resourceModel>
14
- </seoredirects>
15
 
16
- <seoredirects_resource>
17
  <class>Zero1_Seoredirects_Model_Resource</class>
18
- <deprecatedNode>seoredirects_mysql4</deprecatedNode>
19
  <entities>
20
  <redirection>
21
  <table>zero1_seoredirects_redirection</table>
22
  </redirection>
 
 
 
23
  </entities>
24
- </seoredirects_resource>
25
  </models>
26
 
27
- <resources>
28
- <seoredirects_setup>
29
  <setup>
30
  <module>Zero1_Seoredirects</module>
31
- <!-- <class>Mage_Eav_Model_Entity_Setup</class> -->
32
  </setup>
33
- </seoredirects_setup>
34
  </resources>
35
 
36
  <blocks>
37
- <seoredirects>
38
  <class>Zero1_Seoredirects_Block</class>
39
- </seoredirects>
40
  </blocks>
41
 
42
  <helpers>
43
- <seoredirects>
44
  <class>Zero1_Seoredirects_Helper</class>
45
- </seoredirects>
46
  </helpers>
47
  </global>
48
 
@@ -69,7 +71,7 @@
69
  </Zero1_Seoredirects_Model_Observer>
70
  </observers>
71
  </controller_front_send_response_before>
72
-
73
  <controller_front_send_response_after>
74
  <observers>
75
  <Zero1_Seoredirects_Model_Observer>
@@ -86,23 +88,12 @@
86
  <layout>
87
  <updates>
88
  <seoredirects>
89
- <file>seoredirects.xml</file>
90
  </seoredirects>
91
  </updates>
92
  </layout>
93
  </adminhtml>
94
 
95
- <default>
96
- <seoredirects>
97
- <settings>
98
- <enabled>0</enabled>
99
- <url></url>
100
- <strip_domain>1</strip_domain>
101
- <strip_slash>1</strip_slash>
102
- </settings>
103
- </seoredirects>
104
- </default>
105
-
106
  <crontab>
107
  <jobs>
108
  <seoredirects>
@@ -110,9 +101,17 @@
110
  <cron_expr>0 2 * * *</cron_expr>
111
  </schedule>
112
  <run>
113
- <model>seoredirects/observer::updateRedirectionsCronJob</model>
114
  </run>
115
  </seoredirects>
116
  </jobs>
117
  </crontab>
 
 
 
 
 
 
 
 
118
  </config>
2
  <config>
3
  <modules>
4
  <Zero1_Seoredirects>
5
+ <version>1.1.1</version>
6
  </Zero1_Seoredirects>
7
  </modules>
8
 
9
  <global>
10
+ <models>
11
+ <zero1_seo_redirects>
12
  <class>Zero1_Seoredirects_Model</class>
13
+ <resourceModel>zero1_seo_redirects_resource</resourceModel>
14
+ </zero1_seo_redirects>
15
 
16
+ <zero1_seo_redirects_resource>
17
  <class>Zero1_Seoredirects_Model_Resource</class>
 
18
  <entities>
19
  <redirection>
20
  <table>zero1_seoredirects_redirection</table>
21
  </redirection>
22
+ <redirection_cache>
23
+ <table>zero1_seoredirects_redirection_cache</table>
24
+ </redirection_cache>
25
  </entities>
26
+ </zero1_seo_redirects_resource>
27
  </models>
28
 
29
+ <resources>
30
+ <zero1_seoredirects_setup>
31
  <setup>
32
  <module>Zero1_Seoredirects</module>
33
+ <class>Mage_Eav_Model_Entity_Setup</class>
34
  </setup>
35
+ </zero1_seoredirects_setup>
36
  </resources>
37
 
38
  <blocks>
39
+ <zero1_seo_redirects>
40
  <class>Zero1_Seoredirects_Block</class>
41
+ </zero1_seo_redirects>
42
  </blocks>
43
 
44
  <helpers>
45
+ <zero1_seo_redirects>
46
  <class>Zero1_Seoredirects_Helper</class>
47
+ </zero1_seo_redirects>
48
  </helpers>
49
  </global>
50
 
71
  </Zero1_Seoredirects_Model_Observer>
72
  </observers>
73
  </controller_front_send_response_before>
74
+
75
  <controller_front_send_response_after>
76
  <observers>
77
  <Zero1_Seoredirects_Model_Observer>
88
  <layout>
89
  <updates>
90
  <seoredirects>
91
+ <file>zero1/seoredirects.xml</file>
92
  </seoredirects>
93
  </updates>
94
  </layout>
95
  </adminhtml>
96
 
 
 
 
 
 
 
 
 
 
 
 
97
  <crontab>
98
  <jobs>
99
  <seoredirects>
101
  <cron_expr>0 2 * * *</cron_expr>
102
  </schedule>
103
  <run>
104
+ <model>zero1_seo_redirects/observer::cronImport</model>
105
  </run>
106
  </seoredirects>
107
  </jobs>
108
  </crontab>
109
+
110
+ <default>
111
+ <seoredirects>
112
+ <advanced_settings>
113
+ <import_log_level>5</import_log_level>
114
+ </advanced_settings>
115
+ </seoredirects>
116
+ </default>
117
  </config>
app/code/community/Zero1/Seoredirects/etc/system.xml CHANGED
@@ -1,17 +1,18 @@
1
  <?xml version="1.0"?>
2
  <config>
3
  <sections>
4
- <seoredirects translate="label" module="seoredirects">
5
- <label>SEO Redirect</label>
6
  <tab>catalog</tab>
7
  <sort_order>990</sort_order>
8
  <show_in_default>1</show_in_default>
9
  <show_in_website>1</show_in_website>
10
  <show_in_store>1</show_in_store>
 
11
  <groups>
12
  <settings translate="label">
13
- <label>SEO Redirect Settings</label>
14
- <sort_order>1</sort_order>
15
  <show_in_default>1</show_in_default>
16
  <show_in_website>1</show_in_website>
17
  <show_in_store>1</show_in_store>
@@ -25,61 +26,182 @@
25
  <show_in_website>1</show_in_website>
26
  <show_in_store>1</show_in_store>
27
  </enabled>
28
-
 
 
 
 
 
 
 
 
 
 
29
  <url translate="label">
30
  <label>Google Docs URL</label>
31
  <frontend_type>text</frontend_type>
32
- <sort_order>1</sort_order>
33
  <show_in_default>1</show_in_default>
34
  <show_in_website>1</show_in_website>
35
  <show_in_store>1</show_in_store>
36
  <comment><![CDATA[The above document will be downloaded and parsed into Magento at 2am every morning]]></comment>
 
37
  </url>
38
 
39
- <file translate="label">
40
- <label>File to import</label>
41
  <frontend_type>select</frontend_type>
42
- <source_model>seoredirects/source_files</source_model>
43
- <sort_order>2</sort_order>
 
 
 
 
 
 
 
 
 
 
 
44
  <show_in_default>1</show_in_default>
45
  <show_in_website>1</show_in_website>
46
  <show_in_store>1</show_in_store>
47
- <comment><![CDATA[The above document from "var/seoredirects/import" will be parsed into Magento at 2am every morning]]></comment>
48
- </file>
 
49
 
50
  <serial translate="label">
51
  <label>Serial</label>
52
  <frontend_type>textarea</frontend_type>
53
- <sort_order>3</sort_order>
54
  <show_in_default>1</show_in_default>
55
- <show_in_website>1</show_in_website>
56
  <show_in_store>0</show_in_store>
57
  <comment><![CDATA[Visit <a href="http://www.zero1.co.uk/" target="_blank">http://www.zero1.co.uk</a> if you require a serial.]]></comment>
58
  </serial>
59
-
60
- <strip_domain translate="label">
61
- <label>Strip Domain</label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  <frontend_type>select</frontend_type>
63
  <source_model>adminhtml/system_config_source_yesno</source_model>
64
- <sort_order>4</sort_order>
65
  <show_in_default>1</show_in_default>
66
  <show_in_website>1</show_in_website>
67
  <show_in_store>1</show_in_store>
68
- <comment><![CDATA[Removes domain from imported URLs]]></comment>
69
- </strip_domain>
70
-
71
- <strip_slash translate="label">
72
- <label>Strip Slash</label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  <frontend_type>select</frontend_type>
74
  <source_model>adminhtml/system_config_source_yesno</source_model>
75
- <sort_order>5</sort_order>
76
  <show_in_default>1</show_in_default>
77
  <show_in_website>1</show_in_website>
78
  <show_in_store>1</show_in_store>
79
- <comment><![CDATA[Removes "/" from the start of imported URLs]]></comment>
80
- </strip_slash>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  </fields>
82
- </settings>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  </groups>
84
  </seoredirects>
85
  </sections>
1
  <?xml version="1.0"?>
2
  <config>
3
  <sections>
4
+ <seoredirects translate="label" module="zero1_seo_redirects">
5
+ <label>SEO Redirects</label>
6
  <tab>catalog</tab>
7
  <sort_order>990</sort_order>
8
  <show_in_default>1</show_in_default>
9
  <show_in_website>1</show_in_website>
10
  <show_in_store>1</show_in_store>
11
+ <frontend_model>zero1_seo_redirects/adminhtml_system_config_form</frontend_model>
12
  <groups>
13
  <settings translate="label">
14
+ <label>General Settings</label>
15
+ <sort_order>10</sort_order>
16
  <show_in_default>1</show_in_default>
17
  <show_in_website>1</show_in_website>
18
  <show_in_store>1</show_in_store>
26
  <show_in_website>1</show_in_website>
27
  <show_in_store>1</show_in_store>
28
  </enabled>
29
+
30
+ <use_google_docs traslate="label">
31
+ <label>Use Google Doc</label>
32
+ <frontend_type>select</frontend_type>
33
+ <source_model>adminhtml/system_config_source_yesno</source_model>
34
+ <sort_order>10</sort_order>
35
+ <show_in_default>1</show_in_default>
36
+ <show_in_website>1</show_in_website>
37
+ <show_in_store>1</show_in_store>
38
+ </use_google_docs>
39
+
40
  <url translate="label">
41
  <label>Google Docs URL</label>
42
  <frontend_type>text</frontend_type>
43
+ <sort_order>11</sort_order>
44
  <show_in_default>1</show_in_default>
45
  <show_in_website>1</show_in_website>
46
  <show_in_store>1</show_in_store>
47
  <comment><![CDATA[The above document will be downloaded and parsed into Magento at 2am every morning]]></comment>
48
+ <depends><use_google_docs>1</use_google_docs></depends>
49
  </url>
50
 
51
+ <use_local_file translate="label">
52
+ <label>Use local file</label>
53
  <frontend_type>select</frontend_type>
54
+ <source_model>adminhtml/system_config_source_yesno</source_model>
55
+ <sort_order>20</sort_order>
56
+ <show_in_default>1</show_in_default>
57
+ <show_in_website>1</show_in_website>
58
+ <show_in_store>1</show_in_store>
59
+ </use_local_file>
60
+
61
+ <local_file translate="label">
62
+ <label>File to import</label>
63
+ <frontend_type>zero1_seo_redirects_file</frontend_type>
64
+ <frontend_model>zero1_seo_redirects/adminhtml_system_config_form_field</frontend_model>
65
+ <backend_model>zero1_seo_redirects/adminhtml_system_config_backend_file</backend_model>
66
+ <sort_order>22</sort_order>
67
  <show_in_default>1</show_in_default>
68
  <show_in_website>1</show_in_website>
69
  <show_in_store>1</show_in_store>
70
+ <depends><use_local_file>1</use_local_file></depends>
71
+ <comment>The above file will be parsed into Magento at 2am every morning</comment>
72
+ </local_file>
73
 
74
  <serial translate="label">
75
  <label>Serial</label>
76
  <frontend_type>textarea</frontend_type>
77
+ <sort_order>30</sort_order>
78
  <show_in_default>1</show_in_default>
79
+ <show_in_website>0</show_in_website>
80
  <show_in_store>0</show_in_store>
81
  <comment><![CDATA[Visit <a href="http://www.zero1.co.uk/" target="_blank">http://www.zero1.co.uk</a> if you require a serial.]]></comment>
82
  </serial>
83
+ </fields>
84
+ </settings>
85
+ <redirection_settings translate="label">
86
+ <label>Redirection Settings</label>
87
+ <frontend_type>text</frontend_type>
88
+ <sort_order>20</sort_order>
89
+ <show_in_default>1</show_in_default>
90
+ <show_in_website>1</show_in_website>
91
+ <show_in_store>1</show_in_store>
92
+ <fields>
93
+ <params translate="label">
94
+ <label>Auto Remove Query Params</label>
95
+ <frontend_type>select</frontend_type>
96
+ <frontend_model>zero1_seo_redirects/adminhtml_settings_params</frontend_model>
97
+ <backend_model>adminhtml/system_config_backend_serialized</backend_model>
98
+ <sort_order>0</sort_order>
99
+ <show_in_default>1</show_in_default>
100
+ <show_in_website>1</show_in_website>
101
+ <show_in_store>1</show_in_store>
102
+ <comment>When checking URLs these parameters will automatically be stripped from the query string.</comment>
103
+ </params>
104
+ </fields>
105
+ </redirection_settings>
106
+ <advanced_settings>
107
+ <label>Advanced Settings</label>
108
+ <sort_order>30</sort_order>
109
+ <show_in_default>1</show_in_default>
110
+ <show_in_website>1</show_in_website>
111
+ <show_in_store>1</show_in_store>
112
+ <fields>
113
+ <log_404s traslate="label">
114
+ <label>Log 404's</label>
115
  <frontend_type>select</frontend_type>
116
  <source_model>adminhtml/system_config_source_yesno</source_model>
117
+ <sort_order>10</sort_order>
118
  <show_in_default>1</show_in_default>
119
  <show_in_website>1</show_in_website>
120
  <show_in_store>1</show_in_store>
121
+ </log_404s>
122
+ <log_404s_limit>
123
+ <label>Limit number of 404's logged</label>
124
+ <frontend_type>text</frontend_type>
125
+ <backend_model>zero1_seo_redirects/adminhtml_system_config_backend_number</backend_model>
126
+ <sort_order>11</sort_order>
127
+ <show_in_default>1</show_in_default>
128
+ <show_in_website>1</show_in_website>
129
+ <show_in_store>1</show_in_store>
130
+ <depends><log_404s>1</log_404s></depends>
131
+ <comment>0 for unlimited, though not recommended</comment>
132
+ </log_404s_limit>
133
+ <import_log_level traslate="label">
134
+ <label>Import Log Level</label>
135
+ <frontend_type>select</frontend_type>
136
+ <source_model>zero1_seo_redirects/adminhtml_system_config_source_logLevels</source_model>
137
+ <sort_order>12</sort_order>
138
+ <show_in_default>1</show_in_default>
139
+ <show_in_website>1</show_in_website>
140
+ <show_in_store>1</show_in_store>
141
+ <comment><![CDATA[How much information should be displayed after running an import]]></comment>
142
+ </import_log_level>
143
+ <enable_reporting traslate="label">
144
+ <label>Enable reporting</label>
145
  <frontend_type>select</frontend_type>
146
  <source_model>adminhtml/system_config_source_yesno</source_model>
147
+ <sort_order>13</sort_order>
148
  <show_in_default>1</show_in_default>
149
  <show_in_website>1</show_in_website>
150
  <show_in_store>1</show_in_store>
151
+ <comment><![CDATA[Enable this to be sent a report after the scheduled import has ran.]]></comment>
152
+ </enable_reporting>
153
+ <email_addresses>
154
+ <label>Email</label>
155
+ <frontend_type>text</frontend_type>
156
+ <sort_order>14</sort_order>
157
+ <show_in_default>1</show_in_default>
158
+ <show_in_website>1</show_in_website>
159
+ <show_in_store>1</show_in_store>
160
+ <depends><enable_reporting>1</enable_reporting></depends>
161
+ <comment>Comma seperated list</comment>
162
+ </email_addresses>
163
+ <after_manual_import>
164
+ <label>Report after a manual import</label>
165
+ <frontend_type>select</frontend_type>
166
+ <source_model>adminhtml/system_config_source_yesno</source_model>
167
+ <sort_order>15</sort_order>
168
+ <show_in_default>1</show_in_default>
169
+ <show_in_website>1</show_in_website>
170
+ <show_in_store>1</show_in_store>
171
+ <depends><enable_reporting>1</enable_reporting></depends>
172
+ <comment><![CDATA[Enable this to be sent a report after a manual import has ran.]]></comment>
173
+ </after_manual_import>
174
  </fields>
175
+ </advanced_settings>
176
+ <debug_settings>
177
+ <label>Debug Settings</label>
178
+ <sort_order>40</sort_order>
179
+ <show_in_default>1</show_in_default>
180
+ <show_in_website>1</show_in_website>
181
+ <show_in_store>1</show_in_store>
182
+ <fields>
183
+ <enable_debug traslate="label">
184
+ <label>Enable Debug</label>
185
+ <frontend_type>select</frontend_type>
186
+ <source_model>adminhtml/system_config_source_yesno</source_model>
187
+ <sort_order>10</sort_order>
188
+ <show_in_default>1</show_in_default>
189
+ <show_in_website>1</show_in_website>
190
+ <show_in_store>1</show_in_store>
191
+ <comment><![CDATA[Enable debug mode for select IPs.]]></comment>
192
+ </enable_debug>
193
+ <debug_ips>
194
+ <label>IP Addresses</label>
195
+ <frontend_type>text</frontend_type>
196
+ <sort_order>20</sort_order>
197
+ <show_in_default>1</show_in_default>
198
+ <show_in_website>1</show_in_website>
199
+ <show_in_store>1</show_in_store>
200
+ <depends><enable_debug>1</enable_debug></depends>
201
+ <comment>Comma seperated list, blank for all</comment>
202
+ </debug_ips>
203
+ </fields>
204
+ </debug_settings>
205
  </groups>
206
  </seoredirects>
207
  </sections>
app/code/community/Zero1/Seoredirects/sql/seoredirects_setup/install-1.0.0.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
- $installer = $this;
3
-
4
- $installer->startSetup();
5
-
6
- $installer->run("
7
-
8
- DROP TABLE IF EXISTS {$this->getTable('zero1_seoredirects_redirection')};
9
- CREATE TABLE {$this->getTable('zero1_seoredirects_redirection')} (
10
- `entity_id` int(11) unsigned NOT NULL auto_increment,
11
- `redirect_from` varchar(2047) NOT NULL,
12
- `redirect_to` varchar(2047) NOT NULL,
13
- `store` int(4) NOT NULL,
14
- PRIMARY KEY (`entity_id`)
15
- ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
16
-
17
- ");
18
-
19
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Zero1/Seoredirects/sql/seoredirects_setup/install-1.0.1.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
- $installer = $this;
3
-
4
- $installer->startSetup();
5
-
6
- $installer->run("
7
-
8
- DROP TABLE IF EXISTS {$this->getTable('zero1_seoredirects_redirection')};
9
- CREATE TABLE {$this->getTable('zero1_seoredirects_redirection')} (
10
- `entity_id` int(11) unsigned NOT NULL auto_increment,
11
- `redirect_from` varchar(2047) NOT NULL,
12
- `redirect_to` varchar(2047) NOT NULL,
13
- `store` int(4) NOT NULL,
14
- PRIMARY KEY (`entity_id`)
15
- ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
16
-
17
- ");
18
-
19
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Zero1/Seoredirects/sql/seoredirects_setup/mysql4-install-1.0.0.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
- $installer = $this;
3
-
4
- $installer->startSetup();
5
-
6
- $installer->run("
7
-
8
- DROP TABLE IF EXISTS {$this->getTable('zero1_seoredirects_redirection')};
9
- CREATE TABLE {$this->getTable('zero1_seoredirects_redirection')} (
10
- `entity_id` int(11) unsigned NOT NULL auto_increment,
11
- `redirect_from` varchar(2047) NOT NULL,
12
- `redirect_to` varchar(2047) NOT NULL,
13
- `store` int(4) NOT NULL,
14
- PRIMARY KEY (`entity_id`)
15
- ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
16
-
17
- ");
18
-
19
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Zero1/Seoredirects/sql/seoredirects_setup/mysql4-install-1.0.1.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
- $installer = $this;
3
-
4
- $installer->startSetup();
5
-
6
- $installer->run("
7
-
8
- DROP TABLE IF EXISTS {$this->getTable('zero1_seoredirects_redirection')};
9
- CREATE TABLE {$this->getTable('zero1_seoredirects_redirection')} (
10
- `entity_id` int(11) unsigned NOT NULL auto_increment,
11
- `redirect_from` varchar(2047) NOT NULL,
12
- `redirect_to` varchar(2047) NOT NULL,
13
- `store` int(4) NOT NULL,
14
- PRIMARY KEY (`entity_id`)
15
- ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
16
-
17
- ");
18
-
19
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Zero1/Seoredirects/sql/zero1_seoredirects_setup/install-1.1.0.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+ $installer->startSetup();
4
+
5
+ // Clean up old table
6
+ $installer->run("DROP TABLE IF EXISTS {$installer->getTable('zero1_seo_redirects/redirection')};");
7
+
8
+ /**
9
+ * Create table 'zero1_seoredirects/redirection'
10
+ */
11
+ $table = $installer->getConnection()
12
+ ->newTable($installer->getTable('zero1_seo_redirects/redirection'))
13
+ ->addColumn('redirection_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
14
+ 'identity' => true,
15
+ 'unsigned' => true,
16
+ 'nullable' => false,
17
+ 'primary' => true,
18
+ ), 'Redirection Id')
19
+ ->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
20
+ 'unsigned' => true,
21
+ 'nullable' => false,
22
+ 'primary' => true,
23
+ 'default' => '0',
24
+ ), 'Store Id')
25
+
26
+ ->addColumn('from_url', Varien_Db_Ddl_Table::TYPE_TEXT, null, array(
27
+ 'nullable' => false,
28
+ ), 'From URL')
29
+
30
+ ->addColumn('to_url', Varien_Db_Ddl_Table::TYPE_TEXT, null, array(
31
+ 'nullable' => false,
32
+ ), 'To URL')
33
+
34
+ ->addIndex($installer->getIdxName('zero1_seo_redirects/redirection', array('redirection_id')),
35
+ array('redirection_id'))
36
+ ->addIndex($installer->getIdxName('zero1_seo_redirects/redirection', array('store_id')),
37
+ array('store_id'))
38
+ ->addForeignKey($installer->getFkName('zero1_seo_redirects/redirection', 'store_id', 'core/store', 'store_id'),
39
+ 'store_id', $installer->getTable('core/store'), 'store_id',
40
+ Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
41
+ ->setComment('Zero1 Seoredirects Redirection');
42
+
43
+ $installer->getConnection()->createTable($table);
44
+
45
+ $installer->endSetup();
app/code/community/Zero1/Seoredirects/sql/zero1_seoredirects_setup/upgrade-1.1.0-1.1.1.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $installer Mage_Eav_Model_Entity_Setup */
3
+ $installer = $this;
4
+ $table = $installer->getTable('zero1_seo_redirects/redirection');
5
+ $installer->getConnection()->addColumn($table,
6
+ 'from_type', array(
7
+ 'type' => Varien_Db_Ddl_Table::TYPE_SMALLINT,
8
+ 'unsigned' => true,
9
+ 'nullable' => false,
10
+ 'default' => '0',
11
+ 'comment' => 'The status of this redirection'
12
+ )
13
+ );
14
+ $installer->getConnection()->addColumn($table,
15
+ 'persist_query', array(
16
+ 'type' => Varien_Db_Ddl_Table::TYPE_SMALLINT,
17
+ 'unsigned' => true,
18
+ 'nullable' => false,
19
+ 'default' => '0',
20
+ 'comment' => 'Flag for persisting query through to to_url'
21
+ )
22
+ );
23
+ $installer->getConnection()->addColumn($table,
24
+ 'source', array(
25
+ 'type' => Varien_Db_Ddl_Table::TYPE_SMALLINT,
26
+ 'unsigned' => true,
27
+ 'nullable' => false,
28
+ 'default' => '0',
29
+ 'comment' => 'Source of redirect, import, logged or manual'
30
+ )
31
+ );
32
+ $installer->getConnection()->addColumn($table,
33
+ 'hits', array(
34
+ 'type' => Varien_Db_Ddl_Table::TYPE_BIGINT,
35
+ 'unsigned' => true,
36
+ 'nullable' => false,
37
+ 'default' => '0',
38
+ 'comment' => 'The number of times this redirect has been used'
39
+ )
40
+ );
41
+ $installer->getConnection()->addColumn($table,
42
+ 'status', array(
43
+ 'type' => Varien_Db_Ddl_Table::TYPE_SMALLINT,
44
+ 'unsigned' => true,
45
+ 'nullable' => false,
46
+ 'default' => '0',
47
+ 'comment' => 'The status of this redirection'
48
+ )
49
+ );
50
+ $installer->getConnection()->dropColumn($table, 'from_url');
51
+ $installer->getConnection()->addColumn($table,
52
+ 'from_url_path', array(
53
+ 'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
54
+ 'nullable' => false,
55
+ 'comment' => 'From URL path'
56
+ )
57
+ );
58
+ $installer->getConnection()->addColumn($table,
59
+ 'from_url_query', array(
60
+ 'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
61
+ 'nullable' => false,
62
+ 'comment' => 'From URL query',
63
+ 'default' => '',
64
+ )
65
+ );
66
+
67
+ /**
68
+ * Create table 'zero1_seoredirects/redirection_cache'
69
+ */
70
+ $installer->run("DROP TABLE IF EXISTS {$installer->getTable('zero1_seo_redirects/redirection_cache')};");
71
+ $table = $installer->getConnection()
72
+ ->newTable($installer->getTable('zero1_seo_redirects/redirection_cache'))
73
+ ->addColumn('redirection_cache_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
74
+ 'identity' => true,
75
+ 'unsigned' => true,
76
+ 'nullable' => false,
77
+ 'primary' => true,
78
+ ), 'Redirection Cache Id')
79
+ ->addColumn('redirection_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
80
+ 'unsigned' => true,
81
+ 'nullable' => false,
82
+ ), 'Related redirection id')
83
+ ->addColumn('from_url', Varien_Db_Ddl_Table::TYPE_TEXT, null, array(
84
+ 'nullable' => false,
85
+ ), 'From URL')
86
+ ->addColumn('to_url', Varien_Db_Ddl_Table::TYPE_TEXT, null, array(
87
+ 'nullable' => true,
88
+ ), 'To URL')
89
+
90
+ ->addIndex($installer->getIdxName('zero1_seo_redirects/redirection_cache', array('redirection_cache_id')),
91
+ array('redirection_id'))
92
+ ->addForeignKey(
93
+ $installer->getFkName('zero1_seo_redirects/redirection_cache', 'redirection_id', 'zero1_seo_redirects/redirection', 'redirection_id'),
94
+ 'redirection_id',
95
+ $installer->getTable('zero1_seo_redirects/redirection'),
96
+ 'redirection_id',
97
+ Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_NO_ACTION)
98
+ ->setComment('Zero1 Redirection Cache');
99
+
100
+ $installer->getConnection()->createTable($table);
101
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/seoredirects.xml DELETED
@@ -1,13 +0,0 @@
1
- <?xml version="1.0"?>
2
- <layout>
3
- <adminhtml_seoredirects_manage_index>
4
- <reference name="content">
5
- <!--
6
- <block type="adminhtml/store_switcher" name="store_switcher" as="store_switcher">
7
- <action method="setUseConfirm"><params>0</params></action>
8
- </block>
9
- -->
10
- <block type="seoredirects/manage" name="seoredirects_manage"></block>
11
- </reference>
12
- </adminhtml_seoredirects_manage_index>
13
- </layout>
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/layout/zero1/seoredirects.xml ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+ <adminhtml_seoredirects_manage_index>
4
+ <reference name="content">
5
+ <block type="zero1_seo_redirects/adminhtml_manage" name="seoredirects_manage">
6
+ <block type="adminhtml/store_switcher" name="store_switcher" as="store_switcher">
7
+ <action method="setUseConfirm"><params>0</params></action>
8
+ </block>
9
+ <block type="zero1_seo_redirects/adminhtml_manage_report" name="seoredirects_report" />
10
+ </block>
11
+ </reference>
12
+ </adminhtml_seoredirects_manage_index>
13
+
14
+ <adminhtml_seoredirects_manage_grid>
15
+ <update handle="formkey"/>
16
+ <block type="zero1_seo_redirects/adminhtml_manage_grid" name="seoredirects_manage.ajax" output="toHtml"/>
17
+ </adminhtml_seoredirects_manage_grid>
18
+
19
+ <adminhtml_seoredirects_export_index>
20
+ <reference name="content">
21
+ <block type="zero1_seo_redirects/adminhtml_export" name="seoredirects_export">
22
+ </block>
23
+ </reference>
24
+ </adminhtml_seoredirects_export_index>
25
+
26
+ <adminhtml_seoredirects_manage_edit>
27
+ <reference name="content">
28
+ <block type="zero1_seo_redirects/adminhtml_edit" name="seoredirects_edit" />
29
+ </reference>
30
+ </adminhtml_seoredirects_manage_edit>
31
+
32
+ <adminhtml_seoredirects_import_index>
33
+ <reference name="content">
34
+ <block type="zero1_seo_redirects/adminhtml_import" name="seo_redirects_import" />
35
+ </reference>
36
+ </adminhtml_seoredirects_import_index>
37
+ </layout>
app/design/adminhtml/default/default/template/zero1/seoredirects/edit.phtml ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category design
22
+ * @package default_default
23
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+
27
+ /**
28
+ * SEO Redirects edit container
29
+ *
30
+ * @see Zero1_Seoredirects_Block_Edit
31
+ */
32
+ ?>
33
+ <div class="content-header">
34
+ <?php echo $this->getHeaderHtml() ?>
35
+ <p class="content-buttons form-buttons"><?php echo $this->getButtonsHtml() ?></p>
36
+ </div>
37
+
38
+ <?php echo $this->getChildHtml() ?>
39
+
40
+ <?php if ($this->getChild('form')): ?>
41
+ <script type="text/javascript">
42
+ var editForm = new varienForm('edit_form', '<?php echo $this->getValidationUrl() ?>');
43
+ </script>
44
+ <?php endif; ?>
app/design/adminhtml/default/default/template/zero1/seoredirects/import/container.phtml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ?>
3
+ <div class="content-header">
4
+ <table cellspacing="0">
5
+ <tr>
6
+ <td style="<?php echo $this->getHeaderWidth() ?>"><?php echo $this->getHeaderHtml() ?></td>
7
+ <td class="form-buttons"><?php echo $this->getButtonsHtml() ?></td>
8
+ </tr>
9
+ </table>
10
+ </div>
11
+ <div id="report-container"></div>
app/design/adminhtml/default/default/template/zero1/seoredirects/import/report.phtml ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Zero1_Seoredirects_Block_Adminhtml_Import_Report */
3
+ $logData = $this->getLogData();
4
+ if(empty($logData)){
5
+ echo 'Nothing to import';
6
+ return;
7
+ }
8
+ //add row counts to log data, so we can add to table
9
+ $websiteOrder = array();
10
+ foreach($logData as $websiteCode => $websiteData){
11
+ if($websiteCode !== 'default'){
12
+ $websiteOrder[Mage::app()->getWebsite($websiteCode)->getId()] = $websiteCode;
13
+ }
14
+ }
15
+ ksort($websiteOrder);
16
+ if(isset($logData['default'])){
17
+ array_unshift($websiteOrder, 'default');
18
+ }
19
+ foreach($websiteOrder as $websiteCode){
20
+ $logData[$websiteCode]['rowCount'] = 1 + count($logData[$websiteCode]['log']);
21
+ if(isset($logData[$websiteCode]['stores'])){
22
+ foreach($logData[$websiteCode]['stores'] as $storeCode => $storeData){
23
+ $logData[$websiteCode]['rowCount'] += (1 + count($storeData['log']));
24
+ $logData[$websiteCode]['stores'][$storeCode]['rowCount'] = 1 + count($storeData['log']);
25
+ }
26
+ }
27
+ }
28
+
29
+ ?>
30
+ <div class="grid" style="margin-bottom: 50px;">
31
+ <table class="data" cellspacing="0">
32
+ <colgroup>
33
+ <col span="1" style="width: 250px;" />
34
+ <col span="1" style="width: 250px;" />
35
+ <col span="1" />
36
+ <col span="1" style="width: 100px;" />
37
+ <col span="1" style="width: 50px;" />
38
+ </colgroup>
39
+ <thead>
40
+ <tr class="headings">
41
+ <th class="no-link"><span class="nobr"><?php echo Mage::helper('core')->__('Website Name') ?></span></th>
42
+ <th class="no-link"><span class="nobr"><?php echo Mage::helper('core')->__('Store View Name') ?></span></th>
43
+ <th class="no-link"><span class="nobr"><?php echo Mage::helper('core')->__('Message') ?></span></th>
44
+ <th class="no-link"><span class="nobr"><?php echo Mage::helper('core')->__('Severity') ?></span></th>
45
+ <th class="no-link"><span class="nobr"><?php echo Mage::helper('core')->__('Line Number') ?></span></th>
46
+ </tr>
47
+ </thead>
48
+ <tbody>
49
+ <?php foreach($websiteOrder as $websiteCode): ?>
50
+ <?php
51
+ $websiteData = $logData[$websiteCode];
52
+ $website = ($websiteCode == 'default')? Mage::app()->getStore(0) : Mage::app()->getWebsite($websiteCode);
53
+ ?>
54
+
55
+ <tr>
56
+ <td rowspan="<?php echo $websiteData['rowCount']; ?>"><?php echo $website->getName(); ?></td>
57
+ <td rowspan="<?php echo count($websiteData['log']) + 1; ?>">&nbsp;</td>
58
+ </tr>
59
+ <?php foreach($websiteData['log'] as $websiteLogRow): ?>
60
+ <tr style="background-color: <?php echo $this->getSeverityColor($websiteLogRow['severity']); ?>">
61
+ <?php // website col ?>
62
+ <?php // store col ?>
63
+ <td><?php echo $websiteLogRow['message']; ?></td>
64
+ <td><?php echo $this->getSeverityLabel($websiteLogRow['severity']);?></td>
65
+ <td><?php echo $websiteLogRow['line_number']; ?></td>
66
+ </tr>
67
+ <?php endforeach; ?>
68
+ <?php if(isset($websiteData['stores'])): ?>
69
+ <?php foreach($websiteData['stores'] as $storeCode => $storeData): ?>
70
+ <?php $store = Mage::app()->getStore($storeCode); ?>
71
+ <tr>
72
+ <?php //website col ?>
73
+ <td rowspan="<?php echo $storeData['rowCount']; ?>"><?php echo $store->getName();?></td>
74
+ </tr>
75
+ <?php foreach($storeData['log'] as $storeLogRow): ?>
76
+ <tr style="background-color: <?php echo $this->getSeverityColor($storeLogRow['severity']); ?>">
77
+ <?php // website col ?>
78
+ <?php // store col ?>
79
+ <td><?php echo $storeLogRow['message']; ?></td>
80
+ <td><?php echo $this->getSeverityLabel($storeLogRow['severity']);?></td>
81
+ <td><?php echo $storeLogRow['line_number']; ?></td>
82
+ </tr>
83
+ <?php endforeach; ?>
84
+
85
+ <?php endforeach; ?>
86
+ <?php endif; ?>
87
+ <?php endforeach; ?>
88
+ </tbody>
89
+ </table>
90
+ </div>
app/design/adminhtml/default/default/template/zero1/seoredirects/manage.phtml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="content-header">
2
+ <table cellspacing="0">
3
+ <tr>
4
+ <td style="width:50%;"><h3 class="icon-head head-products"><?php echo Mage::helper('catalog')->__('Manage Redirects') ?></h3></td>
5
+ <td class="a-right">
6
+ <?php echo $this->getButtonsHtml() ?>
7
+ </td>
8
+ </tr>
9
+ </table>
10
+ </div>
11
+ <?php echo $this->getChildHtml('seoredirects_report'); ?>
12
+
13
+ <?php if( !$this->isSingleStoreMode() ): ?>
14
+ <?php echo $this->getChildHtml('store_switcher');?>
15
+ <?php endif;?>
16
+ <div>
17
+ <?php echo $this->getGridHtml() ?>
18
+ </div>
app/design/adminhtml/default/default/template/zero1/seoredirects/manage/report.phtml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php /* @var $this Zero1_Seoredirects_Block_Adminhtml_Manage_Report */ ?>
2
+ <?php
3
+ $licenseCounts = $this->getLicenseCounts();
4
+ $licenseLimit = $this->getLicenseLimit();
5
+ ?>
6
+ <style>
7
+ li.seo-redirects-licesnse-limit{
8
+ display: inline;
9
+ margin-left: 50px;
10
+ }
11
+ </style>
12
+ <div class="switcher">
13
+ <h4>License Usage&nbsp;&nbsp;
14
+ <?php if(isset($licenseCounts[0])): ?>
15
+ (Overall: <?php echo $licenseCounts[0]['count']; ?> / <?php echo ($licenseLimit == 0)? 'Unlimited' : $licenseLimit; ?>)
16
+ <?php endif; ?>
17
+ </h4>
18
+ <ul>
19
+
20
+ <?php foreach($licenseCounts as $storeId => $data): ?>
21
+ <?php if($storeId == 0){ continue; } ?>
22
+ <li class="seo-redirects-licesnse-limit"><?php echo $licenseCounts[$storeId]['name']; ?>: <?php echo $licenseCounts[$storeId]['count']; ?></li>
23
+ <?php endforeach; ?>
24
+ </ul>
25
+ </div>
app/etc/modules/Zero1_Seoredirects.xml CHANGED
@@ -1,11 +1,9 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <config>
3
- <modules>
4
- <Zero1_Seoredirects>
5
- <active>true</active>
6
- <codePool>community</codePool>
7
- <depends>
8
- </depends>
9
- </Zero1_Seoredirects>
10
- </modules>
11
- </config>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <config>
3
+ <modules>
4
+ <Zero1_Seoredirects>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Zero1_Seoredirects>
8
+ </modules>
9
+ </config>
 
 
package.xml CHANGED
@@ -1,19 +1,31 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Zero1_Seoredirects</name>
4
- <version>1.0.17</version>
5
  <stability>stable</stability>
6
  <license uri="http://shop.zero1.co.uk/LICENSE.txt">Commercial</license>
7
  <channel>community</channel>
8
  <extends/>
9
- <summary>Manage you SEO redirects using a Google Doc</summary>
10
- <description>Manage you SEO redirects using a Google Doc</description>
11
- <notes>Added file importing from "var/seoredirect/import"&#xD;
12
- </notes>
 
 
 
 
 
 
 
 
 
 
 
 
13
  <authors><author><name>Arron Moss</name><user>zero1limited</user><email>arron.moss@zero1.co.uk</email></author></authors>
14
- <date>2013-06-25</date>
15
- <time>12:15:08</time>
16
- <contents><target name="magecommunity"><dir name="Zero1"><dir name="Seoredirects"><dir name="Block"><dir name="Manage"><file name="Grid.php" hash="b06399e81b30ef592805277595061b38"/></dir><file name="Manage.php" hash="e891c9539563a551ceb65601532ed402"/></dir><dir name="Helper"><file name="Data.php" hash="36474aca2c8e7dce3f30c398bd9c0ce0"/><file name="License.php" hash="479affaec1ba20aa6b916dec4e055b4b"/></dir><dir name="Model"><dir name="Mysql4"><dir name="Redirection"><file name="Collection.php" hash="a848d959fdca977b4470f46c93a27eb7"/></dir><file name="Redirection.php" hash="a357992dee4bb6cf526bb358dc4d1e0d"/></dir><file name="Observer.php" hash="6d7b2a20b22b10094216c1d1e1085268"/><file name="Redirection.php" hash="8d26f395bf5b33679b032c160152e24a"/><dir name="Resource"><dir name="Redirection"><file name="Collection.php" hash="107e0dab442d292a426e2ac635f8e4fd"/></dir><file name="Redirection.php" hash="dc53fa0fec1044e9f09a0d7815bcc32d"/></dir><dir name="Source"><file name="Files.php" hash="b797b3fe23d3e10217440bd45d5d55e4"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Seoredirects"><file name="ManageController.php" hash="bf497a1ce5f202abd024a5736a0e8a9a"/></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="7e8d3a4c8dff9b4df9f380c284225393"/><file name="config.xml" hash="c4e2d8e29d4c1ab25ea990df0e5b4759"/><file name="system.xml" hash="d2d19029c76339de9786b333702c0a97"/></dir><dir name="sql"><dir name="seoredirects_setup"><file name="install-1.0.0.php" hash="918bc1dee6bb2388e78b7346929916c9"/><file name="install-1.0.1.php" hash="918bc1dee6bb2388e78b7346929916c9"/><file name="mysql4-install-1.0.0.php" hash="918bc1dee6bb2388e78b7346929916c9"/><file name="mysql4-install-1.0.1.php" hash="918bc1dee6bb2388e78b7346929916c9"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Zero1_Seoredirects.xml" hash="dd176346dbb2abf0e20d8ea087abe2ce"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="seoredirects.xml" hash="84e2381a4d12eb22fa5e6b5b092ddef7"/></dir></dir></dir></dir></target></contents>
17
  <compatible/>
18
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
19
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Zero1_Seoredirects</name>
4
+ <version>1.1.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://shop.zero1.co.uk/LICENSE.txt">Commercial</license>
7
  <channel>community</channel>
8
  <extends/>
9
+ <summary>Manage you SEO redirects using a Google Doc or and Uploaded File.</summary>
10
+ <description>Manage you SEO redirects using a Google Doc or and Uploaded File.</description>
11
+ <notes>Upgrade from 1.0.X&#xD;
12
+ - Add From Types&#xD;
13
+ - Added the ability to persist query&#xD;
14
+ - Add the ability to automatically ignore query variables&#xD;
15
+ - Reworked import process.&#xD;
16
+ - Add the ability to log 404s automatically&#xD;
17
+ - Made the redirect key global&#xD;
18
+ - Import files are now locked to store scope.&#xD;
19
+ - Added redirection summary to view page.&#xD;
20
+ - Added reporting options&#xD;
21
+ - Added url caching feature, to improve performance.&#xD;
22
+ - Added the ability to import a google doc as HTML or CSV&#xD;
23
+ - Added the ability to manage redirects from a gid page (add, edit, delete, mass delete, export)&#xD;
24
+ - Added Hit counter.</notes>
25
  <authors><author><name>Arron Moss</name><user>zero1limited</user><email>arron.moss@zero1.co.uk</email></author></authors>
26
+ <date>2015-04-09</date>
27
+ <time>10:19:39</time>
28
+ <contents><target name="magecommunity"><dir name="Zero1"><dir name="Seoredirects"><dir name="Block"><dir name="Adminhtml"><dir name="Edit"><file name="Form.php" hash="e5c46b2102e4a9af2a563a19ed462b86"/></dir><file name="Edit.php" hash="8e5eb2ce884f2db36842d17ba9e7a9af"/><dir name="Import"><file name="Report.php" hash="0d26c2b8f8fecd8ba4326d2b11cef1f5"/></dir><file name="Import.php" hash="c19209bfcf6c495deb7b8711ec243e04"/><dir name="Manage"><dir name="Grid"><dir name="Renderer"><file name="Options.php" hash="81156ac356044306cf8a11608afe764a"/><file name="Url.php" hash="c4208700f3531082c72dc4efd6b4a4af"/></dir></dir><file name="Grid.php" hash="f2867600450f3fb577735052110c6cf0"/><file name="Report.php" hash="8ea23cee5ff2988cd4894b69f5676359"/></dir><file name="Manage.php" hash="8e019efa0d59c78b405acf7e74b6e7ee"/><dir name="Settings"><file name="Params.php" hash="87ed9af2d9c11c791988544b7a49c404"/></dir><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="File.php" hash="138093538cccbea31434aacb40fbce1e"/></dir><file name="Field.php" hash="23167e787e4c3692dea5c54ad8cc5fa6"/></dir><file name="Form.php" hash="6d3f19bdd5d6bce464f749eacb6b917d"/></dir></dir></dir></dir><file name="Exception.php" hash="bd003aafc41afb3de920e4a4fbb58dc2"/><dir name="Helper"><file name="Data.php" hash="424e5675964cd1287ef50a270ad63e75"/><file name="Files.php" hash="1a34ab122975730bf44ed4d128c590ac"/><file name="Hints.php" hash="2a3fc3984d10c680dd113b4df0cffaaf"/><file name="License.php" hash="eb24338369084cd47fdaea4b30d697c5"/><file name="Urls.php" hash="685e8c0ca20f897905240905a993684b"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><file name="File.php" hash="be9bc739028fa9af06fc45235ba4b551"/><file name="Number.php" hash="e21d15ea0eac997b93ea2de45b0fb777"/></dir><dir name="Source"><file name="LogLevels.php" hash="767d3f90a070e1fccdc3f7349516385f"/></dir></dir></dir></dir><file name="File.php" hash="9ebec42806237689d91a389f82a092d3"/><file name="Importer.php" hash="a3bc257d20f99223dadfae67ae2b0d6d"/><file name="Observer.php" hash="17e1298598834a3b7a784f99e7749447"/><dir name="Redirection"><file name="Cache.php" hash="6bcd1757d36f00c5dff1edacd064cdb3"/></dir><file name="Redirection.php" hash="e1d674a25acabd697191f2412bc6cb8b"/><file name="Redirector.php" hash="694b59ce5f60ad2552b899036dced695"/><dir name="Resource"><dir name="Redirection"><dir name="Cache"><file name="Collection.php" hash="4a5438247157f2262fb6c9ade0ef452d"/></dir><file name="Cache.php" hash="5da3db53f90cc665ec372d471db6ed4a"/><file name="Collection.php" hash="5c4f92128b58ede4c0709f452be0709e"/></dir><file name="Redirection.php" hash="43971cae6be73c8be9af886304dac4b6"/></dir></dir><file name="TODO.txt" hash="cd72a0ba8dd2e9c3bdd7cbacdc5d0a04"/><dir name="controllers"><dir name="Adminhtml"><dir name="Seoredirects"><file name="ConfigController.php" hash="263aee27d04fc1326a5a826ce71e9005"/><file name="ImportController.php" hash="89902a8e4dcdde002d8d8e6f25b11556"/><file name="ManageController.php" hash="ba77329cf88d3566429c20e309399ca4"/></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="f2fdfb040bcf0b0a4a23f4dd7d1eacdd"/><file name="config.xml" hash="b326841b9c3b961321354e5665a07f70"/><file name="system.xml" hash="7fefbdaa8fb4697609bd54945d35bc03"/></dir><dir name="sql"><dir name="zero1_seoredirects_setup"><file name="install-1.1.0.php" hash="b508de10922d332b296bc6a90da2170f"/><file name="upgrade-1.1.0-1.1.1.php" hash="b853472314a81c0914b91af9ff3e7f6e"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Zero1_Seoredirects.xml" hash="7894f7794de7240b9bb65384e846a585"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="zero1"><file name="seoredirects.xml" hash="e6be6b7de008d5fd58c1bdc82ee20111"/></dir></dir><dir name="template"><dir name="zero1"><dir name="seoredirects"><file name="edit.phtml" hash="85c0a991007e22ed6ac859b8a08b6a56"/><dir name="import"><file name="container.phtml" hash="ac15394e738869520e333e96290b3e4f"/><file name="report.phtml" hash="8eb36402e30f7fbf58374d4139423246"/></dir><dir name="manage"><file name="report.phtml" hash="0afdc7ef9471e9fb6d69fc97d9a429ea"/></dir><file name="manage.phtml" hash="618639a7e5bba02c21d189e0add457c6"/></dir></dir></dir></dir></dir></dir></target><target name="mage"><dir name="var"><dir name="Zero1"><dir name="SeoRedirects"><dir name="data"><file name="template.csv" hash="8dcfaf8a9de77b2c479de12f504ce379"/></dir></dir></dir></dir></target></contents>
29
  <compatible/>
30
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
31
  </package>
var/Zero1/SeoRedirects/data/template.csv ADDED
@@ -0,0 +1 @@
 
1
+ from-url,to-url,persist-query,type