SEO SQUIRRLY™ - Version 8.3.08

Version Description

  • 02/15/2018 =
  • SEO Update - Update the article:tag Meta for Facebook Open Graph (SEO update)
  • Squirrly SEO is compatible with Cache Enabler plugin
  • SEO Update - Show canonical link for Draft Posts in Squirrly SEO Snippet
  • SEO Fix - Fixed the invalid email issue for longer domain extensions when connecting the blog with Squirrly SEO
  • SEO Fix - Removed the Memory Filter from Frontend (SEO update)
  • SEO Fix - Removed the deprecate PHP 7.2 functions

=

Download this release

Release Info

Developer cifi
Plugin Icon 128x128 SEO SQUIRRLY™
Version 8.3.08
Comparing to
See all releases

Code changes from version 8.2.26 to 8.3.08

Files changed (99) hide show
  1. classes/Action.php +52 -41
  2. classes/DisplayController.php +2 -1
  3. classes/Error.php +11 -5
  4. classes/FrontController.php +4 -0
  5. classes/ObjController.php +29 -25
  6. classes/Ranking.php +1 -1
  7. classes/Tools.php +69 -35
  8. controllers/Api.php +1 -1
  9. controllers/Cron.php +15 -7
  10. controllers/FrontMenu.php +4 -0
  11. controllers/Frontend.php +22 -6
  12. controllers/Menu.php +83 -63
  13. controllers/Post.php +5 -0
  14. controllers/PostsList.php +52 -48
  15. controllers/SerpChecker.php +391 -0
  16. controllers/Sitemaps.php +19 -21
  17. core/BlockBriefcaseKeywords.php +210 -0
  18. core/BlockPatterns.php +3 -0
  19. core/BlockPostsAnalytics.php +21 -1
  20. core/BlockSerpKeywords.php +140 -0
  21. core/BlockSettings.php +8 -3
  22. core/BlockSettingsSeo.php +54 -15
  23. core/Blocklogin.php +12 -4
  24. core/Loading.php +5 -0
  25. core/config.xml +41 -0
  26. languages/squirrly-seo-de_DE.mo +0 -0
  27. languages/squirrly-seo-de_DE.po +702 -306
  28. languages/squirrly-seo-ro_RO.mo +0 -0
  29. languages/squirrly-seo-ro_RO.po +701 -308
  30. models/BlockSettingsSeo.php +2 -0
  31. models/Frontend.php +28 -19
  32. models/Post.php +28 -22
  33. models/PostsList.php +13 -1
  34. models/SerpChecker.php +507 -0
  35. models/SerpCheckerTable.php +722 -0
  36. models/Sitemaps.php +6 -5
  37. models/abstract/Seo.php +27 -6
  38. models/domain/Patterns.php +19 -6
  39. models/domain/Post.php +1 -1
  40. models/domain/Sq.php +1 -1
  41. models/services/JsonLD.php +19 -17
  42. models/services/OpenGraph.php +19 -8
  43. models/services/Pixel.php +2 -2
  44. models/services/Verify.php +0 -1
  45. readme.txt +386 -334
  46. squirrly.php +13 -6
  47. view/BlockAnalytics.php +6 -0
  48. view/BlockBriefcaseKeywords.php +169 -0
  49. view/BlockCustomerService.php +1 -1
  50. view/BlockPatterns.php +17 -4
  51. view/BlockPostsAnalytics.php +0 -1
  52. view/BlockSerpKeywords.php +155 -0
  53. view/BlockSettings.php +62 -40
  54. view/BlockSettingsSeo.php +77 -20
  55. view/Blocksearch.php +10 -6
  56. view/FrontMenu.php +32 -10
  57. view/SerpChecker.php +216 -0
  58. view/css/blockaccount.css +1 -1
  59. view/css/blockaccount.min.css +1 -1
  60. view/css/blockaffiliate.css +3 -0
  61. view/css/blockaffiliate.min.css +1 -0
  62. view/css/blockaudit.css +4 -0
  63. view/css/blockaudit.min.css +1 -1
  64. view/css/blockcopyright.css +4 -0
  65. view/css/blockcopyright.min.css +1 -1
  66. view/css/blockcustomerservice.css +3 -0
  67. view/css/blockcustomerservice.min.css +1 -0
  68. view/css/blockdashboard.css +1 -1
  69. view/css/blockdashboard.min.css +1 -1
  70. view/css/blockimport.css +3 -0
  71. view/css/blockimport.min.css +1 -0
  72. view/css/blockkeywordresearch.css +4 -0
  73. view/css/blockkeywordresearch.min.css +1 -1
  74. view/css/blockliveassistant.css +4 -0
  75. view/css/blockliveassistant.min.css +1 -1
  76. view/css/blockpatterns.css +3 -0
  77. view/css/blockpatterns.min.css +1 -0
  78. view/css/blockpostsanalytics.css +3 -0
  79. view/css/blockpostsanalytics.min.css +1 -0
  80. view/css/blockresearch.css +33 -4
  81. view/css/blockresearch.min.css +1 -1
  82. view/css/blocksearch.css +218 -22
  83. view/css/blocksearch.min.css +1 -1
  84. view/css/blocksettings.css +1 -1
  85. view/css/blocksettings.min.css +1 -1
  86. view/css/blocksettingsseo.css +21 -1
  87. view/css/blocksettingsseo.min.css +1 -1
  88. view/css/datatables.css +448 -0
  89. view/css/datatables.min.css +1 -0
  90. view/css/fonts/FontAwesome.otf +0 -0
  91. view/css/fonts/fontawesome-webfont.eot +0 -0
  92. view/css/fonts/fontawesome-webfont.svg +565 -0
  93. view/css/fonts/fontawesome-webfont.ttf +0 -0
  94. view/css/fonts/fontawesome-webfont.woff +0 -0
  95. view/css/fonts/fontawesome-webfont.woff2 +0 -0
  96. view/css/frontmenu.css +1 -0
  97. view/css/frontmenu.min.css +1 -1
  98. view/css/global.css +10 -0
  99. view/css/global.min.css +1 -1
classes/Action.php CHANGED
@@ -86,52 +86,56 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
86
  * @return void
87
  */
88
  public function getActions($cur_action) {
89
- //Let only the logged users to access the actions
90
- if (is_admin() || is_network_admin()) {
91
- /* if config allready in cache */
92
- if (!isset(self::$config)) {
93
- $config_file = _SQ_CORE_DIR_ . 'config.xml';
94
- if (!file_exists($config_file)) {
95
- return;
96
- }
 
97
 
98
- /* load configuration blocks data from core config files */
99
- $data = file_get_contents($config_file);
100
- self::$config = json_decode(json_encode((array)simplexml_load_string($data)), 1);
101
- }
102
 
103
- if (is_array(self::$config))
104
- foreach (self::$config['block'] as $block) {
105
- if (isset($block['active']) && $block['active'] == 1) {
106
- /* if there is a single action */
107
- if (isset($block['actions']['action']))
108
- if (isset($block['admin']) &&
109
- (($block['admin'] == 1 && is_user_logged_in()) ||
110
- $block['admin'] == 0)
111
- ) {
112
- /* if there are more actions for the current block */
113
- if (!is_array($block['actions']['action'])) {
114
- /* add the action in the actions array */
115
- if ($block['actions']['action'] == $cur_action)
116
- $this->actions[] = array('class' => $block['name']);
117
- } else {
118
  /* if there are more actions for the current block */
119
- foreach ($block['actions']['action'] as $action) {
120
- /* add the actions in the actions array */
121
- if ($action == $cur_action)
122
  $this->actions[] = array('class' => $block['name']);
 
 
 
 
 
 
 
123
  }
124
  }
125
- }
126
 
 
127
  }
128
- }
129
 
130
 
131
- /* add the actions in WP */
132
- foreach ($this->actions as $actions) {
133
- SQ_Classes_ObjController::getClass($actions['class'])->action();
 
134
  }
 
 
135
  }
136
  }
137
 
@@ -141,8 +145,7 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
141
  * @param array $args
142
  * @return json | string
143
  */
144
- public
145
- static function apiCall($module, $args = array(), $timeout = 10) {
146
  $parameters = "";
147
  $scheme = "http:";
148
 
@@ -182,8 +185,13 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
182
  }
183
  //call it with http to prevent curl issues with ssls
184
  $url = self::cleanUrl($scheme . _SQ_API_URL_ . $module . "?" . $parameters);
185
- //update_option('sq_seopost_log', $url);
186
- return SQ_Classes_Tools::sq_remote_get($url, array(), array('timeout' => $timeout));
 
 
 
 
 
187
  }
188
 
189
  /**
@@ -191,9 +199,12 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
191
  * @param string $url
192
  * @return string
193
  */
194
- private
195
- static function cleanUrl($url) {
196
  return str_replace(array(' '), array('+'), $url);
197
  }
198
 
 
 
 
 
199
  }
86
  * @return void
87
  */
88
  public function getActions($cur_action) {
89
+ if(function_exists('simplexml_load_string')) {
90
+ //Let only the logged users to access the actions
91
+ if (is_admin() || is_network_admin()) {
92
+ /* if config allready in cache */
93
+ if (!isset(self::$config)) {
94
+ $config_file = _SQ_CORE_DIR_ . 'config.xml';
95
+ if (!file_exists($config_file)) {
96
+ return;
97
+ }
98
 
99
+ /* load configuration blocks data from core config files */
100
+ $data = file_get_contents($config_file);
101
+ self::$config = json_decode(json_encode((array)simplexml_load_string($data)), 1);
102
+ }
103
 
104
+ if (is_array(self::$config))
105
+ foreach (self::$config['block'] as $block) {
106
+ if (isset($block['active']) && $block['active'] == 1) {
107
+ /* if there is a single action */
108
+ if (isset($block['actions']['action']))
109
+ if (isset($block['admin']) &&
110
+ (($block['admin'] == 1 && is_user_logged_in()) ||
111
+ $block['admin'] == 0)
112
+ ) {
 
 
 
 
 
 
113
  /* if there are more actions for the current block */
114
+ if (!is_array($block['actions']['action'])) {
115
+ /* add the action in the actions array */
116
+ if ($block['actions']['action'] == $cur_action)
117
  $this->actions[] = array('class' => $block['name']);
118
+ } else {
119
+ /* if there are more actions for the current block */
120
+ foreach ($block['actions']['action'] as $action) {
121
+ /* add the actions in the actions array */
122
+ if ($action == $cur_action)
123
+ $this->actions[] = array('class' => $block['name']);
124
+ }
125
  }
126
  }
 
127
 
128
+ }
129
  }
 
130
 
131
 
132
+ /* add the actions in WP */
133
+ foreach ($this->actions as $actions) {
134
+ SQ_Classes_ObjController::getClass($actions['class'])->action();
135
+ }
136
  }
137
+ }else{
138
+ SQ_Classes_Error::setMessage(__('You need to activate the PHP simplexml_load_string extension for Squirrly SEO to work.', _SQ_PLUGIN_NAME_));
139
  }
140
  }
141
 
145
  * @param array $args
146
  * @return json | string
147
  */
148
+ public static function apiCall($module, $args = array(), $timeout = 10) {
 
149
  $parameters = "";
150
  $scheme = "http:";
151
 
185
  }
186
  //call it with http to prevent curl issues with ssls
187
  $url = self::cleanUrl($scheme . _SQ_API_URL_ . $module . "?" . $parameters);
188
+ try {
189
+ //echo $url;exit();
190
+ return SQ_Classes_Tools::sq_remote_get($url, array(), array('timeout' => $timeout));
191
+ }catch (Exception $e){
192
+ return '';
193
+ }
194
+
195
  }
196
 
197
  /**
199
  * @param string $url
200
  * @return string
201
  */
202
+ private static function cleanUrl($url) {
 
203
  return str_replace(array(' '), array('+'), $url);
204
  }
205
 
206
+ public static function apiSaveSettings(){
207
+ self::apiCall('sq/user/settings', array('settings' => json_encode(SQ_Classes_Tools::getBriefOptions())), 10);
208
+ }
209
+
210
  }
classes/DisplayController.php CHANGED
@@ -33,7 +33,7 @@ class SQ_Classes_DisplayController {
33
  *
34
  * @return string
35
  */
36
- public static function loadMedia($uri = '', $params = array('trigger' => true, 'media' => 'all')) {
37
  if (self::_isAjax()) {
38
  return;
39
  }
@@ -96,6 +96,7 @@ class SQ_Classes_DisplayController {
96
  if (isset($params['trigger']) && $params['trigger'] === true) {
97
  wp_print_scripts(array($name));
98
  }
 
99
  }
100
  }
101
 
33
  *
34
  * @return string
35
  */
36
+ public static function loadMedia($uri = '', $params = array('trigger' => false, 'media' => 'all')) {
37
  if (self::_isAjax()) {
38
  return;
39
  }
96
  if (isset($params['trigger']) && $params['trigger'] === true) {
97
  wp_print_scripts(array($name));
98
  }
99
+
100
  }
101
  }
102
 
classes/Error.php CHANGED
@@ -62,20 +62,26 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
62
  break;
63
  case 'settings':
64
  /* switch off option for notifications */
65
- self::$switch_off = "<a href=\"javascript:void(0);\" onclick=\"jQuery.post( ajaxurl, {action: 'sq_warnings_off', nonce: '" . wp_create_nonce(_SQ_NONCE_ID_) . "'}, function(data) { if (data) { jQuery('#sq_ignore_warn').attr('checked', true); jQuery('.sq_message').hide(); jQuery('#toplevel_page_squirrly .awaiting-mod').fadeOut('slow'); } });\" >" . __("Turn off warnings!", _SQ_PLUGIN_NAME_) . "</a>";
66
  self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'] . " ", $error['id']);
67
  break;
68
 
69
  case 'helpnotice':
70
- if (SQ_Classes_Tools::getOption('ignore_warn')) {
71
- break;
 
72
  }
73
- self::$switch_off = "<a href=\"javascript:void(0);\" onclick=\"jQuery.post( ajaxurl, {action: 'sq_warnings_off', nonce: '" . wp_create_nonce(_SQ_NONCE_ID_) . "'}, function(data) { if (data) { jQuery('#sq_ignore_warn').attr('checked', true); jQuery('.sq_message').hide(); jQuery('#toplevel_page_squirrly .awaiting-mod').fadeOut('slow'); } });\" >" . __("Don't bother me!", _SQ_PLUGIN_NAME_) . "</a>";
74
- self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'] . " " . self::$switch_off, $error['id'], 'sq_helpnotice');
75
  break;
 
76
  case 'success':
77
  self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'] . " ", $error['id'], 'sq_success');
78
  break;
 
 
 
 
 
 
 
79
  default:
80
 
81
  self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'], $error['id']);
62
  break;
63
  case 'settings':
64
  /* switch off option for notifications */
 
65
  self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'] . " ", $error['id']);
66
  break;
67
 
68
  case 'helpnotice':
69
+ if (!SQ_Classes_Tools::getOption('ignore_warn')) {
70
+ self::$switch_off = "<a href=\"javascript:void(0);\" onclick=\"jQuery.post( ajaxurl, {action: 'sq_warnings_off', nonce: '" . wp_create_nonce(_SQ_NONCE_ID_) . "'}, function() {jQuery('#sq_ignore_warn').attr('checked', true); jQuery('.sq_message').hide(); jQuery('#toplevel_page_squirrly .awaiting-mod').fadeOut('slow'); });\" >" . __("Don't bother me!", _SQ_PLUGIN_NAME_) . "</a>";
71
+ self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'] . " " . self::$switch_off, $error['id'], 'sq_helpnotice');
72
  }
 
 
73
  break;
74
+
75
  case 'success':
76
  self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'] . " ", $error['id'], 'sq_success');
77
  break;
78
+
79
+ case 'trial':
80
+ if (SQ_Classes_Tools::getOption('sq_google_alert_trial')) {
81
+ self::$switch_off = "<a href=\"javascript:void(0);\" style=\"font-size: 12px;float:right;margin-right: 5px;color: #ddd;\" onclick=\"jQuery.post( ajaxurl, {action: 'sq_google_alert_trial', nonce: '" . wp_create_nonce(_SQ_NONCE_ID_) . "'}, function() {jQuery('.sq_message').fadeOut('slow');});\" >" . __("Don't bother me!", _SQ_PLUGIN_NAME_) . "</a>";
82
+ self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'] . " " . self::$switch_off, $error['id'], 'sq_success');
83
+ }
84
+ break;
85
  default:
86
 
87
  self::showError("<span class='sq_notice_author'>" . _SQ_PLUGIN_NAME_ . "</span> " . $error['text'], $error['id']);
classes/FrontController.php CHANGED
@@ -47,6 +47,10 @@ class SQ_Classes_FrontController {
47
  SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Seo');
48
  }
49
 
 
 
 
 
50
  /**
51
  * load sequence of classes
52
  * Function called usualy when the controller is loaded in WP
47
  SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Seo');
48
  }
49
 
50
+ public function getClass(){
51
+ return $this->name;
52
+ }
53
+
54
  /**
55
  * load sequence of classes
56
  * Function called usualy when the controller is loaded in WP
classes/ObjController.php CHANGED
@@ -166,35 +166,39 @@ class SQ_Classes_ObjController {
166
  * @param string $for
167
  */
168
  public function getBlocks($for) {
169
- /* if config allready in cache */
170
- if (!isset(self::$config)) {
171
- $config_file = _SQ_CORE_DIR_ . 'config.xml';
172
- if (!file_exists($config_file))
173
- return;
174
-
175
- /* load configuration blocks data from core config files */
176
- $data = file_get_contents($config_file);
177
- self::$config = json_decode(json_encode((array)simplexml_load_string($data)), 1);;
178
- }
179
- //print_r(self::$config);
180
- if (is_array(self::$config))
181
- foreach (self::$config['block'] as $block) {
182
- if ($block['active'] == 1)
183
- if (isset($block['controllers']['controller']))
184
- if (!is_array($block['controllers']['controller'])) {
185
- /* if the block should load for the current controller */
186
- if ($for == $block['controllers']['controller']) {
187
- SQ_Classes_ObjController::getClass($block['name'])->init();
188
- }
189
- } else {
190
- foreach ($block['controllers']['controller'] as $controller) {
191
  /* if the block should load for the current controller */
192
- if ($for == $controller) {
193
  SQ_Classes_ObjController::getClass($block['name'])->init();
194
  }
 
 
 
 
 
 
 
195
  }
196
- }
197
- }
 
 
198
  }
199
 
200
  }
166
  * @param string $for
167
  */
168
  public function getBlocks($for) {
169
+ if (function_exists('simplexml_load_string')) {
170
+ /* if config allready in cache */
171
+ if (!isset(self::$config)) {
172
+ $config_file = _SQ_CORE_DIR_ . 'config.xml';
173
+ if (!file_exists($config_file))
174
+ return;
175
+
176
+ /* load configuration blocks data from core config files */
177
+ $data = file_get_contents($config_file);
178
+ self::$config = json_decode(json_encode((array)simplexml_load_string($data)), 1);;
179
+ }
180
+ //print_r(self::$config);
181
+ if (is_array(self::$config))
182
+ foreach (self::$config['block'] as $block) {
183
+ if ($block['active'] == 1)
184
+ if (isset($block['controllers']['controller']))
185
+ if (!is_array($block['controllers']['controller'])) {
 
 
 
 
 
186
  /* if the block should load for the current controller */
187
+ if ($for == $block['controllers']['controller']) {
188
  SQ_Classes_ObjController::getClass($block['name'])->init();
189
  }
190
+ } else {
191
+ foreach ($block['controllers']['controller'] as $controller) {
192
+ /* if the block should load for the current controller */
193
+ if ($for == $controller) {
194
+ SQ_Classes_ObjController::getClass($block['name'])->init();
195
+ }
196
+ }
197
  }
198
+ }
199
+ } else {
200
+ SQ_Classes_Error::setMessage(__('You need to activate the PHP simplexml_load_string extension for Squirrly SEO to work.', _SQ_PLUGIN_NAME_));
201
+ }
202
  }
203
 
204
  }
classes/Ranking.php CHANGED
@@ -224,7 +224,7 @@ class SQ_Classes_Ranking extends SQ_Classes_FrontController {
224
  if (!empty($matches[1])) {
225
  $pos = -1;
226
  foreach ($matches[1] as $index => $url) {
227
- if (strpos($url, rtrim($permalink, '/')) !== false) {
228
  $pos = $index + 1;
229
  break;
230
  }
224
  if (!empty($matches[1])) {
225
  $pos = -1;
226
  foreach ($matches[1] as $index => $url) {
227
+ if (strpos($url, rtrim(str_replace(array('https:', 'http:'), array('', ''), $permalink), '/')) !== false) {
228
  $pos = $index + 1;
229
  break;
230
  }
classes/Tools.php CHANGED
@@ -22,11 +22,40 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
22
  public function __construct() {
23
  parent::__construct();
24
 
 
 
 
 
 
25
  self::$options = $this->getOptions();
26
 
27
  $this->checkDebug(); //dev mode
28
  }
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  public static function getUserID() {
31
  global $current_user;
32
  return $current_user->ID;
@@ -38,8 +67,7 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
38
  * @return void
39
  */
40
  function hookInit() {
41
- //TinyMCE editor required
42
- //set_user_setting('editor', 'tinymce');
43
 
44
  $this->loadMultilanguage();
45
 
@@ -81,6 +109,7 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
81
  'sq_post_types' => array(
82
  'post', 'page', 'product', 'shopp_page_shopp-products'
83
  ),
 
84
  // --
85
  'sq_auto_canonical' => 1,
86
  'sq_auto_sitemap' => 0,
@@ -156,10 +185,13 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
156
  'sq_google_language' => 'en',
157
  'sq_google_country_strict' => 0,
158
  'sq_google_ranksperhour' => 0,
 
159
  'sq_google_last_checked' => 0,
 
160
  'sq_google_show_ignored' => 0,
161
  'sq_google_serp_active' => 0,
162
- 'sq_google_serp_expired' => 0,
 
163
  // --
164
  'sq_affiliate_link' => '',
165
  'sq_sla' => 1,
@@ -197,7 +229,7 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
197
  'pinterest_verify' => "",
198
  'alexa_verify' => "",
199
  ),
200
-
201
  'patterns' => array(
202
  'home' => array(
203
  'sep' => '|',
@@ -492,12 +524,15 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
492
  'sq_google_plus' => (int)($socials['google_plus_url'] <> ''),
493
  'sq_google_wt' => (int)($codes['google_wt'] <> ''),
494
  'sq_google_analytics' => (int)($codes['google_analytics'] <> ''),
 
495
  'sq_facebook_insights' => (int)(!empty($socials['sq_facebook_insights'])),
496
  'sq_bing_wt' => (int)($codes['bing_wt'] <> ''),
497
  'sq_pinterest' => (int)($codes['pinterest_verify'] <> ''),
498
  'sq_alexa' => (int)($codes['alexa_verify'] <> ''),
499
  'sq_keyword_help' => SQ_Classes_Tools::getOption('sq_keyword_help'),
500
  'sq_keyword_information' => SQ_Classes_Tools::getOption('sq_keyword_information'),
 
 
501
  'sq_google_country_strict' => SQ_Classes_Tools::getOption('sq_google_country_strict'),
502
  'sq_keywordtag' => SQ_Classes_Tools::getOption('sq_keywordtag'),
503
  'sq_local_images' => SQ_Classes_Tools::getOption('sq_local_images'),
@@ -842,15 +877,7 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
842
  * @return string
843
  */
844
  private static function cleanResponce($response) {
845
-
846
- if (function_exists('substr_count'))
847
- if (substr_count($response, '(') > 1)
848
- return $response;
849
-
850
- if (strpos($response, '(') !== false && strpos($response, ')') !== false)
851
- $response = substr($response, (strpos($response, '(') + 1), (strpos($response, ')') - 1));
852
-
853
- return $response;
854
  }
855
 
856
  /**
@@ -1116,7 +1143,6 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
1116
  $title = str_replace(array("\n", "&nbsp;"), " ", $title);
1117
 
1118
  $title = self::i18n(trim(esc_html(ent2ncr(strip_tags($title)))));
1119
- $title = addcslashes($title, '$');
1120
 
1121
  $title = preg_replace('/\s{2,}/', ' ', $title);
1122
  }
@@ -1125,8 +1151,6 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
1125
 
1126
  public static function clearDescription($description) {
1127
  if ($description <> '') {
1128
-
1129
-
1130
  if (function_exists('preg_replace')) {
1131
  $search = array("'<script[^>]*?>.*?<\/script>'si", // strip out javascript
1132
  "/<form.*?<\/form>/si",
@@ -1142,7 +1166,6 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
1142
  }
1143
 
1144
  $description = self::i18n(trim(esc_html(ent2ncr(strip_tags($description)))));
1145
- $description = addcslashes($description, '$');
1146
  }
1147
 
1148
  return $description;
@@ -1289,7 +1312,7 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
1289
  * Check if debug is called
1290
  */
1291
  private function checkDebug() {
1292
- //if debug is called
1293
  if (SQ_DEBUG && self::getIsset('sq_debug')) {
1294
  if (self::getValue('sq_debug') === 'on') {
1295
  if (function_exists('register_shutdown_function')) {
@@ -1345,20 +1368,20 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
1345
  self::$debug[] = $output;
1346
  }
1347
 
 
 
 
 
 
 
 
 
 
1348
  /**
1349
  * Show the debug dump
1350
  */
1351
  public static function showDebug() {
1352
  echo "Debug result: <br />" . '<div id="wpcontent">' . @implode('<br />', self::$debug) . '</div>';
1353
-
1354
- $run_time = number_format(microtime(true) - REQUEST_TIME, 3);
1355
- $pps = number_format(1 / $run_time, 0);
1356
- $memory_avail = ini_get('memory_limit');
1357
- $memory_used = number_format(memory_get_usage(true) / (1024 * 1024), 2);
1358
- $memory_peak = number_format(memory_get_peak_usage(true) / (1024 * 1024), 2);
1359
-
1360
- echo PHP_EOL . " Load: {$memory_avail} (avail) / {$memory_used}M (used) / {$memory_peak}M (peak)";
1361
- echo " | Time: {$run_time}s | {$pps} req/sec";
1362
  }
1363
 
1364
  public function sq_activate() {
@@ -1368,16 +1391,18 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
1368
  }
1369
 
1370
  public function sq_deactivate() {
1371
- //clear the cron job
1372
- wp_clear_scheduled_hook('sq_processCron');
 
1373
 
1374
- $args = array();
1375
- $args['type'] = 'deact';
1376
- SQ_Classes_Action::apiCall('sq/user/log', $args, 5);
1377
 
1378
- remove_filter('rewrite_rules_array', array(SQ_Classes_ObjController::getClass('SQ_Core_BlockSettingsSeo'), 'rewrite_rules'));
1379
- global $wp_rewrite;
1380
- $wp_rewrite->flush_rules();
 
1381
  }
1382
 
1383
  public static function emptyCache($post_id = null) {
@@ -1501,4 +1526,13 @@ class SQ_Classes_Tools extends SQ_Classes_FrontController {
1501
  }
1502
  }
1503
  }
 
 
 
 
 
 
 
 
 
1504
  }
22
  public function __construct() {
23
  parent::__construct();
24
 
25
+ $maxmemory = self::getMaxMemory();
26
+ if ($maxmemory && $maxmemory < 60) {
27
+ @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
28
+ }
29
+
30
  self::$options = $this->getOptions();
31
 
32
  $this->checkDebug(); //dev mode
33
  }
34
 
35
+ public static function getMaxMemory() {
36
+ try {
37
+ $memory_limit = @ini_get('memory_limit');
38
+ if((int) $memory_limit > 0) {
39
+ if (preg_match('/^(\d+)(.)$/', $memory_limit, $matches)) {
40
+ if ($matches[2] == 'M') {
41
+ $memory_limit = $matches[1] * 1024 * 1024; // nnnM -> nnn MB
42
+ } else if ($matches[2] == 'K') {
43
+ $memory_limit = $matches[1] * 1024; // nnnK -> nnn KB
44
+ }
45
+ }
46
+ return number_format($memory_limit / 1024 / 1024, 0);
47
+ }
48
+ } catch (Exception $e) {
49
+ }
50
+
51
+ return false;
52
+
53
+ }
54
+
55
+ public static function getUsedMemory() {
56
+ return number_format(memory_get_usage() / 1024 / 1024, 0);
57
+ }
58
+
59
  public static function getUserID() {
60
  global $current_user;
61
  return $current_user->ID;
67
  * @return void
68
  */
69
  function hookInit() {
70
+
 
71
 
72
  $this->loadMultilanguage();
73
 
109
  'sq_post_types' => array(
110
  'post', 'page', 'product', 'shopp_page_shopp-products'
111
  ),
112
+ 'sq_exclude_post_types' => array(),
113
  // --
114
  'sq_auto_canonical' => 1,
115
  'sq_auto_sitemap' => 0,
185
  'sq_google_language' => 'en',
186
  'sq_google_country_strict' => 0,
187
  'sq_google_ranksperhour' => 0,
188
+ 'sq_google_serpsperhour' => 50,
189
  'sq_google_last_checked' => 0,
190
+ 'sq_google_last_info' => 0,
191
  'sq_google_show_ignored' => 0,
192
  'sq_google_serp_active' => 0,
193
+ 'sq_google_serp_trial' => 0,
194
+ 'sq_google_alert_trial' => 1,
195
  // --
196
  'sq_affiliate_link' => '',
197
  'sq_sla' => 1,
229
  'pinterest_verify' => "",
230
  'alexa_verify' => "",
231
  ),
232
+ 'sq_auto_pattern' => 1,
233
  'patterns' => array(
234
  'home' => array(
235
  'sep' => '|',
524
  'sq_google_plus' => (int)($socials['google_plus_url'] <> ''),
525
  'sq_google_wt' => (int)($codes['google_wt'] <> ''),
526
  'sq_google_analytics' => (int)($codes['google_analytics'] <> ''),
527
+ 'sq_google_serpsperhour' => (int)SQ_Classes_Tools::getOption('sq_google_serpsperhour'),
528
  'sq_facebook_insights' => (int)(!empty($socials['sq_facebook_insights'])),
529
  'sq_bing_wt' => (int)($codes['bing_wt'] <> ''),
530
  'sq_pinterest' => (int)($codes['pinterest_verify'] <> ''),
531
  'sq_alexa' => (int)($codes['alexa_verify'] <> ''),
532
  'sq_keyword_help' => SQ_Classes_Tools::getOption('sq_keyword_help'),
533
  'sq_keyword_information' => SQ_Classes_Tools::getOption('sq_keyword_information'),
534
+ 'sq_google_language' => SQ_Classes_Tools::getOption('sq_google_language'),
535
+ 'sq_google_country' => SQ_Classes_Tools::getOption('sq_google_country'),
536
  'sq_google_country_strict' => SQ_Classes_Tools::getOption('sq_google_country_strict'),
537
  'sq_keywordtag' => SQ_Classes_Tools::getOption('sq_keywordtag'),
538
  'sq_local_images' => SQ_Classes_Tools::getOption('sq_local_images'),
877
  * @return string
878
  */
879
  private static function cleanResponce($response) {
880
+ return trim($response, '()');
 
 
 
 
 
 
 
 
881
  }
882
 
883
  /**
1143
  $title = str_replace(array("\n", "&nbsp;"), " ", $title);
1144
 
1145
  $title = self::i18n(trim(esc_html(ent2ncr(strip_tags($title)))));
 
1146
 
1147
  $title = preg_replace('/\s{2,}/', ' ', $title);
1148
  }
1151
 
1152
  public static function clearDescription($description) {
1153
  if ($description <> '') {
 
 
1154
  if (function_exists('preg_replace')) {
1155
  $search = array("'<script[^>]*?>.*?<\/script>'si", // strip out javascript
1156
  "/<form.*?<\/form>/si",
1166
  }
1167
 
1168
  $description = self::i18n(trim(esc_html(ent2ncr(strip_tags($description)))));
 
1169
  }
1170
 
1171
  return $description;
1312
  * Check if debug is called
1313
  */
1314
  private function checkDebug() {
1315
+ //if debug is called
1316
  if (SQ_DEBUG && self::getIsset('sq_debug')) {
1317
  if (self::getValue('sq_debug') === 'on') {
1318
  if (function_exists('register_shutdown_function')) {
1368
  self::$debug[] = $output;
1369
  }
1370
 
1371
+ /**
1372
+ * Add Memory Debug in the footer
1373
+ */
1374
+ public function hookFooter() {
1375
+ if (self::getValue('sq_debug') === 'on') {
1376
+ self::dump(self::getMaxMemory(), self::getUsedMemory());
1377
+ }
1378
+ }
1379
+
1380
  /**
1381
  * Show the debug dump
1382
  */
1383
  public static function showDebug() {
1384
  echo "Debug result: <br />" . '<div id="wpcontent">' . @implode('<br />', self::$debug) . '</div>';
 
 
 
 
 
 
 
 
 
1385
  }
1386
 
1387
  public function sq_activate() {
1391
  }
1392
 
1393
  public function sq_deactivate() {
1394
+ try {
1395
+ //clear the cron job
1396
+ wp_clear_scheduled_hook('sq_processCron');
1397
 
1398
+ $args = array();
1399
+ $args['type'] = 'deact';
1400
+ SQ_Classes_Action::apiCall('sq/user/log', $args, 5);
1401
 
1402
+ remove_filter('rewrite_rules_array', array(SQ_Classes_ObjController::getClass('SQ_Core_BlockSettingsSeo'), 'rewrite_rules'));
1403
+ } catch (Exception $e) {
1404
+
1405
+ }
1406
  }
1407
 
1408
  public static function emptyCache($post_id = null) {
1526
  }
1527
  }
1528
  }
1529
+
1530
+ public static function getBusinessLink() {
1531
+ if (!self::getOption('sq_google_serp_active')) {
1532
+ return _SQ_DASH_URL_ . 'login/?token=' . self::getOption('sq_api') . '&redirect_to=' . _SQ_DASH_URL_ . 'user/plans?pid=31';
1533
+ } else {
1534
+ return admin_url('admin.php?page=sq_posts');
1535
+ }
1536
+
1537
+ }
1538
  }
controllers/Api.php CHANGED
@@ -36,7 +36,7 @@ class SQ_Controllers_Api extends SQ_Classes_FrontController {
36
  }
37
 
38
  if (SQ_Classes_Tools::getOption('sq_token') <> $token) {
39
- SQ_Classes_Action::apiCall('sq/user/settings', array('settings' => json_encode(SQ_Classes_Tools::getBriefOptions())), 10);
40
  exit(json_encode(array('error' => __('Connection expired. Please try again', _SQ_PLUGIN_NAME_))));
41
 
42
  }
36
  }
37
 
38
  if (SQ_Classes_Tools::getOption('sq_token') <> $token) {
39
+ SQ_Classes_Action::apiSaveSettings();
40
  exit(json_encode(array('error' => __('Connection expired. Please try again', _SQ_PLUGIN_NAME_))));
41
 
42
  }
controllers/Cron.php CHANGED
@@ -8,22 +8,30 @@ class SQ_Controllers_Cron extends SQ_Classes_FrontController {
8
 
9
  if (get_option('sq_seopost') !== false) {
10
  $process = json_decode(get_option('sq_seopost'), true);
11
- foreach ($process as $key => $call) {
12
 
13
- if (!$response = json_decode(SQ_Classes_Action::apiCall('sq/seo/post', $call, 10))) {
14
- break;
15
- }
 
 
 
16
 
17
- if (isset($response->saved) && $response->saved == true) {
18
- unset($process[$key]);
 
19
  }
 
20
  }
21
  update_option('sq_seopost', json_encode($process));
22
  }
23
  }
24
 
25
  public function processRankingCron() {
26
- SQ_Classes_ObjController::getClass('SQ_Classes_Ranking')->processCron();
 
 
 
 
27
  }
28
 
29
  }
8
 
9
  if (get_option('sq_seopost') !== false) {
10
  $process = json_decode(get_option('sq_seopost'), true);
 
11
 
12
+ if(!empty($process)) {
13
+ foreach ($process as $key => $call) {
14
+
15
+ if (!$response = json_decode(SQ_Classes_Action::apiCall('sq/seo/post', $call, 10))) {
16
+ break;
17
+ }
18
 
19
+ if (isset($response->saved) && $response->saved == true) {
20
+ unset($process[$key]);
21
+ }
22
  }
23
+
24
  }
25
  update_option('sq_seopost', json_encode($process));
26
  }
27
  }
28
 
29
  public function processRankingCron() {
30
+ if(SQ_Classes_Tools::getOption('sq_google_serp_active')) {
31
+ SQ_Classes_ObjController::getClass('SQ_Controllers_SerpChecker')->processCron();
32
+ }else {
33
+ SQ_Classes_ObjController::getClass('SQ_Classes_Ranking')->processCron();
34
+ }
35
  }
36
 
37
  }
controllers/FrontMenu.php CHANGED
@@ -59,6 +59,10 @@ class SQ_Controllers_FrontMenu extends SQ_Classes_FrontController {
59
  $sq->tw_media = SQ_Classes_Tools::getValue('sq_tw_media', false);
60
 
61
 
 
 
 
 
62
  //empty the cache from cache plugins
63
  //SQ_Classes_Tools::emptyCache();
64
 
59
  $sq->tw_media = SQ_Classes_Tools::getValue('sq_tw_media', false);
60
 
61
 
62
+ //Prevent broken url in canonical link
63
+ if(strpos($sq->canonical,'//') === false){
64
+ $sq->canonical = false;
65
+ }
66
  //empty the cache from cache plugins
67
  //SQ_Classes_Tools::emptyCache();
68
 
controllers/Frontend.php CHANGED
@@ -2,6 +2,9 @@
2
 
3
  class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
4
 
 
 
 
5
  public function __construct() {
6
  if (SQ_Classes_Tools::isAjax()) return;
7
  parent::__construct();
@@ -9,11 +12,14 @@ class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
9
  //For favicon and Robots
10
  $this->hookCheckFiles();
11
 
12
- add_action('plugins_loaded', array($this, 'hookBuffer'));
 
 
 
13
  add_action('template_redirect', array($this, 'hookBuffer'));
14
 
15
- //SET THE POST FROM THE BEGINING
16
- add_action('template_redirect', array($this->model, 'setPost'), 10);
17
 
18
  /* Check if sitemap is on and Load the Sitemap */
19
  if (SQ_Classes_Tools::getOption('sq_auto_sitemap')) SQ_Classes_ObjController::getClass('SQ_Controllers_Sitemaps');
@@ -30,7 +36,10 @@ class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
30
  * HOOK THE BUFFER
31
  */
32
  public function hookBuffer() {
33
- remove_action('template_redirect', array($this, 'hookBuffer'));
 
 
 
34
 
35
  if ($this->isSquirrlySeoEnabled()) {
36
  global $wp_super_cache_late_init;
@@ -96,8 +105,10 @@ class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
96
  * Hook the Header load
97
  */
98
  public function hookFronthead() {
99
- if (!SQ_Classes_Tools::isAjax()) {
100
- SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia(_SQ_THEME_URL_ . 'css/frontend' . (SQ_DEBUG ? '' : '.min') . '.css');
 
 
101
  }
102
  }
103
 
@@ -157,6 +168,11 @@ class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
157
  }
158
 
159
  public function hookFrontfooter() {
 
 
 
 
 
160
  if ($this->isSquirrlySeoEnabled()) {
161
  echo $this->model->getFooter();
162
  }
2
 
3
  class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
4
 
5
+ /** @var SQ_Models_Frontend */
6
+ public $model;
7
+
8
  public function __construct() {
9
  if (SQ_Classes_Tools::isAjax()) return;
10
  parent::__construct();
12
  //For favicon and Robots
13
  $this->hookCheckFiles();
14
 
15
+ //Hook the buffer on both actions in case one fails
16
+ if (!defined('CE_FILE')) { //compatible with other cache plugins
17
+ add_action('plugins_loaded', array($this, 'hookBuffer'));
18
+ }
19
  add_action('template_redirect', array($this, 'hookBuffer'));
20
 
21
+ //Set the post so that Squirrly will know which one to process
22
+ add_action('template_redirect', array($this->model, 'setPost'), 9);
23
 
24
  /* Check if sitemap is on and Load the Sitemap */
25
  if (SQ_Classes_Tools::getOption('sq_auto_sitemap')) SQ_Classes_ObjController::getClass('SQ_Controllers_Sitemaps');
36
  * HOOK THE BUFFER
37
  */
38
  public function hookBuffer() {
39
+ //remove the action is already hocked in plugins_loaded
40
+ if (!did_action('template_redirect')) {
41
+ remove_action('template_redirect', array($this, 'hookBuffer'));
42
+ }
43
 
44
  if ($this->isSquirrlySeoEnabled()) {
45
  global $wp_super_cache_late_init;
105
  * Hook the Header load
106
  */
107
  public function hookFronthead() {
108
+ if (!defined('SQ_NOCSS') || (defined('SQ_NOCSS') && !SQ_NOCSS)) {
109
+ if (!SQ_Classes_Tools::isAjax()) {
110
+ SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia(_SQ_THEME_URL_ . 'css/frontend' . (SQ_DEBUG ? '' : '.min') . '.css');
111
+ }
112
  }
113
  }
114
 
168
  }
169
 
170
  public function hookFrontfooter() {
171
+ //Memory Debug
172
+ if (SQ_Classes_Tools::getValue('sq_debug') === 'on') {
173
+ SQ_Classes_Tools::dump(SQ_Classes_Tools::getMaxMemory(), SQ_Classes_Tools::getUsedMemory());
174
+ }
175
+
176
  if ($this->isSquirrlySeoEnabled()) {
177
  echo $this->model->getFooter();
178
  }
controllers/Menu.php CHANGED
@@ -8,7 +8,6 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
8
  /** @var array snippet */
9
  var $options = array();
10
 
11
-
12
  public function __construct() {
13
  parent::__construct();
14
  add_action('admin_bar_menu', array($this, 'hookTopmenu'), 999);
@@ -20,55 +19,56 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
20
  public function hookInit() {
21
  /* add the plugin menu in admin */
22
  if (current_user_can('manage_options')) {
23
- //check if activated
24
- if (get_transient('sq_activate') == 1) {
25
- //Check if there are expected upgrades
26
- SQ_Classes_Tools::checkUpgrade();
27
-
28
- // Delete the redirect transient
29
- delete_transient('sq_activate');
30
- SQ_Classes_Action::apiCall('sq/user/settings', array('settings' => json_encode(SQ_Classes_Tools::getBriefOptions())), 10);
 
 
 
 
 
 
 
 
 
 
31
 
32
- wp_safe_redirect(admin_url('admin.php?page=sq_dashboard'));
33
- exit();
34
- } else {
35
- //Deactivate the QuickSEO plugin
36
- if (SQ_Classes_Tools::isPluginInstalled('quick-seo')) {
37
- $quickSEO = _QSS_ROOT_DIR_ . '/index.php';
38
- if (is_plugin_active(plugin_basename($quickSEO))) {
39
- delete_transient('qss_activate');
40
-
41
- deactivate_plugins(plugin_basename($quickSEO), true);
42
- SQ_Classes_Error::setMessage(sprintf(__("Good news, %s is integrated in Squirrly SEO now and you don't have to run 2 plugins anymore", _SQ_PLUGIN_NAME_), _QSS_PLUGIN_NAME_));
43
  }
44
 
45
- }
 
 
 
 
 
 
46
 
47
- //Deactivate the Premium SEO Pack plugin
48
- if (SQ_Classes_Tools::isPluginInstalled('premium-seo-pack')) {
49
- $phpSEO = _PSP_ROOT_DIR_ . '/index.php';
50
- if (is_plugin_active(plugin_basename($phpSEO))) {
51
- delete_transient('psp_activate');
52
- deactivate_plugins(plugin_basename($phpSEO), true);
53
- SQ_Classes_Error::setMessage(sprintf(__("Good news, %s is integrated in Squirrly SEO now and you don't have to run 2 plugins anymore", _SQ_PLUGIN_NAME_), _PSP_PLUGIN_NAME_));
54
 
 
 
 
55
  }
56
- }
57
 
58
- //Make sure Squirrly upgrades the settings and seo
59
- if (SQ_Classes_Tools::getOption('sq_ver') < 8200 && SQ_Classes_Tools::getOption('sq_api') <> '') {
60
- wp_redirect('admin.php?page=sq_dashboard&action=sq_dataupgrade&nonce=' . wp_create_nonce(_SQ_NONCE_ID_));
61
  }
62
- }
63
 
64
- if (get_transient('sq_rewrite') == 1) {
65
- // Delete the redirect transient
66
- delete_transient('sq_rewrite');
67
- global $wp_rewrite;
68
- $wp_rewrite->flush_rules();
 
 
69
  }
70
 
71
-
72
  }
73
  //activate the cron job if not exists
74
  if (!wp_get_schedule('sq_processCron')) {
@@ -76,8 +76,6 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
76
  }
77
 
78
  add_filter('rewrite_rules_array', array(SQ_Classes_ObjController::getClass('SQ_Core_BlockSettingsSeo'), 'rewrite_rules'), 999, 1);
79
-
80
-
81
  }
82
 
83
  /**
@@ -92,17 +90,17 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
92
  return;
93
  }
94
 
95
- $wp_admin_bar->add_node(array(
96
- 'id' => 'sq_posts',
97
- 'title' => __('See Your Rank on Google', _SQ_PLUGIN_NAME_),
98
- 'href' => admin_url('admin.php?page=sq_posts'),
99
- 'parent' => false
100
- ));
 
 
101
 
102
  if (is_admin()) {
103
  $current_screen = get_current_screen();
104
- SQ_Classes_Tools::dump($current_screen);
105
-
106
  $post = get_post();
107
  if ('post' == $current_screen->base
108
  && ($post_type_object = get_post_type_object($post->post_type))
@@ -183,7 +181,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
183
  if (strpos($_SERVER['REQUEST_URI'], '?page=sq_dashboard') !== false) {
184
  SQ_Classes_Tools::saveOptions('sq_dashboard', 1);
185
  }
186
- if (strpos($_SERVER['REQUEST_URI'], '?page=sq_analytics') !== false) {
187
  SQ_Classes_Tools::saveOptions('sq_analytics', 1);
188
  }
189
 
@@ -195,18 +193,30 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
195
  } else {
196
  $time_loaded = get_transient('sq_analytics');
197
  if (time() - $time_loaded > (60 * 60 * 24 * 3) && time() - $time_loaded < (60 * 60 * 24 * 14)) {
198
- SQ_Classes_Error::setError(__('Check out the Squirrly Analytics section. <a href="admin.php?page=sq_posts" title="Squirrly Analytics">Click here</a>', _SQ_PLUGIN_NAME_));
199
  }
200
  }
201
  }
202
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  $dashboard_alert = (int)(SQ_Classes_Tools::getOption('sq_dashboard') == 0);
204
 
205
 
206
  ///////////////
207
 
208
  $this->model->addMenu(array(ucfirst(_SQ_NAME_),
209
- 'Squirrly' . SQ_Classes_Tools::showNotices(SQ_Classes_Tools::$errors_count, 'errors_count'),
210
  'edit_posts',
211
  'sq_dashboard',
212
  null,
@@ -222,10 +232,18 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
222
  ));
223
 
224
  //IF SERP PLUGIN IS NOT INSTALLED
225
- if (!class_exists('SRC_Classes_ObjController')) {
 
 
 
 
 
 
 
 
226
  $this->model->addSubmenu(array('sq_dashboard',
227
  ucfirst(_SQ_NAME_) . __(' Performance Analytics', _SQ_PLUGIN_NAME_),
228
- __('Performance <br />Analytics', _SQ_PLUGIN_NAME_) . SQ_Classes_Tools::showNotices($analytics_alert, 'errors_count'),
229
  'edit_posts',
230
  'sq_posts',
231
  array(SQ_Classes_ObjController::getClass('SQ_Core_BlockPostsAnalytics'), 'init')
@@ -240,6 +258,14 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
240
  array(SQ_Classes_ObjController::getClass('SQ_Core_BlockKeywordResearch'), 'init')
241
  ));
242
 
 
 
 
 
 
 
 
 
243
  $this->model->addSubmenu(array('sq_dashboard',
244
  ucfirst(_SQ_NAME_) . __(' Live Assistant', _SQ_PLUGIN_NAME_),
245
  __('Live Assistant', _SQ_PLUGIN_NAME_),
@@ -267,7 +293,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
267
 
268
  $this->model->addSubmenu(array('sq_dashboard',
269
  ucfirst(_SQ_NAME_) . __(' SEO Settings', _SQ_PLUGIN_NAME_),
270
- __('SEO Settings', _SQ_PLUGIN_NAME_) . SQ_Classes_Tools::showNotices(SQ_Classes_Tools::$errors_count, 'errors_count'),
271
  'manage_options',
272
  'sq_seo',
273
  array(SQ_Classes_ObjController::getClass('SQ_Core_BlockSettingsSeo'), 'init')
@@ -324,6 +350,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
324
  ));
325
  }
326
 
 
327
  foreach ($this->post_type as $type) {
328
  $this->model->addMeta(array('post' . _SQ_NAME_,
329
  ucfirst(_SQ_NAME_),
@@ -341,13 +368,6 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
341
  $postlist->init();
342
  }
343
 
344
- //Show bar to go back and finish the help
345
- if (current_user_can('manage_options') && ($this->is_page('edit') || strpos($_SERVER['REQUEST_URI'], 'sq_posts') !== false)) {
346
- if (SQ_Classes_Tools::getOption('active_help') <> '' && !SQ_Classes_Tools::getOption('ignore_warn')) {
347
- SQ_Classes_Error::setError(sprintf(__('Go back and complete the Squirrly Tasks for today %sContinue%s', _SQ_PLUGIN_NAME_), '<a href="admin.php?page=sq_' . SQ_Classes_Tools::getOption('active_help') . '" class="sq_button" title="Continue the Help">', '</a>'), 'helpnotice');
348
- }
349
- }
350
-
351
 
352
  }
353
 
@@ -373,7 +393,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
373
  remove_all_actions('print_media_templates');
374
 
375
  //loade the media library
376
- wp_enqueue_media();
377
 
378
  //Set the current post domain with all the data
379
  $this->post = SQ_Classes_ObjController::getClass('SQ_Models_Frontend')->getPost();
8
  /** @var array snippet */
9
  var $options = array();
10
 
 
11
  public function __construct() {
12
  parent::__construct();
13
  add_action('admin_bar_menu', array($this, 'hookTopmenu'), 999);
19
  public function hookInit() {
20
  /* add the plugin menu in admin */
21
  if (current_user_can('manage_options')) {
22
+ try {
23
+ //check if activated
24
+ if (get_transient('sq_activate') == 1) {
25
+ // Delete the redirect transient
26
+ delete_transient('sq_activate');
27
+
28
+ //Check if there are expected upgrades
29
+ SQ_Classes_Tools::checkUpgrade();
30
+
31
+ //Deactivate the QuickSEO plugin
32
+ if (SQ_Classes_Tools::isPluginInstalled('quick-seo')) {
33
+ $quickSEO = _QSS_ROOT_DIR_ . '/index.php';
34
+ if (is_plugin_active(plugin_basename($quickSEO))) {
35
+ delete_transient('qss_activate');
36
+
37
+ deactivate_plugins(plugin_basename($quickSEO), true);
38
+ SQ_Classes_Error::setMessage(sprintf(__("Good news, %s is integrated in Squirrly SEO now and you don't have to run 2 plugins anymore", _SQ_PLUGIN_NAME_), _QSS_PLUGIN_NAME_));
39
+ }
40
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
42
 
43
+ //Deactivate the Premium SEO Pack plugin
44
+ if (SQ_Classes_Tools::isPluginInstalled('premium-seo-pack')) {
45
+ $phpSEO = _PSP_ROOT_DIR_ . '/index.php';
46
+ if (is_plugin_active(plugin_basename($phpSEO))) {
47
+ delete_transient('psp_activate');
48
+ deactivate_plugins(plugin_basename($phpSEO), true);
49
+ SQ_Classes_Error::setMessage(sprintf(__("Good news, %s is integrated in Squirrly SEO now and you don't have to run 2 plugins anymore", _SQ_PLUGIN_NAME_), _PSP_PLUGIN_NAME_));
50
 
51
+ }
52
+ }
 
 
 
 
 
53
 
54
+ //Make sure Squirrly upgrades the settings and seo
55
+ if (SQ_Classes_Tools::getOption('sq_ver') < 8200 && SQ_Classes_Tools::getOption('sq_api') <> '') {
56
+ wp_redirect(admin_url('admin.php?page=sq_dashboard&action=sq_dataupgrade&nonce=' . wp_create_nonce(_SQ_NONCE_ID_)));
57
  }
 
58
 
59
+ wp_safe_redirect(admin_url('admin.php?page=sq_dashboard'));
60
+ die();
 
61
  }
 
62
 
63
+ if (get_transient('sq_rewrite') == 1) {
64
+ // Delete the redirect transient
65
+ delete_transient('sq_rewrite');
66
+ flush_rewrite_rules();
67
+ }
68
+ } catch (Exception $e) {
69
+ SQ_Classes_Error::setMessage(sprintf(__("An error occurred during activation. If this error persists, please contact us at: %s", _SQ_PLUGIN_NAME_), _SQ_SUPPORT_EMAIL_));
70
  }
71
 
 
72
  }
73
  //activate the cron job if not exists
74
  if (!wp_get_schedule('sq_processCron')) {
76
  }
77
 
78
  add_filter('rewrite_rules_array', array(SQ_Classes_ObjController::getClass('SQ_Core_BlockSettingsSeo'), 'rewrite_rules'), 999, 1);
 
 
79
  }
80
 
81
  /**
90
  return;
91
  }
92
 
93
+ if (current_user_can('edit_posts')) {
94
+ $wp_admin_bar->add_node(array(
95
+ 'id' => 'sq_posts',
96
+ 'title' => __('See Your Rank on Google', _SQ_PLUGIN_NAME_),
97
+ 'href' => admin_url('admin.php?page=sq_posts'),
98
+ 'parent' => false
99
+ ));
100
+ }
101
 
102
  if (is_admin()) {
103
  $current_screen = get_current_screen();
 
 
104
  $post = get_post();
105
  if ('post' == $current_screen->base
106
  && ($post_type_object = get_post_type_object($post->post_type))
181
  if (strpos($_SERVER['REQUEST_URI'], '?page=sq_dashboard') !== false) {
182
  SQ_Classes_Tools::saveOptions('sq_dashboard', 1);
183
  }
184
+ if (strpos($_SERVER['REQUEST_URI'], '?page=sq_posts') !== false) {
185
  SQ_Classes_Tools::saveOptions('sq_analytics', 1);
186
  }
187
 
193
  } else {
194
  $time_loaded = get_transient('sq_analytics');
195
  if (time() - $time_loaded > (60 * 60 * 24 * 3) && time() - $time_loaded < (60 * 60 * 24 * 14)) {
196
+ SQ_Classes_Error::setError(sprintf(__('Check out the Squirrly Analytics section. %sClick here%s', _SQ_PLUGIN_NAME_), '<a href="admin.php?page=sq_posts" title="' . __('Squirrly Analytics', _SQ_PLUGIN_NAME_) . '">', '</a>'));
197
  }
198
  }
199
  }
200
 
201
+
202
+ //Show bar to go back and finish the help
203
+ if (current_user_can('manage_options') && ($this->is_page('edit') || strpos($_SERVER['REQUEST_URI'], '?page=sq_posts') !== false)) {
204
+ if (SQ_Classes_Tools::getOption('active_help') <> '' && !SQ_Classes_Tools::getOption('ignore_warn')) {
205
+ SQ_Classes_Error::setError(sprintf(__('Go back and complete the Squirrly Tasks for today %sContinue%s', _SQ_PLUGIN_NAME_), '<a href="admin.php?page=sq_' . SQ_Classes_Tools::getOption('active_help') . '" class="sq_button" title="Continue the Help">', '</a>'), 'helpnotice');
206
+ }
207
+
208
+ if (strpos($_SERVER['REQUEST_URI'], '?page=sq_posts') !== false) {
209
+ $analytics_alert = 0;
210
+ }
211
+ }
212
+
213
  $dashboard_alert = (int)(SQ_Classes_Tools::getOption('sq_dashboard') == 0);
214
 
215
 
216
  ///////////////
217
 
218
  $this->model->addMenu(array(ucfirst(_SQ_NAME_),
219
+ 'Squirrly' . (($analytics_alert) ? SQ_Classes_Tools::showNotices($analytics_alert, 'errors_count') : ''),
220
  'edit_posts',
221
  'sq_dashboard',
222
  null,
232
  ));
233
 
234
  //IF SERP PLUGIN IS NOT INSTALLED
235
+ if (SQ_Classes_Tools::getOption('sq_google_serp_active')) {
236
+ $this->model->addSubmenu(array('sq_dashboard',
237
+ ucfirst(_SQ_NAME_) . __(' Advanced Analytics (Business Level)', _SQ_PLUGIN_NAME_),
238
+ __('Advanced Analytics', _SQ_PLUGIN_NAME_) . ($analytics_alert ? SQ_Classes_Tools::showNotices($analytics_alert, 'errors_count') : ''),
239
+ 'edit_posts',
240
+ 'sq_posts',
241
+ array(SQ_Classes_ObjController::getClass('SQ_Controllers_SerpChecker'), 'init')
242
+ ));
243
+ } else {
244
  $this->model->addSubmenu(array('sq_dashboard',
245
  ucfirst(_SQ_NAME_) . __(' Performance Analytics', _SQ_PLUGIN_NAME_),
246
+ __('Performance <br />Analytics', _SQ_PLUGIN_NAME_) . ($analytics_alert ? SQ_Classes_Tools::showNotices($analytics_alert, 'errors_count') : ''),
247
  'edit_posts',
248
  'sq_posts',
249
  array(SQ_Classes_ObjController::getClass('SQ_Core_BlockPostsAnalytics'), 'init')
258
  array(SQ_Classes_ObjController::getClass('SQ_Core_BlockKeywordResearch'), 'init')
259
  ));
260
 
261
+ $this->model->addSubmenu(array('sq_dashboard',
262
+ ucfirst(_SQ_NAME_) . __(' Briefcase', _SQ_PLUGIN_NAME_),
263
+ __('Briefcase', _SQ_PLUGIN_NAME_),
264
+ 'edit_posts',
265
+ 'sq_briefcase',
266
+ array(SQ_Classes_ObjController::getClass('SQ_Core_BlockBriefcaseKeywords'), 'init')
267
+ ));
268
+
269
  $this->model->addSubmenu(array('sq_dashboard',
270
  ucfirst(_SQ_NAME_) . __(' Live Assistant', _SQ_PLUGIN_NAME_),
271
  __('Live Assistant', _SQ_PLUGIN_NAME_),
293
 
294
  $this->model->addSubmenu(array('sq_dashboard',
295
  ucfirst(_SQ_NAME_) . __(' SEO Settings', _SQ_PLUGIN_NAME_),
296
+ __('SEO Settings', _SQ_PLUGIN_NAME_),
297
  'manage_options',
298
  'sq_seo',
299
  array(SQ_Classes_ObjController::getClass('SQ_Core_BlockSettingsSeo'), 'init')
350
  ));
351
  }
352
 
353
+
354
  foreach ($this->post_type as $type) {
355
  $this->model->addMeta(array('post' . _SQ_NAME_,
356
  ucfirst(_SQ_NAME_),
368
  $postlist->init();
369
  }
370
 
 
 
 
 
 
 
 
371
 
372
  }
373
 
393
  remove_all_actions('print_media_templates');
394
 
395
  //loade the media library
396
+ @wp_enqueue_media();
397
 
398
  //Set the current post domain with all the data
399
  $this->post = SQ_Classes_ObjController::getClass('SQ_Models_Frontend')->getPost();
controllers/Post.php CHANGED
@@ -238,6 +238,11 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
238
  //save for later send to api
239
  update_option('sq_seopost', json_encode($process));
240
  wp_schedule_single_event(time(), 'sq_processApi');
 
 
 
 
 
241
  }
242
 
243
  //Save the keyword for this post
238
  //save for later send to api
239
  update_option('sq_seopost', json_encode($process));
240
  wp_schedule_single_event(time(), 'sq_processApi');
241
+
242
+ //If the queue is too big ... means that the cron is not working
243
+ if(count($process) > 5){
244
+ SQ_Classes_Tools::saveOptions('sq_force_savepost',1);
245
+ }
246
  }
247
 
248
  //Save the keyword for this post
controllers/PostsList.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
- class SQ_Controllers_PostsList extends SQ_Classes_FrontController
4
- {
5
 
6
  /** @var array Posts types in */
7
  private $types = array();
@@ -16,55 +15,55 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
16
  private $is_list = false;
17
  private $posts = array();
18
 
 
19
  /**
20
  * Called in SQ_Controllers_Menu > hookMenu
21
  */
22
- public function init()
23
- {
24
  $this->types = array_map(array($this, '_addPostsType'), SQ_Classes_Tools::getOption('sq_post_types'));
25
  }
26
 
27
- protected function _addPostsType($type)
28
- {
29
- return $type . '_posts';
30
- }
31
-
32
- public function setPosts($posts)
33
- {
34
- if (!empty($posts)) {
35
- $this->posts = $posts;
36
- $this->is_list = true;
37
- }
38
- return $this;
39
- }
40
-
41
  /**
42
  * Create the column and filter for the Posts List
43
  *
44
  */
45
- public function hookInit()
46
- {
 
 
 
47
  $browser = SQ_Classes_Tools::getBrowserInfo();
48
 
49
  if ($browser['name'] == 'IE' && (int)$browser['version'] < 9 && (int)$browser['version'] > 0)
50
  return;
51
 
52
- if (SQ_Classes_Tools::getOption('sq_api') <> '') {
53
- foreach ($this->types as $type) {
 
 
54
 
55
- if (isset($options['hideeditbox-post']) && $options['hideeditbox-post'])
56
- continue;
57
- add_filter('manage_' . $type . '_columns', array($this, 'add_column'), 10, 1);
58
- add_action('manage_' . $type . '_custom_column', array($this, 'add_row'), 10, 2);
59
- }
 
 
 
 
 
 
 
 
 
60
  }
 
61
  }
62
 
63
  /**
64
  * Hook the Wordpress header
65
  */
66
- public function loadHead()
67
- {
68
  parent::hookHead();
69
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia(_SQ_THEME_URL_ . '/css/postslist.css');
70
  }
@@ -75,8 +74,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
75
  * @param array $columns
76
  * @return array
77
  */
78
- public function add_column($columns)
79
- {
80
  $this->loadHead(); //load the js only for post list
81
  $this->is_list = true;
82
 
@@ -89,8 +87,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
89
  * @param object $column
90
  * @param integer $post_id
91
  */
92
- public function add_row($column, $post_id)
93
- {
94
  $cached = false;
95
 
96
  if ($column == $this->column_id) {
@@ -117,8 +114,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
117
  * Hook the Footer
118
  *
119
  */
120
- public function hookFooter()
121
- {
122
  if (!$this->is_list)
123
  return;
124
 
@@ -142,8 +138,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
142
  /**
143
  * Set the javascript variables
144
  */
145
- public function setVars()
146
- {
147
  echo '<script type="text/javascript">
148
  var __sq_article_rank = "' . __('SEO Analytics, by Squirrly', _SQ_PLUGIN_NAME_) . '";
149
  var __sq_refresh = "' . __('Update', _SQ_PLUGIN_NAME_) . '"
@@ -155,8 +150,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
155
  </script>';
156
  }
157
 
158
- public function getScripts()
159
- {
160
  return '<script type="text/javascript">
161
  //load the rank from squirrly
162
  if (typeof sq_script === "undefined"){
@@ -207,8 +201,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
207
  * @param integer $pos
208
  * @return array
209
  */
210
- public function insert($src, $in, $pos)
211
- {
212
  $array = array();
213
  if (is_int($pos))
214
  $array = array_merge(array_slice($src, 0, $pos), $in, array_slice($src, $pos));
@@ -226,8 +219,20 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
226
  * Hook Get/Post action
227
  * @return string
228
  */
229
- public function action()
230
- {
 
 
 
 
 
 
 
 
 
 
 
 
231
  parent::action();
232
  switch (SQ_Classes_Tools::getValue('action')) {
233
  case 'sq_posts_rank':
@@ -306,7 +311,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
306
  }
307
 
308
  if ($json->rank == -1) {
309
- $value = sprintf(__('Not in top 100 for: %s'), '<br />' .$json->keyword);
310
  } elseif ($json->rank == 0) {
311
  $value = __('The URL is Indexed', _SQ_PLUGIN_NAME_);
312
  } elseif ($json->rank > 0) {
@@ -324,7 +329,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
324
  exit(json_encode(array('error' => true)));
325
  } else {
326
  if ($json->rank == -1) {
327
- $value = sprintf(__('Not in top 100 for: %s'), '<br />' .$json->keyword);
328
  } elseif ($json->rank == 0) {
329
  $value = __('The URL is Indexed', _SQ_PLUGIN_NAME_);
330
  } elseif ($json->rank > 0) {
@@ -333,7 +338,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
333
  exit(json_encode(array('rank' => $value)));
334
  }
335
  }
336
- exit(json_encode(array('rank' => $rank)));
337
  }
338
  break;
339
  }
@@ -345,8 +350,7 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController
345
  * @param type $keyword
346
  * @return type
347
  */
348
- private function checkKeyword($keyword, $force = false)
349
- {
350
  $rank = null;
351
 
352
  if ($keyword == '')
1
  <?php
2
 
3
+ class SQ_Controllers_PostsList extends SQ_Classes_FrontController {
 
4
 
5
  /** @var array Posts types in */
6
  private $types = array();
15
  private $is_list = false;
16
  private $posts = array();
17
 
18
+
19
  /**
20
  * Called in SQ_Controllers_Menu > hookMenu
21
  */
22
+ public function init() {
 
23
  $this->types = array_map(array($this, '_addPostsType'), SQ_Classes_Tools::getOption('sq_post_types'));
24
  }
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  /**
27
  * Create the column and filter for the Posts List
28
  *
29
  */
30
+ public function hookInit() {
31
+ if (SQ_Classes_Tools::getOption('sq_api') == '') {
32
+ return;
33
+ }
34
+
35
  $browser = SQ_Classes_Tools::getBrowserInfo();
36
 
37
  if ($browser['name'] == 'IE' && (int)$browser['version'] < 9 && (int)$browser['version'] > 0)
38
  return;
39
 
40
+ foreach ($this->types as $type) {
41
+ add_filter('manage_' . $type . '_columns', array($this, 'add_column'), 10, 1);
42
+ add_action('manage_' . $type . '_custom_column', array($this, 'add_row'), 10, 2);
43
+ }
44
 
45
+ //Update post status
46
+ add_action('before_delete_post', array($this->model, 'hookUpdateStatus'));
47
+ add_action('untrashed_post', array($this->model, 'hookUpdateStatus'));
48
+ add_action('trashed_post', array($this->model, 'hookUpdateStatus'));
49
+ }
50
+
51
+ protected function _addPostsType($type) {
52
+ return $type . '_posts';
53
+ }
54
+
55
+ public function setPosts($posts) {
56
+ if (!empty($posts)) {
57
+ $this->posts = $posts;
58
+ $this->is_list = true;
59
  }
60
+ return $this;
61
  }
62
 
63
  /**
64
  * Hook the Wordpress header
65
  */
66
+ public function loadHead() {
 
67
  parent::hookHead();
68
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia(_SQ_THEME_URL_ . '/css/postslist.css');
69
  }
74
  * @param array $columns
75
  * @return array
76
  */
77
+ public function add_column($columns) {
 
78
  $this->loadHead(); //load the js only for post list
79
  $this->is_list = true;
80
 
87
  * @param object $column
88
  * @param integer $post_id
89
  */
90
+ public function add_row($column, $post_id) {
 
91
  $cached = false;
92
 
93
  if ($column == $this->column_id) {
114
  * Hook the Footer
115
  *
116
  */
117
+ public function hookFooter() {
 
118
  if (!$this->is_list)
119
  return;
120
 
138
  /**
139
  * Set the javascript variables
140
  */
141
+ public function setVars() {
 
142
  echo '<script type="text/javascript">
143
  var __sq_article_rank = "' . __('SEO Analytics, by Squirrly', _SQ_PLUGIN_NAME_) . '";
144
  var __sq_refresh = "' . __('Update', _SQ_PLUGIN_NAME_) . '"
150
  </script>';
151
  }
152
 
153
+ public function getScripts() {
 
154
  return '<script type="text/javascript">
155
  //load the rank from squirrly
156
  if (typeof sq_script === "undefined"){
201
  * @param integer $pos
202
  * @return array
203
  */
204
+ public function insert($src, $in, $pos) {
 
205
  $array = array();
206
  if (is_int($pos))
207
  $array = array_merge(array_slice($src, 0, $pos), $in, array_slice($src, $pos));
219
  * Hook Get/Post action
220
  * @return string
221
  */
222
+ public function action() {
223
+ switch (SQ_Classes_Tools::getValue('action')) {
224
+ case 'inline-save':
225
+ check_ajax_referer('inlineeditnonce', '_inline_edit');
226
+ if (isset($_POST['post_ID']) && ($post_id = (int)$_POST['post_ID']) && isset($_POST['_status']) && $_POST['_status'] <> '') {
227
+ $args = array();
228
+ $args['status'] = $_POST['_status'];
229
+ $args['post_id'] = $post_id;
230
+ SQ_Classes_Action::apiCall('sq/seo/update', $args, 10);
231
+ }
232
+
233
+ return;
234
+ }
235
+
236
  parent::action();
237
  switch (SQ_Classes_Tools::getValue('action')) {
238
  case 'sq_posts_rank':
311
  }
312
 
313
  if ($json->rank == -1) {
314
+ $value = sprintf(__('Not in top 100 for: %s'), '<br />' . $json->keyword);
315
  } elseif ($json->rank == 0) {
316
  $value = __('The URL is Indexed', _SQ_PLUGIN_NAME_);
317
  } elseif ($json->rank > 0) {
329
  exit(json_encode(array('error' => true)));
330
  } else {
331
  if ($json->rank == -1) {
332
+ $value = sprintf(__('Not in top 100 for: %s'), '<br />' . $json->keyword);
333
  } elseif ($json->rank == 0) {
334
  $value = __('The URL is Indexed', _SQ_PLUGIN_NAME_);
335
  } elseif ($json->rank > 0) {
338
  exit(json_encode(array('rank' => $value)));
339
  }
340
  }
341
+ exit(json_encode(array('error' => true)));
342
  }
343
  break;
344
  }
350
  * @param type $keyword
351
  * @return type
352
  */
353
+ private function checkKeyword($keyword, $force = false) {
 
354
  $rank = null;
355
 
356
  if ($keyword == '')
controllers/SerpChecker.php ADDED
@@ -0,0 +1,391 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class SQ_Controllers_SerpChecker extends SQ_Classes_FrontController {
4
+
5
+ public $checkin;
6
+ /** @var SQ_Models_SerpChecker */
7
+ public $model;
8
+ /** @var SQ_Models_SerpCheckerTable */
9
+ public $listTable;
10
+ //
11
+ protected $_tabs;
12
+ protected $_tab;
13
+
14
+ public function init() {
15
+ $this->tabs = array();
16
+
17
+ SQ_Classes_Tools::saveOptions('sq_analytics', 1); //Save analytics viewed
18
+
19
+ if (SQ_Classes_Tools::getOption('sq_api') <> '') {
20
+ $this->checkin = json_decode(SQ_Classes_Action::apiCall('sq/rank-checker/checkin'));
21
+ if (isset($this->checkin->error)) {
22
+ SQ_Classes_Tools::saveOptions('sq_google_serp_active', 0);
23
+ SQ_Classes_ObjController::getClass('SQ_Classes_Error')->setError(sprintf(__('To get back to the Advanced Analytics and see rankings for all the keywords in Briefcase upgrade to %sBusiness Plan%s.'), '<a href="' . SQ_Classes_Tools::getBusinessLink() . '" target="_blank">', '</a>'), 'error');
24
+ }else{
25
+ if (isset($this->checkin->trial) && $this->checkin->trial) {
26
+ SQ_Classes_Tools::saveOptions('sq_google_serp_trial', 1);
27
+ }else{
28
+ SQ_Classes_Tools::saveOptions('sq_google_serp_trial', 0);
29
+ }
30
+ }
31
+
32
+ SQ_Classes_ObjController::getClass('SQ_Classes_Error')->hookNotices();
33
+
34
+ //Prepare the table with records
35
+ $this->listTable = SQ_Classes_ObjController::getClass('SQ_Models_SerpCheckerTable');
36
+ $this->listTable->prepare_items();
37
+
38
+ //Set the Tabs
39
+ $this->_tabs['keywords'] = 'Top Keywords';
40
+ $this->_tab = SQ_Classes_Tools::getValue('tab', false);
41
+
42
+ //SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('//storage.googleapis.com/squirrly/wp480/js/bootstrap.min.js');
43
+ SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('serpchecker');
44
+
45
+ if ($this->_tab <> '') {
46
+ foreach ($this->_tabs as $slug => $value) {
47
+ if ($this->_tab == $slug) {
48
+ echo SQ_Classes_ObjController::getClass('SQ_Core_BlockSerp' . ucfirst($slug))->init()->getView();
49
+ return;
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+ return parent::init();
56
+ }
57
+
58
+ public function action() {
59
+ parent::action();
60
+
61
+ switch (SQ_Classes_Tools::getValue('action')) {
62
+ case 'sq_serp_process':
63
+ SQ_Classes_Tools::setHeader('json');
64
+ $done = false;
65
+
66
+ $paged = (int)get_transient('sq_progress');
67
+ if (!$this->getAllRanks(($paged + 1), 100, false)) {
68
+ exit(json_encode(array('progress' => (min($paged + 1, 9.9) * 10))));
69
+ } else {
70
+ exit(json_encode(array('progress' => 100)));
71
+ }
72
+
73
+ break;
74
+
75
+ case 'sq_serp_refresh':
76
+ if (!current_user_can('edit_posts')) {
77
+ echo json_encode(array('error' => __("You don't have enough pemission to activate this feature", _SQ_PLUGIN_NAME_)));
78
+ exit();
79
+ }
80
+
81
+ SQ_Classes_Tools::setHeader('json');
82
+
83
+ $this->getAllRanks();
84
+
85
+ exit(json_encode(array('refreshed' => true)));
86
+
87
+ break;
88
+
89
+ case 'sq_serp_refresh_post':
90
+ if (!current_user_can('edit_posts')) {
91
+ echo json_encode(array('error' => __("You don't have enough pemission to activate this feature", _SQ_PLUGIN_NAME_)));
92
+ exit();
93
+ }
94
+
95
+ SQ_Classes_Tools::setHeader('json');
96
+ $this->listTable = SQ_Classes_ObjController::getClass('SQ_Models_SerpCheckerTable');
97
+
98
+ $post_id = SQ_Classes_Tools::getValue('id', false);
99
+ $keyword = SQ_Classes_Tools::getValue('keyword', false);
100
+ if ($post_id && $keyword) {
101
+ $args = array();
102
+ $args['post_id'] = $post_id;
103
+ $args['keyword'] = $keyword;
104
+ $json = json_decode(SQ_Classes_Action::apiCall('sq/rank-checker/process-single', $args));
105
+
106
+ if (isset($json->rank) && !empty($json->rank)) {
107
+ $this->model->saveKeyword($post_id, $json->rank);
108
+
109
+ $rank = current($json->rank);
110
+ $date_format = get_option('date_format');
111
+ $time_format = get_option('time_format');
112
+ $timezone = (int)get_option('gmt_offset');
113
+ $rank->datetime = date($date_format . ' ' . $time_format, strtotime($rank->datetime) + $timezone * HOUR_IN_SECONDS);
114
+
115
+ exit(json_encode(array('rank' => $this->listTable->getRankText($rank->rank, $rank->change), 'datetime' => __('Last checked', _SQ_PLUGIN_NAME_) . ': ' . $rank->datetime)));
116
+ } else {
117
+ $rank = $this->model->getKeyword($post_id);
118
+
119
+ $rank = current($json->rank);
120
+ $date_format = get_option('date_format');
121
+ $time_format = get_option('time_format');
122
+ $timezone = (int)get_option('gmt_offset');
123
+ $rank->datetime = date($date_format . ' ' . $time_format, strtotime($rank->datetime) + $timezone * HOUR_IN_SECONDS);
124
+
125
+ exit(json_encode(array('rank' => $this->listTable->getRankText($rank->rank, $rank->change), 'datetime' => __('Last checked', _SQ_PLUGIN_NAME_) . ': ' . $rank->datetime)));
126
+ }
127
+ }
128
+
129
+ exit(json_encode(array('error' => __('Invalid Request', _SQ_PLUGIN_NAME_))));
130
+
131
+ break;
132
+ case 'sq_serp_purgeall':
133
+ if (!current_user_can('edit_posts')) {
134
+ echo json_encode(array('error' => __("You don't have enough pemission to activate this feature", _SQ_PLUGIN_NAME_)));
135
+ exit();
136
+ }
137
+
138
+ SQ_Classes_ObjController::getClass('SQ_Models_SerpChecker')->purgeAllMeta(array('key' => '_src_processed'));
139
+ SQ_Classes_ObjController::getClass('SQ_Models_SerpChecker')->purgeAllMeta(array('key' => '_src_keyword'));
140
+ $this->getAllRanks();
141
+
142
+ SQ_Classes_Error::setMessage(__('Removed successfully! The ranks were updated from Squirry Server'));
143
+ break;
144
+
145
+ }
146
+ }
147
+
148
+
149
+ public function hookHead() {
150
+ return '';
151
+ }
152
+
153
+ public function getNavigationTop() {
154
+ return $this->listTable->display_tablenav('top');
155
+ }
156
+
157
+ public function getNavigationBottom() {
158
+ return $this->listTable->display_tablenav('bottom');
159
+ }
160
+
161
+ public function getHeaderColumns() {
162
+ return $this->listTable->print_column_headers();
163
+ }
164
+
165
+ public function getRows() {
166
+ return $this->listTable->display_rows();
167
+ }
168
+
169
+ /*
170
+ * Set the javascript variables
171
+ */
172
+ public function setVars() {
173
+ echo '<script type="text/javascript">
174
+ var __sq_refresh = "' . __('Update', _SQ_PLUGIN_NAME_) . '"
175
+
176
+ var __sq_dashurl = "' . _SQ_DASH_URL_ . '";
177
+ var __token = "' . SQ_Classes_Tools::getOption('sq_api') . '";
178
+ var __sq_ranknotpublic_text = "' . __('Not Public', _SQ_PLUGIN_NAME_) . '";
179
+ var __sq_couldnotprocess_text = "' . __('Could not process', _SQ_PLUGIN_NAME_) . '";
180
+ </script>';
181
+ }
182
+
183
+ public function getScripts() {
184
+ return '<script type="text/javascript">
185
+ google.load("visualization", "1", {packages: ["corechart"]});
186
+ function drawChart(id, values, reverse) {
187
+ var data = google.visualization.arrayToDataTable(values);
188
+
189
+ var options = {
190
+
191
+ curveType: "function",
192
+ title: "",
193
+ chartArea:{width:"100%",height:"100%"},
194
+ enableInteractivity: "true",
195
+ tooltip: {trigger: "auto"},
196
+ pointSize: "2",
197
+ colors: ["#55b2ca"],
198
+ hAxis: {
199
+ baselineColor: "transparent",
200
+ gridlineColor: "transparent",
201
+ textPosition: "none"
202
+ } ,
203
+ vAxis:{
204
+ direction: ((reverse) ? -1 : 1),
205
+ baselineColor: "transparent",
206
+ gridlineColor: "transparent",
207
+ textPosition: "none"
208
+ }
209
+ };
210
+
211
+ var chart = new google.visualization.LineChart(document.getElementById(id));
212
+ chart.draw(data, options);
213
+ return chart;
214
+ }
215
+ </script>';
216
+ }
217
+
218
+
219
+ /**
220
+ * Get the specified country in Squirrly
221
+ * @return mixed|string
222
+ */
223
+ public function getCountry() {
224
+ if (SQ_Classes_Tools::getOption('sq_google_country') <> '') {
225
+ return SQ_Classes_Tools::getOption('sq_google_country');
226
+ }
227
+ return 'com';
228
+ }
229
+
230
+ /**
231
+ * Get the google language from settings
232
+ * @return string
233
+ */
234
+ public function getLanguage() {
235
+ if (SQ_Classes_Tools::getOption('sq_google_language') <> '') {
236
+ return SQ_Classes_Tools::getOption('sq_google_language');
237
+ }
238
+ return 'en';
239
+ }
240
+
241
+
242
+ /**
243
+ * Do google rank with cron
244
+ *
245
+ * @param int $limit
246
+ */
247
+ public function processCron($limit = 50, $force_ranks = false) {
248
+ set_time_limit(30);
249
+ /* Load the Submit Actions Handler */
250
+ SQ_Classes_ObjController::getClass('SQ_Classes_Tools');
251
+ SQ_Classes_ObjController::getClass('SQ_Classes_Action');
252
+
253
+ //Get saved ranks from API SERVER
254
+ $last_check = (int)SQ_Classes_Tools::getOption('sq_google_last_checked');
255
+
256
+ //If force ranks or every day
257
+ if ($force_ranks || $last_check < strtotime('-6 hours')) {
258
+ $this->getAllRanks();
259
+ }
260
+
261
+ // try {
262
+ // //Find more posts with keywords and send them to API
263
+ // SQ_Classes_Tools::dump('Process queued posts');
264
+ // if ($posts = $this->model->getQueuePost($limit)) {
265
+ // if (!empty($posts))
266
+ // foreach ($posts as $post) {
267
+ // $this->sendPostToApi($post);
268
+ // }
269
+ // }
270
+ // } catch (Exception $e) {
271
+ //
272
+ // }
273
+
274
+
275
+ }
276
+
277
+ /**
278
+ * Send the post to API for SERP Check
279
+ * @param $post
280
+ */
281
+ public function sendPostToApi($post) {
282
+ global $wp_query;
283
+
284
+ if ($wp_query) {
285
+ if ($keyword = $this->model->getKeywordsFromPost($post)) {
286
+ $args = array();
287
+
288
+ $args['post_id'] = $post->ID;
289
+ $args['permalink'] = get_permalink($post->ID);
290
+ $args['country'] = $this->getCountry();
291
+ $args['language'] = $this->getLanguage();
292
+ $args['keywords'] = json_encode(array($keyword));
293
+
294
+ SQ_Classes_Action::apiCall('sq/rank-checker/save-keywords', $args);
295
+ }
296
+
297
+ //save post verified and exclude from queue
298
+ $this->model->saveProcessed($post->ID);
299
+
300
+ }
301
+
302
+ }
303
+
304
+ /**
305
+ * Get all ranks from API Server
306
+ */
307
+ public function getAllRanks($paged = 1, $per_page = 100, $loop = true, $cnt = 0) {
308
+ $args = array('paged' => $paged, 'per_page' => $per_page);
309
+ set_transient('sq_progress', $paged, 60);
310
+
311
+ $json = json_decode(SQ_Classes_Action::apiCall('sq/rank-checker/get-ranks', $args));
312
+ if (isset($json->ranks)) {
313
+ if (!empty($json->ranks)) {
314
+ foreach ($json->ranks as $post_id => $rank) {
315
+ $status = get_post_status($post_id);
316
+ if ($status <> 'publish') {
317
+ $args = array();
318
+ $args['status'] = ($status ? $status : 'deleted');
319
+ $args['post_id'] = $post_id;
320
+ //Make sure the API has the correct status of the post
321
+ SQ_Classes_Action::apiCall('sq/seo/update', $args, 10);
322
+
323
+ //delete the records for this post to insert all the keywords fresh
324
+ $this->model->purgeMeta($post_id, array('key' => '_src_keyword'));
325
+ continue;
326
+ } else {
327
+ $this->model->saveKeyword($post_id, $rank);
328
+
329
+ }
330
+ }
331
+ } else {
332
+ SQ_Classes_ObjController::getClass('SQ_Models_SerpChecker')->purgeAllMeta(array('key' => '_src_keyword'));
333
+ }
334
+ }
335
+
336
+ if ($cnt < 20 && $loop) { //prevent infinite loops
337
+ if (isset($json->done) && !$json->done) {
338
+ $this->getAllRanks(($paged + 1), $per_page, $loop, ($cnt + 1));
339
+ }
340
+ }
341
+
342
+ //Save the summary if received
343
+ if (isset($json->info) && isset($json->info->keywords)) {
344
+ SQ_Classes_Tools::saveOptions('sq_google_last_info', json_encode($json->info));
345
+ }
346
+
347
+ if (isset($json->done) && $json->done) {
348
+ SQ_Classes_Tools::saveOptions('sq_google_last_checked', time());
349
+
350
+ return true;
351
+ }
352
+
353
+ return false;
354
+
355
+ }
356
+
357
+
358
+ /**
359
+ * Get all ranks from API Server
360
+ *
361
+ * public function getChangedRanks($paged = 1, $per_page = 100, $cnt = 0) {
362
+ * $args = array('paged' => $paged, 'per_page' => $per_page);
363
+ * $json = json_decode(SQ_Classes_Action::apiCall('sq/rank-checker/get-changes', $args));
364
+ *
365
+ * if (isset($json->ranks) && !empty($json->ranks)) {
366
+ * foreach ($json->ranks as $post_id => $rank) {
367
+ * $this->model->saveKeyword($post_id, $rank);
368
+ * }
369
+ * }
370
+ *
371
+ * if ($cnt < 20) { //prevent infinite loops
372
+ * if (isset($json->done) && !$json->done) {
373
+ * $this->getChangedRanks(($paged + 1), $per_page, ($cnt + 1));
374
+ * }
375
+ * }
376
+ *
377
+ * SQ_Classes_Tools::saveOptions('sq_google_last_checked', time());
378
+ *
379
+ * // print_R($json->info);
380
+ * // exit();
381
+ * //Save the summary if received
382
+ * if (isset($json->info) && !empty($json->info->keywords)) {
383
+ * SQ_Classes_Tools::saveOptions('sq_google_last_info', json_encode($json->info));
384
+ * }
385
+ * }
386
+ */
387
+ public function getKeywordsFound() {
388
+ return $this->model->countKeywords();
389
+ }
390
+
391
+ }
controllers/Sitemaps.php CHANGED
</
@@ -46,7 +46,7 @@ class SQ_Controllers_Sitemaps extends SQ_Classes_FrontController {
46
  $page = 0;
47
 
48
  foreach ($stemaplist as $request => $sitemap) {
49
- if (isset($sitemap[0]) && $sitemap[1] && str_replace('/', '', $parseurl['path']) == $sitemap[0]) {
50
  $wp_query->is_404 = false;
51
  $wp_query->is_feed = true;
52
 
@@ -76,27 +76,31 @@ class SQ_Controllers_Sitemaps extends SQ_Classes_FrontController {
76
  * Listen the feed call from wordpress
77
  * @param string $request
78
  * @param integer $page
79
- * @return SQ_Controllers_Sitemaps
80
  */
81
  public function feedRequest($request = null, $page = 1) {
82
- global $wp_query;
83
- $query = array();
84
 
85
  if (isset($request) && strpos($request, 'sitemap') !== false) {
86
  $sq_sitemap = SQ_Classes_Tools::getOption('sq_sitemap');
87
  $this->model->type = $request;
 
 
88
 
89
  if ($request == 'sitemap') { //if sitemapindex, return
90
- return $wp_query;
91
  }
92
 
93
  if ($this->model->type == 'sitemap-news') {
94
  $this->posts_limit = $this->news_limit;
95
  }
96
 
 
 
 
 
97
  //init the query
98
- $query = array(
99
- 'sq_feed' => $this->model->type,
100
  'post_type' => array('post'),
101
  'tax_query' => array(),
102
  'post_status' => 'publish',
@@ -128,7 +132,7 @@ class SQ_Controllers_Sitemaps extends SQ_Classes_FrontController {
128
  add_filter('get_terms_fields', array($this, 'customTaxFilter'), 5, 2);
129
  break;
130
  case 'sitemap-page':
131
- $query['post_type'] = array('page');
132
  break;
133
  case 'sitemap-author':
134
  add_filter('sq-sitemap-authors', array($this, 'authorFilter'), 5);
@@ -143,7 +147,7 @@ class SQ_Controllers_Sitemaps extends SQ_Classes_FrontController {
143
 
144
  foreach ($types as $type) {
145
  $type_data = get_post_type_object($type);
146
- if ((isset($type_data->rewrite['feeds']) && $type_data->rewrite['feeds'] == 1) || (isset($type_data->feeds) && $type_data->feeds == 1)) {
147
  continue;
148
  }
149
  unset($types[$type]);
@@ -153,27 +157,21 @@ class SQ_Controllers_Sitemaps extends SQ_Classes_FrontController {
153
  array_push($types, 'custom-post');