SEO SQUIRRLY™ - Version 10.2.00

Version Description

  • 10/21/2020 =
  • Update - Keyword Research Algoritm get better results with the last Google Algorithm upgrades
  • Update - Bulk SEO and Focus Pages works with keywords having special chars
  • Update - Keyword Research, Briefcase and Live Assistant work with special chars and all languages
  • Update - Show in Briefcase the posts where a specific keyword was used
  • Update - Show in Briefcase the search volume for a keyword if exists
  • Update - The user experience in Focus Pages when the page is indexed
  • Update - Added the option to disconnect and send feedback on plugin deactivation
  • Update - Sitemap XML works with special chars in title, description and keywords
  • Update - Squirrly SEO tracking tool supports Google Analytics 4
  • Fixed - Escaped all translations and variables in the plugin to prevent errors on plugin translation
  • Fixed - Corrected all the numbers format in Focus Pages, SEO Audit, Briefcase, Rankings
  • Fixed - Show the decoded arabic URLs on all the plugin places
  • Fixed - Compatibility with plugins like Polylang, Woocommerce
Download this release

Release Info

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

Code changes from version 10.1.07 to 10.2.00

Files changed (49) hide show
  1. classes/ActionController.php +9 -3
  2. classes/BlockController.php +3 -14
  3. classes/DisplayController.php +1 -3
  4. classes/Error.php +11 -17
  5. classes/FrontController.php +2 -2
  6. classes/RemoteController.php +98 -76
  7. classes/helpers/DevKit.php +10 -6
  8. classes/helpers/Sanitize.php +105 -13
  9. classes/helpers/Tools.php +33 -23
  10. config.json +2 -1
  11. config/config.php +32 -32
  12. config/paths.php +15 -14
  13. controllers/Account.php +1 -1
  14. controllers/Api.php +13 -13
  15. controllers/Assistant.php +9 -9
  16. controllers/Audits.php +14 -14
  17. controllers/BulkSeo.php +3 -3
  18. controllers/CheckSeo.php +10 -8
  19. controllers/Dashboard.php +1 -1
  20. controllers/FocusPages.php +14 -14
  21. controllers/Frontend.php +3 -3
  22. controllers/Menu.php +21 -15
  23. controllers/Overview.php +1 -1
  24. controllers/Patterns.php +15 -13
  25. controllers/Post.php +35 -33
  26. controllers/PostsList.php +13 -13
  27. controllers/Ranking.php +12 -12
  28. controllers/Research.php +76 -76
  29. controllers/SeoSettings.php +59 -60
  30. controllers/Sitemaps.php +2 -2
  31. controllers/Snippet.php +8 -8
  32. controllers/Uninstall.php +16 -0
  33. core/BlockAudits.php +0 -43
  34. core/BlockFocusPages.php +0 -65
  35. core/BlockKRFound.php +0 -16
  36. core/BlockKRHistory.php +0 -16
  37. core/BlockRanks.php +0 -62
  38. core/BlockSEOIssues.php +0 -14
  39. core/BlockSupport.php +27 -37
  40. core/Blocklogin.php +10 -10
  41. debug/index.php +2 -2
  42. languages/squirrly-seo-cs_CZ.mo +0 -0
  43. languages/squirrly-seo-cs_CZ.po +2169 -1915
  44. languages/squirrly-seo-de_DE.mo +0 -0
  45. languages/squirrly-seo-de_DE.po +2665 -2010
  46. languages/squirrly-seo-en_US.mo +0 -0
  47. languages/squirrly-seo-ro_RO.mo +0 -0
  48. languages/squirrly-seo-ro_RO.po +2032 -1835
  49. languages/{squirrly-seo-en_US.po → squirrly-seo.pot} +312 -386
classes/ActionController.php CHANGED
@@ -70,8 +70,13 @@ class SQ_Classes_ActionController extends SQ_Classes_FrontController {
70
  *
71
  */
72
  public function getActions() {
 
 
 
 
73
  $this->actions = array();
74
  $cur_action = SQ_Classes_Helpers_Tools::getValue('action', false);
 
75
  $sq_nonce = SQ_Classes_Helpers_Tools::getValue('sq_nonce', false);
76
 
77
  if (!function_exists('is_user_logged_in')) {
@@ -83,12 +88,12 @@ class SQ_Classes_ActionController extends SQ_Classes_FrontController {
83
  /* if config allready in cache */
84
  if (!isset(self::$config)) {
85
  $config_file = _SQ_ROOT_DIR_ . 'config.json';
86
- if (!file_exists($config_file)) {
87
  return;
88
  }
89
 
90
  /* load configuration blocks data from core config files */
91
- self::$config = json_decode(file_get_contents($config_file), 1);
92
  }
93
 
94
  if (is_array(self::$config))
@@ -117,10 +122,11 @@ class SQ_Classes_ActionController extends SQ_Classes_FrontController {
117
  }
118
  }
119
 
 
120
  if (!empty($this->actions)) {
121
  /* add the actions in WP */
122
  foreach ($this->actions as $actions) {
123
- if (SQ_Classes_Helpers_Tools::isAjax()) {
124
  check_ajax_referer(_SQ_NONCE_ID_, 'sq_nonce');
125
  add_action('wp_ajax_' . $cur_action, array(SQ_Classes_ObjController::getClass($actions['class']), 'action'));
126
  } else {
70
  *
71
  */
72
  public function getActions() {
73
+ global $wp_filesystem;
74
+ require_once(ABSPATH . '/wp-admin/includes/file.php');
75
+ WP_Filesystem();
76
+
77
  $this->actions = array();
78
  $cur_action = SQ_Classes_Helpers_Tools::getValue('action', false);
79
+ $http_referer = SQ_Classes_Helpers_Tools::getValue('_wp_http_referer', false);
80
  $sq_nonce = SQ_Classes_Helpers_Tools::getValue('sq_nonce', false);
81
 
82
  if (!function_exists('is_user_logged_in')) {
88
  /* if config allready in cache */
89
  if (!isset(self::$config)) {
90
  $config_file = _SQ_ROOT_DIR_ . 'config.json';
91
+ if (!$wp_filesystem->exists($config_file)) {
92
  return;
93
  }
94
 
95
  /* load configuration blocks data from core config files */
96
+ self::$config = json_decode($wp_filesystem->get_contents($config_file), 1);
97
  }
98
 
99
  if (is_array(self::$config))
122
  }
123
  }
124
 
125
+ //If there is an action found in the config.js file
126
  if (!empty($this->actions)) {
127
  /* add the actions in WP */
128
  foreach ($this->actions as $actions) {
129
+ if (SQ_Classes_Helpers_Tools::isAjax() && !$http_referer) {
130
  check_ajax_referer(_SQ_NONCE_ID_, 'sq_nonce');
131
  add_action('wp_ajax_' . $cur_action, array(SQ_Classes_ObjController::getClass($actions['class']), 'action'));
132
  } else {
classes/BlockController.php CHANGED
@@ -25,7 +25,7 @@ class SQ_Classes_BlockController {
25
 
26
  /* create the model and view instances */
27
  $model_classname = str_replace('Core', 'Models', $this->name);
28
- if(SQ_Classes_ObjController::getClassPath($model_classname)) {
29
  $this->model = SQ_Classes_ObjController::getClass($model_classname);
30
  }
31
  }
@@ -45,9 +45,9 @@ class SQ_Classes_BlockController {
45
  if ($this->flush) {
46
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia($class['name']);
47
 
48
- echo $this->getView($class['name']);
49
  } else {
50
- return $this->getView($class['name']);
51
  }
52
 
53
  return '';
@@ -73,17 +73,6 @@ class SQ_Classes_BlockController {
73
  echo $this->init();
74
  }
75
 
76
- public function preloadSettings() {
77
- if (SQ_Classes_Helpers_Tools::getOption('sq_api') <> '') {
78
- echo '<script>
79
- var __blog_url = "' . get_bloginfo('url') . '";
80
- var __token = "' . SQ_Classes_Helpers_Tools::getOption('sq_api') . '";
81
- var __language = "' . get_bloginfo('language') . '";
82
- var __apiv2_url = "' . _SQ_APIV2_URL_ . '";
83
- </script>';
84
- }
85
- }
86
-
87
  /**
88
  * This function is called from Ajax class as a wp_ajax_action
89
  *
25
 
26
  /* create the model and view instances */
27
  $model_classname = str_replace('Core', 'Models', $this->name);
28
+ if (SQ_Classes_ObjController::getClassPath($model_classname)) {
29
  $this->model = SQ_Classes_ObjController::getClass($model_classname);
30
  }
31
  }
45
  if ($this->flush) {
46
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia($class['name']);
47
 
48
+ echo (string)$this->getView($class['name']);
49
  } else {
50
+ return (string)$this->getView($class['name']);
51
  }
52
 
53
  return '';
73
  echo $this->init();
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
76
  /**
77
  * This function is called from Ajax class as a wp_ajax_action
78
  *
classes/DisplayController.php CHANGED
@@ -75,7 +75,6 @@ class SQ_Classes_DisplayController {
75
  }
76
  }
77
 
78
-
79
  }
80
 
81
  if ($js_uri <> '') {
@@ -109,15 +108,14 @@ class SQ_Classes_DisplayController {
109
  $file = apply_filters('sq_view', _SQ_THEME_DIR_ . $block . '.php', $block);
110
 
111
  if (file_exists($file)) {
112
-
113
  ob_start();
114
  include($file);
115
  return ob_get_clean();
116
  }
117
 
118
  } catch (Exception $e) {
119
- // SQ_Debug::dump($file, $e->getMessage(), $e->getFile(), $e->getLine());
120
  }
 
121
  return false;
122
  }
123
 
75
  }
76
  }
77
 
 
78
  }
79
 
80
  if ($js_uri <> '') {
108
  $file = apply_filters('sq_view', _SQ_THEME_DIR_ . $block . '.php', $block);
109
 
110
  if (file_exists($file)) {
 
111
  ob_start();
112
  include($file);
113
  return ob_get_clean();
114
  }
115
 
116
  } catch (Exception $e) {
 
117
  }
118
+
119
  return false;
120
  }
121
 
classes/Error.php CHANGED
@@ -22,6 +22,7 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
22
  if (count(self::$errors) > 0) {
23
  return self::$errors[0]['text'];
24
  }
 
25
  return false;
26
  }
27
 
@@ -46,6 +47,10 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
46
  'text' => $error);
47
  }
48
 
 
 
 
 
49
  public static function isError() {
50
  if(!empty(self::$errors)){
51
  foreach (self::$errors as $error){
@@ -56,6 +61,11 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
56
  }
57
  }
58
 
 
 
 
 
 
59
  public static function setMessage($message = '', $id = '') {
60
  self::$errors[] = array(
61
  'id' => $id,
@@ -80,29 +90,15 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
80
  self::showError($error['text'] . " ", $error['id']);
81
  break;
82
 
83
- case 'helpnotice':
84
- if (!SQ_Classes_Helpers_Tools::getOption('ignore_warn')) {
85
- 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>";
86
- self::showError($error['text'] . " " . self::$switch_off, $error['id'], 'sq_helpnotice');
87
- }
88
- break;
89
-
90
  case 'success':
91
  self::showError($error['text'] . " ", $error['id'], 'sq_success');
92
  break;
93
 
94
- case 'trial':
95
- if (SQ_Classes_Helpers_Tools::getOption('sq_google_alert_trial')) {
96
- 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>";
97
- self::showError($error['text'] . " " . self::$switch_off, $error['id'], 'sq_success');
98
- }
99
- break;
100
  default:
101
 
102
  self::showError($error['text'], $error['id']);
103
  }
104
  }
105
- //self::$errors = array();
106
  }
107
 
108
  /**
@@ -120,7 +116,7 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
120
  ob_end_clean();
121
  }
122
 
123
- return $message;
124
  }
125
 
126
  /**
@@ -135,8 +131,6 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
135
  public static function showError($message, $id = '', $type = 'sq_error') {
136
  if (file_exists(_SQ_THEME_DIR_ . 'Notices.php')) {
137
  include(_SQ_THEME_DIR_ . 'Notices.php');
138
- } else {
139
- echo $message;
140
  }
141
  }
142
 
22
  if (count(self::$errors) > 0) {
23
  return self::$errors[0]['text'];
24
  }
25
+
26
  return false;
27
  }
28
 
47
  'text' => $error);
48
  }
49
 
50
+ /**
51
+ * Check if there is a Squirrly Error triggered
52
+ * @return bool
53
+ */
54
  public static function isError() {
55
  if(!empty(self::$errors)){
56
  foreach (self::$errors as $error){
61
  }
62
  }
63
 
64
+ /**
65
+ * Set a success message
66
+ * @param string $message
67
+ * @param string $id
68
+ */
69
  public static function setMessage($message = '', $id = '') {
70
  self::$errors[] = array(
71
  'id' => $id,
90
  self::showError($error['text'] . " ", $error['id']);
91
  break;
92
 
 
 
 
 
 
 
 
93
  case 'success':
94
  self::showError($error['text'] . " ", $error['id'], 'sq_success');
95
  break;
96
 
 
 
 
 
 
 
97
  default:
98
 
99
  self::showError($error['text'], $error['id']);
100
  }
101
  }
 
102
  }
103
 
104
  /**
116
  ob_end_clean();
117
  }
118
 
119
+ return (string)$message;
120
  }
121
 
122
  /**
131
  public static function showError($message, $id = '', $type = 'sq_error') {
132
  if (file_exists(_SQ_THEME_DIR_ . 'Notices.php')) {
133
  include(_SQ_THEME_DIR_ . 'Notices.php');
 
 
134
  }
135
  }
136
 
classes/FrontController.php CHANGED
@@ -60,9 +60,9 @@ class SQ_Classes_FrontController {
60
  if ($this->flush) {
61
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia($class['name']);
62
 
63
- echo $this->getView($class['name']);
64
  } else {
65
- return $this->getView($class['name']);
66
  }
67
 
68
  return '';
60
  if ($this->flush) {
61
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia($class['name']);
62
 
63
+ echo (string)$this->getView($class['name']);
64
  } else {
65
+ return (string)$this->getView($class['name']);
66
  }
67
 
68
  return '';
classes/RemoteController.php CHANGED
@@ -42,7 +42,6 @@ class SQ_Classes_RemoteController {
42
  //call it with http to prevent curl issues with ssls
43
  $url = self::cleanUrl(_SQ_APIV2_URL_ . $module . "?" . $parameters);
44
 
45
- //print_R($options) . '<br>';echo $url . '<br>';exit();
46
  if (!isset(self::$cache[md5($url)])) {
47
  if ($options['method'] == 'post') {
48
  $options['body'] = $args;
@@ -260,11 +259,11 @@ class SQ_Classes_RemoteController {
260
 
261
  //prevent throttling on API
262
  if ($json->error == 'too_many_requests') {
263
- SQ_Classes_Error::setError(__("Too many API attempts, please slow down the request.", _SQ_PLUGIN_NAME_));
264
  SQ_Classes_Error::hookNotices();
265
  return (new WP_Error('api_error', $json->error));
266
  } elseif ($json->error == 'maintenance') {
267
- SQ_Classes_Error::setError(__("Squirrly Cloud is down for a bit of maintenance right now. But we'll be back in a minute.", _SQ_PLUGIN_NAME_));
268
  SQ_Classes_Error::hookNotices();
269
  return (new WP_Error('maintenance', $json->error));
270
  }
@@ -293,6 +292,30 @@ class SQ_Classes_RemoteController {
293
  return $json->data;
294
  }
295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  /**
297
  * Get the API stats for this blog
298
  * @return array
@@ -323,74 +346,50 @@ class SQ_Classes_RemoteController {
323
  //Get last month articles
324
  $stats['all_articles'] = array();
325
  $stats['all_articles']['value'] = ((int)$data->optimized_articles);
326
- $stats['all_articles']['text'] = __('Articles optimized so far', _SQ_PLUGIN_NAME_);
327
  $stats['all_articles']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_assistant', 'assistant');
328
- $stats['all_articles']['linktext'] = __('add post', _SQ_PLUGIN_NAME_);
329
 
330
  //Get last month articles
331
  $stats['avg_articles'] = array();
332
  $stats['avg_articles']['value'] = ((int)$data->average_optimization);
333
- $stats['avg_articles']['text'] = __('Average optimization', _SQ_PLUGIN_NAME_);
334
  $stats['avg_articles']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_assistant');
335
- $stats['avg_articles']['linktext'] = __('add post', _SQ_PLUGIN_NAME_);
336
 
337
  //Get all keyword researched
338
  $stats['all_researches'] = array();
339
  $stats['all_researches']['value'] = (int)$data->kr_research;
340
- $stats['all_researches']['text'] = __('Keyword Researches', _SQ_PLUGIN_NAME_);
341
  $stats['all_researches']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_research');
342
- $stats['all_researches']['linktext'] = __('do research', _SQ_PLUGIN_NAME_);
343
 
344
  //Get all keywords from briefcase
345
  $stats['all_briefcase'] = array();
346
  $stats['all_briefcase']['value'] = (int)$data->kr_in_briefcase;
347
- $stats['all_briefcase']['text'] = __('Keywords stored in Squirrly Briefcase', _SQ_PLUGIN_NAME_);
348
  $stats['all_briefcase']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_research', 'briefcase');
349
- $stats['all_briefcase']['linktext'] = __('add keyword', _SQ_PLUGIN_NAME_);
350
 
351
  //Get the top 100 ranking
352
  $stats['top_ranking'] = array();
353
  $stats['top_ranking']['value'] = (int)$data->ranked_top;
354
- $stats['top_ranking']['text'] = __('Pages ranking in top 100 Google', _SQ_PLUGIN_NAME_);
355
  $stats['top_ranking']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_rankings');
356
- $stats['top_ranking']['linktext'] = __('see rankings', _SQ_PLUGIN_NAME_);
357
 
358
  //Get last month audits
359
  $stats['lm_audit'] = array();
360
  $stats['lm_audit']['value'] = (int)$data->audits_made;
361
- $stats['lm_audit']['text'] = __('SEO Audits', _SQ_PLUGIN_NAME_);
362
  $stats['lm_audit']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_audits');
363
- $stats['lm_audit']['linktext'] = __('see audits', _SQ_PLUGIN_NAME_);
364
  }
365
  }
366
 
367
  return $stats;
368
  }
369
 
370
- /******************************** NOTIFICATIONS *********************/
371
- /**
372
- * Get the Notifications from API for the current blog
373
- * @return array|WP_Error
374
- */
375
- public static function getNotifications() {
376
- self::$apimethod = 'get'; //call method
377
-
378
- $notifications = array();
379
- if ($json = json_decode(self::apiCall('api/audits/notifications', array()))) {
380
-
381
- if (isset($json->error) && $json->error <> '') {
382
- return (new WP_Error('api_error', $json->error));
383
- } elseif (!isset($json->data)) {
384
- return (new WP_Error('api_error', 'no_data'));
385
- }
386
-
387
- $notifications = $json->data;
388
-
389
- }
390
-
391
- return $notifications;
392
- }
393
-
394
  /**
395
  * Get audits from API
396
  *
@@ -415,6 +414,25 @@ class SQ_Classes_RemoteController {
415
  return $json->data->audits;
416
  }
417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  /******************************** BRIEFCASE *********************/
419
  public static function getBriefcase($args = array()) {
420
  self::$apimethod = 'get'; //call method
@@ -1216,7 +1234,7 @@ class SQ_Classes_RemoteController {
1216
  public static function saveSettings($args) {
1217
  self::$apimethod = 'post'; //call method
1218
 
1219
- self::apiCall('api/user/settings', array('settings' => json_encode($args)));
1220
  }
1221
 
1222
  /**
@@ -1249,6 +1267,7 @@ class SQ_Classes_RemoteController {
1249
  global $post;
1250
  $referer = '';
1251
 
 
1252
  $sq_postID = (isset($post->ID) ? $post->ID : 0);
1253
 
1254
  if (SQ_Classes_Helpers_Tools::isPluginInstalled('elementor/elementor.php')) {
@@ -1276,43 +1295,46 @@ class SQ_Classes_RemoteController {
1276
  frontend_css: "' . _SQ_ASSETS_URL_ . 'css/frontend' . (SQ_DEBUG ? '' : '.min') . '.css",
1277
  postID: "' . $sq_postID . '",
1278
  prevNonce: "' . wp_create_nonce('post_preview_' . $sq_postID) . '",
1279
- __keyword: "' . __('Keyword:', _SQ_PLUGIN_NAME_) . '",
1280
- __date: "' . __('date', _SQ_PLUGIN_NAME_) . '",
1281
- __saved: "' . __('Saved!', _SQ_PLUGIN_NAME_) . '",
1282
- __readit: "' . __('Read it!', _SQ_PLUGIN_NAME_) . '",
1283
- __insertit: "' . __('Insert it!', _SQ_PLUGIN_NAME_) . '",
1284
- __reference: "' . __('Reference', _SQ_PLUGIN_NAME_) . '",
1285
- __insertasbox: "' . __('Insert as box', _SQ_PLUGIN_NAME_) . '",
1286
- __addlink: "' . __('Insert Link', _SQ_PLUGIN_NAME_) . '",
1287
- __notrelevant: "' . __('Not relevant?', _SQ_PLUGIN_NAME_) . '",
1288
- __insertparagraph: "' . __('Insert in your article', _SQ_PLUGIN_NAME_) . '",
1289
- __ajaxerror: "' . __(':( An error occurred while processing your request. Please try again', _SQ_PLUGIN_NAME_) . '",
1290
- __nofound: "' . __('No results found!', _SQ_PLUGIN_NAME_) . '",
1291
- __sq_photo_copyright: "' . __('[ ATTRIBUTE: Please check: %s to find out how to attribute this image ]', _SQ_PLUGIN_NAME_) . '",
1292
- __has_attributes: "' . __('Has creative commons attributes', _SQ_PLUGIN_NAME_) . '",
1293
- __no_attributes: "' . __('No known copyright restrictions', _SQ_PLUGIN_NAME_) . '",
1294
- __noopt: "' . __('You haven`t used Squirrly SEO to optimize your article. Do you want to optimize for a keyword before publishing?', _SQ_PLUGIN_NAME_) . '",
1295
- __subscription_expired: "' . __('Your Subscription has Expired', _SQ_PLUGIN_NAME_) . '",
1296
- __no_briefcase: "' . __('There are no keywords saved in briefcase yet', _SQ_PLUGIN_NAME_) . '",
1297
- __fulloptimized: "' . __('Congratulations! Your article is 100% optimized!', _SQ_PLUGIN_NAME_) . '",
1298
- __toomanytimes: "' . __('appears too many times. Try to remove %s of them', _SQ_PLUGIN_NAME_) . '",
1299
- __writemorewords: "' . __('write %s more words', _SQ_PLUGIN_NAME_) . '",
1300
- __keywordinintroduction: "' . __('Add the keyword in the %s of your article', _SQ_PLUGIN_NAME_) . '",
1301
- __clicktohighlight: "' . __('Click to keep the highlight on', _SQ_PLUGIN_NAME_) . '",
1302
- __introduction: "' . __('introduction', _SQ_PLUGIN_NAME_) . '",
1303
- __morewordsafter: "' . __('Write more words after the %s keyword', _SQ_PLUGIN_NAME_) . '",
1304
- __orusesynonyms: "' . __('or use synonyms', _SQ_PLUGIN_NAME_) . '",
1305
- __addmorewords: "' . __('add %s more word(s)', _SQ_PLUGIN_NAME_) . '",
1306
- __removewords: "' . __('or remove %s word(s)', _SQ_PLUGIN_NAME_) . '",
1307
- __addmorekeywords: "' . __('add %s more keyword(s)', _SQ_PLUGIN_NAME_) . '",
1308
- __addminimumwords: "' . __('write %s more words to start calculating', _SQ_PLUGIN_NAME_) . '",
1309
- __add_to_briefcase: "' . __('Add to Briefcase', _SQ_PLUGIN_NAME_) . '",
1310
- __add_keyword_briefcase: "' . __('Add Keyword to Briefcase', _SQ_PLUGIN_NAME_) . '",
1311
- __usekeyword: "' . __('Select', _SQ_PLUGIN_NAME_) . '",
1312
- __new_post_title: "' . __('Auto Draft') . '",
1313
- __frontend_optimized: "' . __('You’ve already used the Live Assistant to optimize this post when creating it in your Page Builder. Please go back and resume your optimization work there.', _SQ_PLUGIN_NAME_) . '",
 
 
 
 
1314
  };
1315
-
1316
  })(jQuery);
1317
  </script>';
1318
 
42
  //call it with http to prevent curl issues with ssls
43
  $url = self::cleanUrl(_SQ_APIV2_URL_ . $module . "?" . $parameters);
44
 
 
45
  if (!isset(self::$cache[md5($url)])) {
46
  if ($options['method'] == 'post') {
47
  $options['body'] = $args;
259
 
260
  //prevent throttling on API
261
  if ($json->error == 'too_many_requests') {
262
+ SQ_Classes_Error::setError(esc_html__("Too many API attempts, please slow down the request.", _SQ_PLUGIN_NAME_));
263
  SQ_Classes_Error::hookNotices();
264
  return (new WP_Error('api_error', $json->error));
265
  } elseif ($json->error == 'maintenance') {
266
+ SQ_Classes_Error::setError(esc_html__("Squirrly Cloud is down for a bit of maintenance right now. But we'll be back in a minute.", _SQ_PLUGIN_NAME_));
267
  SQ_Classes_Error::hookNotices();
268
  return (new WP_Error('maintenance', $json->error));
269
  }
292
  return $json->data;
293
  }
294
 
295
+ /******************************** NOTIFICATIONS *********************/
296
+ /**
297
+ * Get the Notifications from API for the current blog
298
+ * @return array|WP_Error
299
+ */
300
+ public static function getNotifications() {
301
+ self::$apimethod = 'get'; //call method
302
+
303
+ $notifications = array();
304
+ if ($json = json_decode(self::apiCall('api/audits/notifications', array()))) {
305
+
306
+ if (isset($json->error) && $json->error <> '') {
307
+ return (new WP_Error('api_error', $json->error));
308
+ } elseif (!isset($json->data)) {
309
+ return (new WP_Error('api_error', 'no_data'));
310
+ }
311
+
312
+ $notifications = $json->data;
313
+
314
+ }
315
+
316
+ return $notifications;
317
+ }
318
+
319
  /**
320
  * Get the API stats for this blog
321
  * @return array
346
  //Get last month articles
347
  $stats['all_articles'] = array();
348
  $stats['all_articles']['value'] = ((int)$data->optimized_articles);
349
+ $stats['all_articles']['text'] = esc_html__("Articles optimized so far", _SQ_PLUGIN_NAME_);
350
  $stats['all_articles']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_assistant', 'assistant');
351
+ $stats['all_articles']['linktext'] = esc_html__("add post", _SQ_PLUGIN_NAME_);
352
 
353
  //Get last month articles
354
  $stats['avg_articles'] = array();
355
  $stats['avg_articles']['value'] = ((int)$data->average_optimization);
356
+ $stats['avg_articles']['text'] = esc_html__("Average optimization", _SQ_PLUGIN_NAME_);
357
  $stats['avg_articles']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_assistant');
358
+ $stats['avg_articles']['linktext'] = esc_html__("add post", _SQ_PLUGIN_NAME_);
359
 
360
  //Get all keyword researched
361
  $stats['all_researches'] = array();
362
  $stats['all_researches']['value'] = (int)$data->kr_research;
363
+ $stats['all_researches']['text'] = esc_html__("Keyword Researches", _SQ_PLUGIN_NAME_);
364
  $stats['all_researches']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_research');
365
+ $stats['all_researches']['linktext'] = esc_html__("do research", _SQ_PLUGIN_NAME_);
366
 
367
  //Get all keywords from briefcase
368
  $stats['all_briefcase'] = array();
369
  $stats['all_briefcase']['value'] = (int)$data->kr_in_briefcase;
370
+ $stats['all_briefcase']['text'] = esc_html__("Keywords stored in Squirrly Briefcase", _SQ_PLUGIN_NAME_);
371
  $stats['all_briefcase']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_research', 'briefcase');
372
+ $stats['all_briefcase']['linktext'] = esc_html__("add keyword", _SQ_PLUGIN_NAME_);
373
 
374
  //Get the top 100 ranking
375
  $stats['top_ranking'] = array();
376
  $stats['top_ranking']['value'] = (int)$data->ranked_top;
377
+ $stats['top_ranking']['text'] = esc_html__("Pages ranking in top 100 Google", _SQ_PLUGIN_NAME_);
378
  $stats['top_ranking']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_rankings');
379
+ $stats['top_ranking']['linktext'] = esc_html__("see rankings", _SQ_PLUGIN_NAME_);
380
 
381
  //Get last month audits
382
  $stats['lm_audit'] = array();
383
  $stats['lm_audit']['value'] = (int)$data->audits_made;
384
+ $stats['lm_audit']['text'] = esc_html__("SEO Audits", _SQ_PLUGIN_NAME_);
385
  $stats['lm_audit']['link'] = SQ_Classes_Helpers_Tools::getAdminUrl('sq_audits');
386
+ $stats['lm_audit']['linktext'] = esc_html__("see audits", _SQ_PLUGIN_NAME_);
387
  }
388
  }
389
 
390
  return $stats;
391
  }
392
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  /**
394
  * Get audits from API
395
  *
414
  return $json->data->audits;
415
  }
416
 
417
+ public static function saveFeedback($args = array()) {
418
+ self::$apimethod = 'post'; //call method
419
+
420
+ $json = json_decode(self::apiCall('api/user/feedback', $args));
421
+
422
+ if (isset($json->error) && $json->error <> '') {
423
+ return (new WP_Error('api_error', $json->error));
424
+ } elseif (!isset($json->data)) {
425
+ return (new WP_Error('api_error', 'no_data'));
426
+ }
427
+
428
+ if (!empty($json->data)) {
429
+ return $json->data;
430
+ }
431
+
432
+ return false;
433
+ }
434
+
435
+
436
  /******************************** BRIEFCASE *********************/
437
  public static function getBriefcase($args = array()) {
438
  self::$apimethod = 'get'; //call method
1234
  public static function saveSettings($args) {
1235
  self::$apimethod = 'post'; //call method
1236
 
1237
+ self::apiCall('api/user/settings', array('settings' => wp_json_encode($args)));
1238
  }
1239
 
1240
  /**
1267
  global $post;
1268
  $referer = '';
1269
 
1270
+ $metas = json_decode(wp_json_encode(SQ_Classes_Helpers_Tools::getOption('sq_metas')));
1271
  $sq_postID = (isset($post->ID) ? $post->ID : 0);
1272
 
1273
  if (SQ_Classes_Helpers_Tools::isPluginInstalled('elementor/elementor.php')) {
1295
  frontend_css: "' . _SQ_ASSETS_URL_ . 'css/frontend' . (SQ_DEBUG ? '' : '.min') . '.css",
1296
  postID: "' . $sq_postID . '",
1297
  prevNonce: "' . wp_create_nonce('post_preview_' . $sq_postID) . '",
1298
+ __keyword: "' . esc_html__('Keyword:', _SQ_PLUGIN_NAME_) . '",
1299
+ __date: "' . esc_html__('date', _SQ_PLUGIN_NAME_) . '",
1300
+ __saved: "' . esc_html__('Saved!', _SQ_PLUGIN_NAME_) . '",
1301
+ __readit: "' . esc_html__('Read it!', _SQ_PLUGIN_NAME_) . '",
1302
+ __insertit: "' . esc_html__('Insert it!', _SQ_PLUGIN_NAME_) . '",
1303
+ __reference: "' . esc_html__('Reference', _SQ_PLUGIN_NAME_) . '",
1304
+ __insertasbox: "' . esc_html__('Insert as box', _SQ_PLUGIN_NAME_) . '",
1305
+ __addlink: "' . esc_html__('Insert Link', _SQ_PLUGIN_NAME_) . '",
1306
+ __notrelevant: "' . esc_html__('Not relevant?', _SQ_PLUGIN_NAME_) . '",
1307
+ __insertparagraph: "' . esc_html__('Insert in your article', _SQ_PLUGIN_NAME_) . '",
1308
+ __ajaxerror: "' . esc_html__(':( An error occurred while processing your request. Please try again', _SQ_PLUGIN_NAME_) . '",
1309
+ __nofound: "' . esc_html__('No results found!', _SQ_PLUGIN_NAME_) . '",
1310
+ __sq_photo_copyright: "' . esc_html__('[ ATTRIBUTE: Please check: %s to find out how to attribute this image ]', _SQ_PLUGIN_NAME_) . '",
1311
+ __has_attributes: "' . esc_html__('Has creative commons attributes', _SQ_PLUGIN_NAME_) . '",
1312
+ __no_attributes: "' . esc_html__('No known copyright restrictions', _SQ_PLUGIN_NAME_) . '",
1313
+ __noopt: "' . esc_html__('You haven`t used Squirrly SEO to optimize your article. Do you want to optimize for a keyword before publishing?', _SQ_PLUGIN_NAME_) . '",
1314
+ __subscription_expired: "' . esc_html__('Your Subscription has Expired', _SQ_PLUGIN_NAME_) . '",
1315
+ __no_briefcase: "' . esc_html__('There are no keywords saved in briefcase yet', _SQ_PLUGIN_NAME_) . '",
1316
+ __fulloptimized: "' . esc_html__('Congratulations! Your article is 100% optimized!', _SQ_PLUGIN_NAME_) . '",
1317
+ __toomanytimes: "' . esc_html__('appears too many times. Try to remove %s of them', _SQ_PLUGIN_NAME_) . '",
1318
+ __writemorewords: "' . esc_html__('write %s more words', _SQ_PLUGIN_NAME_) . '",
1319
+ __keywordinintroduction: "' . esc_html__('Add the keyword in the %s of your article', _SQ_PLUGIN_NAME_) . '",
1320
+ __clicktohighlight: "' . esc_html__('Click to keep the highlight on', _SQ_PLUGIN_NAME_) . '",
1321
+ __introduction: "' . esc_html__('introduction', _SQ_PLUGIN_NAME_) . '",
1322
+ __morewordsafter: "' . esc_html__('Write more words after the %s keyword', _SQ_PLUGIN_NAME_) . '",
1323
+ __orusesynonyms: "' . esc_html__('or use synonyms', _SQ_PLUGIN_NAME_) . '",
1324
+ __addmorewords: "' . esc_html__('add %s more word(s)', _SQ_PLUGIN_NAME_) . '",
1325
+ __removewords: "' . esc_html__('or remove %s word(s)', _SQ_PLUGIN_NAME_) . '",
1326
+ __addmorekeywords: "' . esc_html__('add %s more keyword(s)', _SQ_PLUGIN_NAME_) . '",
1327
+ __addminimumwords: "' . esc_html__('write %s more words to start calculating', _SQ_PLUGIN_NAME_) . '",
1328
+ __add_to_briefcase: "' . esc_html__('Add to Briefcase', _SQ_PLUGIN_NAME_) . '",
1329
+ __add_keyword_briefcase: "' . esc_html__('Add Keyword to Briefcase', _SQ_PLUGIN_NAME_) . '",
1330
+ __usekeyword: "' . esc_html__('Select', _SQ_PLUGIN_NAME_) . '",
1331
+ __new_post_title: "' . esc_html__('Auto Draft') . '",
1332
+ __frontend_optimized: "' . esc_html__('You’ve already used the Live Assistant to optimize this post when creating it in your Page Builder. Please go back and resume your optimization work there.', _SQ_PLUGIN_NAME_) . '",
1333
+ };
1334
+ $.sq_params = {
1335
+ max_length_title: '.(int)$metas->title_maxlength.',
1336
+ max_length_description: '.(int)$metas->description_maxlength.',
1337
  };
 
1338
  })(jQuery);
1339
  </script>';
1340
 
classes/helpers/DevKit.php CHANGED
@@ -25,25 +25,29 @@ class SQ_Classes_Helpers_DevKit {
25
  * @return bool
26
  */
27
  public function updatePluginData() {
 
 
 
 
28
  $package_file = _SQ_ROOT_DIR_ . 'package.json';
29
- if (!file_exists($package_file)) {
30
  return false;
31
  }
32
 
33
  /* load configuration blocks data from core config files */
34
- $config = json_decode(file_get_contents($package_file), 1);
35
  if (isset($config['package'])) {
36
  self::$package = $config['package'];
37
 
38
- if (isset(self::$package['settings']) && !empty(SQ_Classes_Helpers_Tools::$options)) {
39
- SQ_Classes_Helpers_Tools::$options = @array_replace_recursive(SQ_Classes_Helpers_Tools::$options, self::$package['settings']);
40
 
41
  if (isset(self::$package['name']) && self::$package['name'] <> '') {
42
  SQ_Classes_Helpers_Tools::$options['sq_devkit_name'] = self::$package['name'];
43
  }
44
 
45
  SQ_Classes_Helpers_Tools::saveOptions();
46
- @unlink($package_file);
47
 
48
  wp_redirect(SQ_Classes_Helpers_Tools::getAdminUrl('sq_dashboard'));
49
  exit();
@@ -52,7 +56,7 @@ class SQ_Classes_Helpers_DevKit {
52
 
53
 
54
  //remove the package after activation
55
- @unlink($package_file);
56
 
57
  return true;
58
  }
25
  * @return bool
26
  */
27
  public function updatePluginData() {
28
+ global $wp_filesystem;
29
+ require_once(ABSPATH . '/wp-admin/includes/file.php');
30
+ WP_Filesystem();
31
+
32
  $package_file = _SQ_ROOT_DIR_ . 'package.json';
33
+ if (!$wp_filesystem->exists($package_file)) {
34
  return false;
35
  }
36
 
37
  /* load configuration blocks data from core config files */
38
+ $config = json_decode($wp_filesystem->get_contents($package_file), 1);
39
  if (isset($config['package'])) {
40
  self::$package = $config['package'];
41
 
42
+ if (isset(self::$package['settings']) && !empty(SQ_Classes_Helpers_Tools::$options) && function_exists('array_replace_recursive')) {
43
+ SQ_Classes_Helpers_Tools::$options = array_replace_recursive((array)SQ_Classes_Helpers_Tools::$options, (array)self::$package['settings']);
44
 
45
  if (isset(self::$package['name']) && self::$package['name'] <> '') {
46
  SQ_Classes_Helpers_Tools::$options['sq_devkit_name'] = self::$package['name'];
47
  }
48
 
49
  SQ_Classes_Helpers_Tools::saveOptions();
50
+ unlink($package_file);
51
 
52
  wp_redirect(SQ_Classes_Helpers_Tools::getAdminUrl('sq_dashboard'));
53
  exit();
56
 
57
 
58
  //remove the package after activation
59
+ unlink($package_file);
60
 
61
  return true;
62
  }
classes/helpers/Sanitize.php CHANGED
@@ -63,6 +63,48 @@ class SQ_Classes_Helpers_Sanitize {
63
  return self::clearTitle($keywords);
64
  }
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  /**
67
  * Truncate the text
68
  *
@@ -82,7 +124,7 @@ class SQ_Classes_Helpers_Sanitize {
82
  }
83
 
84
  $text = str_replace(']]>', ']]&gt;', $text);
85
- $text = @preg_replace('/\[(.+?)\]/is', '', $text);
86
 
87
  if ($max < strlen($text)) {
88
  while ($text[$max] != ' ' && $max > $min) {
@@ -103,6 +145,57 @@ class SQ_Classes_Helpers_Sanitize {
103
  return $text;
104
  }
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  /**
107
  * Check the google code saved at settings
108
  *
@@ -113,15 +206,15 @@ class SQ_Classes_Helpers_Sanitize {
113
  if ($code <> '') {
114
  $code = stripslashes($code);
115
  if (strpos($code, 'content') !== false) {
116
- @preg_match('/content\\s*=\\s*[\"]([^\"]+)[\"]/i', $code, $result);
117
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
118
  }
119
  if (strpos($code, '"') !== false) {
120
- @preg_match('/[\"]([^\"]+)[\"]/i', $code, $result);
121
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
122
  }
123
 
124
- if ($code == '') SQ_Classes_Error::setError(__("The code for Google Webmaster Tool is incorrect.", _SQ_PLUGIN_NAME_));
125
  }
126
  return $code;
127
  }
@@ -133,7 +226,6 @@ class SQ_Classes_Helpers_Sanitize {
133
  * @return string
134
  */
135
  public static function checkGoogleAnalyticsCode($code) {
136
- //echo $code;
137
  if ($code <> '') {
138
  $code = stripslashes($code);
139
 
@@ -147,9 +239,9 @@ class SQ_Classes_Helpers_Sanitize {
147
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
148
  }
149
 
150
- if (strpos($code, 'UA-') === false) {
151
  $code = '';
152
- SQ_Classes_Error::setError(__("The code for Google Analytics is incorrect.", _SQ_PLUGIN_NAME_));
153
  }
154
  }
155
  return trim($code);
@@ -186,7 +278,7 @@ class SQ_Classes_Helpers_Sanitize {
186
  return $code;
187
  }
188
 
189
- SQ_Classes_Error::setError(__("The code for Facebook is incorrect.", _SQ_PLUGIN_NAME_));
190
 
191
  }
192
  return false;
@@ -212,7 +304,7 @@ class SQ_Classes_Helpers_Sanitize {
212
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
213
  }
214
 
215
- if ($code == '') SQ_Classes_Error::setError(__("The code for Pinterest is incorrect.", _SQ_PLUGIN_NAME_));
216
  }
217
  return $code;
218
  }
@@ -237,7 +329,7 @@ class SQ_Classes_Helpers_Sanitize {
237
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
238
  }
239
 
240
- if ($code == '') SQ_Classes_Error::setError(__("The code for Bing is incorrect.", _SQ_PLUGIN_NAME_));
241
  }
242
  return $code;
243
  }
@@ -262,7 +354,7 @@ class SQ_Classes_Helpers_Sanitize {
262
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
263
  }
264
 
265
- if ($code == '') SQ_Classes_Error::setError(__("The code for Alexa is incorrect.", _SQ_PLUGIN_NAME_));
266
  }
267
  return $code;
268
  }
@@ -388,7 +480,7 @@ class SQ_Classes_Helpers_Sanitize {
388
  public static function checkFacebookPixel($code) {
389
  if ($code <> '') {
390
  if ((int)$code == 0) {
391
- SQ_Classes_Error::setError(__("The code for Facebook Pixel must only contain numbers.", _SQ_PLUGIN_NAME_));
392
  $code = '';
393
  }
394
  }
@@ -403,7 +495,7 @@ class SQ_Classes_Helpers_Sanitize {
403
  public static function checkFacebookApp($code) {
404
  if ($code <> '') {
405
  if ((int)$code == 0) {
406
- SQ_Classes_Error::setError(__("The code for Facebook App must only contain numbers.", _SQ_PLUGIN_NAME_));
407
  $code = '';
408
  }
409
  }
63
  return self::clearTitle($keywords);
64
  }
65
 
66
+ /**
67
+ * Escape the keyword for tags and urls
68
+ * @param $str
69
+ * @return string
70
+ */
71
+ public static function escapeAttr($str) {
72
+ $str = esc_attr($str);
73
+
74
+ return $str;
75
+ }
76
+
77
+ /**
78
+ * Escape the keyword for tags and urls
79
+ * @param $str
80
+ * @return string
81
+ */
82
+ public static function escapeHtml($str) {
83
+ $str = esc_attr($str);
84
+
85
+ return $str;
86
+ }
87
+
88
+ /**
89
+ * Escape the keyword for tags and urls
90
+ * @param $keyword
91
+ * @param string $for
92
+ * @return string|void
93
+ */
94
+ public static function escapeKeyword($keyword, $for = 'all') {
95
+ switch ($for){
96
+ case 'url':
97
+ $keyword = urlencode(esc_attr($keyword));
98
+ break;
99
+ case 'attr':
100
+ $keyword = htmlspecialchars(str_replace('"', '\"', $keyword));
101
+ break;
102
+ default:
103
+ $keyword = esc_attr($keyword);
104
+ }
105
+ return $keyword;
106
+ }
107
+
108
  /**
109
  * Truncate the text
110
  *
124
  }
125
 
126
  $text = str_replace(']]>', ']]&gt;', $text);
127
+ $text = preg_replace('/\[(.+?)\]/is', '', $text);
128
 
129
  if ($max < strlen($text)) {
130
  while ($text[$max] != ' ' && $max > $min) {
145
  return $text;
146
  }
147
 
148
+ /**
149
+ * Replace language-specific characters by ASCII-equivalents.
150
+ * @param string $s
151
+ * @return string
152
+ */
153
+ public static function normalizeChars($s) {
154
+ $replace = array(
155
+ 'ъ'=>'-', 'Ь'=>'-', 'Ъ'=>'-', 'ь'=>'-',
156
+ 'Ă'=>'A', 'Ą'=>'A', 'À'=>'A', 'Ã'=>'A', 'Á'=>'A', 'Æ'=>'A', 'Â'=>'A', 'Å'=>'A', 'Ä'=>'Ae',
157
+ 'Þ'=>'B',
158
+ 'Ć'=>'C', 'ץ'=>'C', 'Ç'=>'C',
159
+ 'È'=>'E', 'Ę'=>'E', 'É'=>'E', 'Ë'=>'E', 'Ê'=>'E',
160
+ 'Ğ'=>'G',
161
+ 'İ'=>'I', 'Ï'=>'I', 'Î'=>'I', 'Í'=>'I', 'Ì'=>'I',
162
+ 'Ł'=>'L',
163
+ 'Ñ'=>'N', 'Ń'=>'N',
164
+ 'Ø'=>'O', 'Ó'=>'O', 'Ò'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'Oe',
165
+ 'Ş'=>'S', 'Ś'=>'S', 'Ș'=>'S', 'Š'=>'S',
166
+ 'Ț'=>'T',
167
+ 'Ù'=>'U', 'Û'=>'U', 'Ú'=>'U', 'Ü'=>'Ue',
168
+ 'Ý'=>'Y',
169
+ 'Ź'=>'Z', 'Ž'=>'Z', 'Ż'=>'Z',
170
+ 'â'=>'a', 'ǎ'=>'a', 'ą'=>'a', 'á'=>'a', 'ă'=>'a', 'ã'=>'a', 'Ǎ'=>'a', 'а'=>'a', 'А'=>'a', 'å'=>'a', 'à'=>'a', 'א'=>'a', 'Ǻ'=>'a', 'Ā'=>'a', 'ǻ'=>'a', 'ā'=>'a', 'ä'=>'ae', 'æ'=>'ae', 'Ǽ'=>'ae', 'ǽ'=>'ae',
171
+ 'б'=>'b', 'ב'=>'b', 'Б'=>'b', 'þ'=>'b',
172
+ 'ĉ'=>'c', 'Ĉ'=>'c', 'Ċ'=>'c', 'ć'=>'c', 'ç'=>'c', 'ц'=>'c', 'צ'=>'c', 'ċ'=>'c', 'Ц'=>'c', 'Č'=>'c', 'č'=>'c', 'Ч'=>'ch', 'ч'=>'ch',
173
+ 'ד'=>'d', 'ď'=>'d', 'Đ'=>'d', 'Ď'=>'d', 'đ'=>'d', 'д'=>'d', 'Д'=>'D', 'ð'=>'d',
174
+ 'є'=>'e', 'ע'=>'e', 'е'=>'e', 'Е'=>'e', 'Ə'=>'e', 'ę'=>'e', 'ĕ'=>'e', 'ē'=>'e', 'Ē'=>'e', 'Ė'=>'e', 'ė'=>'e', 'ě'=>'e', 'Ě'=>'e', 'Є'=>'e', 'Ĕ'=>'e', 'ê'=>'e', 'ə'=>'e', 'è'=>'e', 'ë'=>'e', 'é'=>'e',
175
+ 'ф'=>'f', 'ƒ'=>'f', 'Ф'=>'f',
176
+ 'ġ'=>'g', 'Ģ'=>'g', 'Ġ'=>'g', 'Ĝ'=>'g', 'Г'=>'g', 'г'=>'g', 'ĝ'=>'g', 'ğ'=>'g', 'ג'=>'g', 'Ґ'=>'g', 'ґ'=>'g', 'ģ'=>'g',
177
+ 'ח'=>'h', 'ħ'=>'h', 'Х'=>'h', 'Ħ'=>'h', 'Ĥ'=>'h', 'ĥ'=>'h', 'х'=>'h', 'ה'=>'h',
178
+ 'î'=>'i', 'ï'=>'i', 'í'=>'i', 'ì'=>'i', 'į'=>'i', 'ĭ'=>'i', 'ı'=>'i', 'Ĭ'=>'i', 'И'=>'i', 'ĩ'=>'i', 'ǐ'=>'i', 'Ĩ'=>'i', 'Ǐ'=>'i', 'и'=>'i', 'Į'=>'i', 'י'=>'i', 'Ї'=>'i', 'Ī'=>'i', 'І'=>'i', 'ї'=>'i', 'і'=>'i', 'ī'=>'i', 'ij'=>'ij', 'IJ'=>'ij',
179
+ 'й'=>'j', 'Й'=>'j', 'Ĵ'=>'j', 'ĵ'=>'j', 'я'=>'ja', 'Я'=>'ja', 'Э'=>'je', 'э'=>'je', 'ё'=>'jo', 'Ё'=>'jo', 'ю'=>'ju', 'Ю'=>'ju',
180
+ 'ĸ'=>'k', 'כ'=>'k', 'Ķ'=>'k', 'К'=>'k', 'к'=>'k', 'ķ'=>'k', 'ך'=>'k',
181
+ 'Ŀ'=>'l', 'ŀ'=>'l', 'Л'=>'l', 'ł'=>'l', 'ļ'=>'l', 'ĺ'=>'l', 'Ĺ'=>'l', 'Ļ'=>'l', 'л'=>'l', 'Ľ'=>'l', 'ľ'=>'l', 'ל'=>'l',
182
+ 'מ'=>'m', 'М'=>'m', 'ם'=>'m', 'м'=>'m',
183
+ 'ñ'=>'n', 'н'=>'n', 'Ņ'=>'n', 'ן'=>'n', 'ŋ'=>'n', 'נ'=>'n', 'Н'=>'n', 'ń'=>'n', 'Ŋ'=>'n', 'ņ'=>'n', 'ʼn'=>'n', 'Ň'=>'n', 'ň'=>'n',
184
+ 'о'=>'o', 'О'=>'o', 'ő'=>'o', 'õ'=>'o', 'ô'=>'o', 'Ő'=>'o', 'ŏ'=>'o', 'Ŏ'=>'o', 'Ō'=>'o', 'ō'=>'o', 'ø'=>'o', 'ǿ'=>'o', 'ǒ'=>'o', 'ò'=>'o', 'Ǿ'=>'o', 'Ǒ'=>'o', 'ơ'=>'o', 'ó'=>'o', 'Ơ'=>'o', 'œ'=>'oe', 'Œ'=>'oe', 'ö'=>'oe',
185
+ 'פ'=>'p', 'ף'=>'p', 'п'=>'p', 'П'=>'p',
186
+ 'ק'=>'q',
187
+ 'ŕ'=>'r', 'ř'=>'r', 'Ř'=>'r', 'ŗ'=>'r', 'Ŗ'=>'r', 'ר'=>'r', 'Ŕ'=>'r', 'Р'=>'r', 'р'=>'r',
188
+ 'ș'=>'s', 'с'=>'s', 'Ŝ'=>'s', 'š'=>'s', 'ś'=>'s', 'ס'=>'s', 'ş'=>'s', 'С'=>'s', 'ŝ'=>'s', 'Щ'=>'sch', 'щ'=>'sch', 'ш'=>'sh', 'Ш'=>'sh', 'ß'=>'ss',
189
+ 'т'=>'t', 'ט'=>'t', 'ŧ'=>'t', 'ת'=>'t', 'ť'=>'t', 'ţ'=>'t', 'Ţ'=>'t', 'Т'=>'t', 'ț'=>'t', 'Ŧ'=>'t', 'Ť'=>'t', '™'=>'tm',
190
+ 'ū'=>'u', 'у'=>'u', 'Ũ'=>'u', 'ũ'=>'u', 'Ư'=>'u', 'ư'=>'u', 'Ū'=>'u', 'Ǔ'=>'u', 'ų'=>'u', 'Ų'=>'u', 'ŭ'=>'u', 'Ŭ'=>'u', 'Ů'=>'u', 'ů'=>'u', 'ű'=>'u', 'Ű'=>'u', 'Ǖ'=>'u', 'ǔ'=>'u', 'Ǜ'=>'u', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'У'=>'u', 'ǚ'=>'u', 'ǜ'=>'u', 'Ǚ'=>'u', 'Ǘ'=>'u', 'ǖ'=>'u', 'ǘ'=>'u', 'ü'=>'ue',
191
+ 'в'=>'v', 'ו'=>'v', 'В'=>'v',
192
+ 'ש'=>'w', 'ŵ'=>'w', 'Ŵ'=>'w',
193
+ 'ы'=>'y', 'ŷ'=>'y', 'ý'=>'y', 'ÿ'=>'y', 'Ÿ'=>'y', 'Ŷ'=>'y',
194
+ 'Ы'=>'y', 'ž'=>'z', 'З'=>'z', 'з'=>'z', 'ź'=>'z', 'ז'=>'z', 'ż'=>'z', 'ſ'=>'z', 'Ж'=>'zh', 'ж'=>'zh'
195
+ );
196
+ return strtr($s, $replace);
197
+ }
198
+
199
  /**
200
  * Check the google code saved at settings
201
  *
206
  if ($code <> '') {
207
  $code = stripslashes($code);
208
  if (strpos($code, 'content') !== false) {
209
+ preg_match('/content\\s*=\\s*[\"]([^\"]+)[\"]/i', $code, $result);
210
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
211
  }
212
  if (strpos($code, '"') !== false) {
213
+ preg_match('/[\"]([^\"]+)[\"]/i', $code, $result);
214
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
215
  }
216
 
217
+ if ($code == '') SQ_Classes_Error::setError(esc_html__("The code for Google Webmaster Tool is incorrect.", _SQ_PLUGIN_NAME_));
218
  }
219
  return $code;
220
  }
226
  * @return string
227
  */
228
  public static function checkGoogleAnalyticsCode($code) {
 
229
  if ($code <> '') {
230
  $code = stripslashes($code);
231
 
239
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
240
  }
241
 
242
+ if (strpos($code, 'UA-') === false && strpos($code, 'G-') === false) {
243
  $code = '';
244
+ SQ_Classes_Error::setError(esc_html__("The code for Google Analytics is incorrect.", _SQ_PLUGIN_NAME_));
245
  }
246
  }
247
  return trim($code);
278
  return $code;
279
  }
280
 
281
+ SQ_Classes_Error::setError(esc_html__("The code for Facebook is incorrect.", _SQ_PLUGIN_NAME_));
282
 
283
  }
284
  return false;
304
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
305
  }
306
 
307
+ if ($code == '') SQ_Classes_Error::setError(esc_html__("The code for Pinterest is incorrect.", _SQ_PLUGIN_NAME_));
308
  }
309
  return $code;
310
  }
329
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
330
  }
331
 
332
+ if ($code == '') SQ_Classes_Error::setError(esc_html__("The code for Bing is incorrect.", _SQ_PLUGIN_NAME_));
333
  }
334
  return $code;
335
  }
354
  if (isset($result[1]) && !empty($result[1])) $code = $result[1];
355
  }
356
 
357
+ if ($code == '') SQ_Classes_Error::setError(esc_html__("The code for Alexa is incorrect.", _SQ_PLUGIN_NAME_));
358
  }
359
  return $code;
360
  }
480
  public static function checkFacebookPixel($code) {
481
  if ($code <> '') {
482
  if ((int)$code == 0) {
483
+ SQ_Classes_Error::setError(esc_html__("The code for Facebook Pixel must only contain numbers.", _SQ_PLUGIN_NAME_));
484
  $code = '';
485
  }
486
  }
495
  public static function checkFacebookApp($code) {
496
  if ($code <> '') {
497
  if ((int)$code == 0) {
498
+ SQ_Classes_Error::setError(esc_html__("The code for Facebook App must only contain numbers.", _SQ_PLUGIN_NAME_));
499
  $code = '';
500
  }
501
  }
classes/helpers/Tools.php CHANGED
@@ -79,7 +79,7 @@ class SQ_Classes_Helpers_Tools {
79
  */
80
  public function hookActionlink($links, $file) {
81
  if ($file == _SQ_PLUGIN_NAME_ . '/squirrly.php') {
82
- $link = '<a href="' . self::getAdminUrl('sq_dashboard') . '">' . __('Getting started', _SQ_PLUGIN_NAME_) . '</a>';
83
  array_unshift($links, $link);
84
  }
85
 
@@ -104,8 +104,8 @@ class SQ_Classes_Helpers_Tools {
104
  .ml-stars svg:hover ~ svg{fill:none}
105
  </style>';
106
 
107
- $meta[] = "<a href='https://howto.squirrly.co/wordpress-seo/' target='_blank'>" . __('Documentation', _SQ_PLUGIN_NAME_) . "</a>";
108
- $meta[] = "<a href='https://wordpress.org/support/plugin/squirrly-seo/reviews/#new-post' target='_blank' title='" . __('Leave a review', _SQ_PLUGIN_NAME_) . "'><i class='ml-stars'><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg></i></a>";
109
  }
110
  return $meta;
111
  }
@@ -188,7 +188,7 @@ class SQ_Classes_Helpers_Tools {
188
  'sq_sitemap_perpage' => 200,
189
  'sq_sitemap_frequency' => 'weekly',
190
  'sq_url_fix' => 1,
191
- 'sq_sitemap_combinelangs' => 1,
192
  'sq_sitemap' => array(
193
  'sitemap' => array('sitemap.xml', 1),
194
  'sitemap-home' => array('sitemap-home.xml', 1),
@@ -405,7 +405,7 @@ class SQ_Classes_Helpers_Tools {
405
  'tax-post_format' => array(
406
  'protected' => 1,
407
  'sep' => '|',
408
- 'title' => '{{term_title}} ' . __('Format', _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
409
  'description' => '{{excerpt}}',
410
  'noindex' => 0,
411
  'nofollow' => 0,
@@ -423,7 +423,7 @@ class SQ_Classes_Helpers_Tools {
423
  'tax-category' => array(
424
  'protected' => 1,
425
  'sep' => '|',
426
- 'title' => '{{term_title}} ' . __('Category', _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
427
  'description' => '{{excerpt}}',
428
  'noindex' => 0,
429
  'nofollow' => 0,
@@ -441,7 +441,7 @@ class SQ_Classes_Helpers_Tools {
441
  'tax-post_tag' => array(
442
  'protected' => 1,
443
  'sep' => '|',
444
- 'title' => '{{term_title}} ' . __('Tag', _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
445
  'description' => '{{excerpt}}',
446
  'noindex' => 0,
447
  'nofollow' => 0,
@@ -459,7 +459,7 @@ class SQ_Classes_Helpers_Tools {
459
  'tax-product_cat' => array(
460
  'protected' => 1,
461
  'sep' => '|',
462
- 'title' => '{{term_title}} ' . __('Category', _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
463
  'description' => '{{excerpt}}',
464
  'noindex' => 0,
465
  'nofollow' => 0,
@@ -477,7 +477,7 @@ class SQ_Classes_Helpers_Tools {
477
  'tax-product_tag' => array(
478
  'protected' => 1,
479
  'sep' => '|',
480
- 'title' => '{{term_title}} ' . __('Tag', _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
481
  'description' => '{{excerpt}}',
482
  'noindex' => 0,
483
  'nofollow' => 0,
@@ -495,7 +495,7 @@ class SQ_Classes_Helpers_Tools {
495
  'tax-product_shipping_class' => array(
496
  'protected' => 1,
497
  'sep' => '|',
498
- 'title' => '{{term_title}} ' . __('Shipping Option', _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
499
  'description' => '{{excerpt}}',
500
  'noindex' => 0,
501
  'nofollow' => 0,
@@ -513,7 +513,7 @@ class SQ_Classes_Helpers_Tools {
513
  'profile' => array(
514
  'protected' => 1,
515
  'sep' => '|',
516
- 'title' => '{{name}}, ' . __('Author at', _SQ_PLUGIN_NAME_) . ' {{sitename}} {{page}}',
517
  'description' => '{{excerpt}}',
518
  'noindex' => 0,
519
  'nofollow' => 0,
@@ -585,8 +585,8 @@ class SQ_Classes_Helpers_Tools {
585
  'search' => array(
586
  'protected' => 1,
587
  'sep' => '|',
588
- 'title' => __('Are you looking for', _SQ_PLUGIN_NAME_) . ' {{searchphrase}}? {{page}} {{sep}} {{sitename}}',
589
- 'description' => __('These are the results for', _SQ_PLUGIN_NAME_) . ' {{searchphrase}} ' . __('that you can find on our website.', _SQ_PLUGIN_NAME_) . ' {{excerpt}}',
590
  'noindex' => 1,
591
  'nofollow' => 0,
592
  'og_type' => 'website',
@@ -620,8 +620,8 @@ class SQ_Classes_Helpers_Tools {
620
  '404' => array(
621
  'protected' => 1,
622
  'sep' => '|',
623
- 'title' => __('Page not found', _SQ_PLUGIN_NAME_) . ' {{sep}} {{sitename}}',
624
- 'description' => __('This page could not be found on our website.', _SQ_PLUGIN_NAME_) . ' {{excerpt}}',
625
  'noindex' => 1,
626
  'nofollow' => 1,
627
  'og_type' => 'website',
@@ -664,8 +664,7 @@ class SQ_Classes_Helpers_Tools {
664
  }
665
 
666
  if (is_array($options)) {
667
- //$options['patterns'] = @array_replace_recursive($default['patterns'], $options['patterns']);
668
- $options = @array_replace_recursive($default, $options);
669
  return $options;
670
  }
671
 
@@ -700,7 +699,7 @@ class SQ_Classes_Helpers_Tools {
700
  self::$options[$key] = $value;
701
  }
702
 
703
- update_option(SQ_OPTION, json_encode(self::$options));
704
  }
705
 
706
  /**
@@ -723,7 +722,7 @@ class SQ_Classes_Helpers_Tools {
723
  $usermeta = $usermetatmp;
724
 
725
  if (is_array($usermeta)) {
726
- $usermeta = @array_merge($default, $usermeta);
727
  } else {
728
  $usermeta = $default;
729
  }
@@ -839,7 +838,7 @@ class SQ_Classes_Helpers_Tools {
839
  }
840
 
841
  if ($echo) {
842
- echo $nonce_field;
843
  }
844
 
845
  return $nonce_field;
@@ -906,13 +905,24 @@ class SQ_Classes_Helpers_Tools {
906
  *
907
  * @param string $content
908
  * @param string $string
 
909
  * @return bool|false|int
910
  */
911
- public static function findStr($content, $string) {
 
 
 
 
 
 
 
 
 
 
912
  if (function_exists('mb_stripos')) {
913
  return mb_stripos($content, $string);
914
  } else {
915
- SQ_Classes_Error::setMessage(sprintf(__("For better text comparison you need to install PHP mbstring extension.", _SQ_PLUGIN_NAME_), _QSS_PLUGIN_NAME_));
916
 
917
  return stripos($content, $string);
918
  }
@@ -1101,7 +1111,7 @@ class SQ_Classes_Helpers_Tools {
1101
  $url .= join('&', $args);
1102
  }
1103
 
1104
- return apply_filters('sq_menu_url', $url, $page, $tab, $args);
1105
  }
1106
 
1107
  }
79
  */
80
  public function hookActionlink($links, $file) {
81
  if ($file == _SQ_PLUGIN_NAME_ . '/squirrly.php') {
82
+ $link = '<a href="' . self::getAdminUrl('sq_dashboard') . '">' . esc_html__("Getting started", _SQ_PLUGIN_NAME_) . '</a>';
83
  array_unshift($links, $link);
84
  }
85
 
104
  .ml-stars svg:hover ~ svg{fill:none}
105
  </style>';
106
 
107
+ $meta[] = "<a href='https://howto.squirrly.co/wordpress-seo/' target='_blank'>" . esc_html__("Documentation", _SQ_PLUGIN_NAME_) . "</a>";
108
+ $meta[] = "<a href='https://wordpress.org/support/plugin/squirrly-seo/reviews/#new-post' target='_blank' title='" . esc_html__("Leave a review", _SQ_PLUGIN_NAME_) . "'><i class='ml-stars'><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg></i></a>";
109
  }
110
  return $meta;
111
  }
188
  'sq_sitemap_perpage' => 200,
189
  'sq_sitemap_frequency' => 'weekly',
190
  'sq_url_fix' => 1,
191
+ 'sq_sitemap_combinelangs' => 0,
192
  'sq_sitemap' => array(
193
  'sitemap' => array('sitemap.xml', 1),
194
  'sitemap-home' => array('sitemap-home.xml', 1),
405
  'tax-post_format' => array(
406
  'protected' => 1,
407
  'sep' => '|',
408
+ 'title' => '{{term_title}} ' . esc_html__("Format", _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
409
  'description' => '{{excerpt}}',
410
  'noindex' => 0,
411
  'nofollow' => 0,
423
  'tax-category' => array(
424
  'protected' => 1,
425
  'sep' => '|',
426
+ 'title' => '{{term_title}} ' . esc_html__("Category", _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
427
  'description' => '{{excerpt}}',
428
  'noindex' => 0,
429
  'nofollow' => 0,
441
  'tax-post_tag' => array(
442
  'protected' => 1,
443
  'sep' => '|',
444
+ 'title' => '{{term_title}} ' . esc_html__("Tag", _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
445
  'description' => '{{excerpt}}',
446
  'noindex' => 0,
447
  'nofollow' => 0,
459
  'tax-product_cat' => array(
460
  'protected' => 1,
461
  'sep' => '|',
462
+ 'title' => '{{term_title}} ' . esc_html__("Category", _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
463
  'description' => '{{excerpt}}',
464
  'noindex' => 0,
465
  'nofollow' => 0,
477
  'tax-product_tag' => array(
478
  'protected' => 1,
479
  'sep' => '|',
480
+ 'title' => '{{term_title}} ' . esc_html__("Tag", _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
481
  'description' => '{{excerpt}}',
482
  'noindex' => 0,
483
  'nofollow' => 0,
495
  'tax-product_shipping_class' => array(
496
  'protected' => 1,
497
  'sep' => '|',
498
+ 'title' => '{{term_title}} ' . esc_html__("Shipping Option", _SQ_PLUGIN_NAME_) . ' {{page}} {{sep}} {{sitename}}',
499
  'description' => '{{excerpt}}',
500
  'noindex' => 0,
501
  'nofollow' => 0,
513
  'profile' => array(
514
  'protected' => 1,
515
  'sep' => '|',
516
+ 'title' => '{{name}}, ' . esc_html__("Author at", _SQ_PLUGIN_NAME_) . ' {{sitename}} {{page}}',
517
  'description' => '{{excerpt}}',
518
  'noindex' => 0,
519
  'nofollow' => 0,
585
  'search' => array(
586
  'protected' => 1,
587
  'sep' => '|',
588
+ 'title' => esc_html__("Are you looking for", _SQ_PLUGIN_NAME_) . ' {{searchphrase}}? {{page}} {{sep}} {{sitename}}',
589
+ 'description' => esc_html__("These are the results for", _SQ_PLUGIN_NAME_) . ' {{searchphrase}} ' . esc_html__("that you can find on our website.", _SQ_PLUGIN_NAME_) . ' {{excerpt}}',
590
  'noindex' => 1,
591
  'nofollow' => 0,
592
  'og_type' => 'website',
620
  '404' => array(
621
  'protected' => 1,
622
  'sep' => '|',
623
+ 'title' => esc_html__("Page not found", _SQ_PLUGIN_NAME_) . ' {{sep}} {{sitename}}',
624
+ 'description' => esc_html__("This page could not be found on our website.", _SQ_PLUGIN_NAME_) . ' {{excerpt}}',
625
  'noindex' => 1,
626
  'nofollow' => 1,
627
  'og_type' => 'website',
664
  }
665
 
666
  if (is_array($options)) {
667
+ $options = array_replace_recursive((array)$default, (array)$options);
 
668
  return $options;
669
  }
670
 
699
  self::$options[$key] = $value;
700
  }
701
 
702
+ update_option(SQ_OPTION, wp_json_encode(self::$options));
703
  }
704
 
705
  /**
722
  $usermeta = $usermetatmp;
723
 
724
  if (is_array($usermeta)) {
725
+ $usermeta = array_merge((array)$default, (array)$usermeta);
726
  } else {
727
  $usermeta = $default;
728
  }
838
  }
839
 
840
  if ($echo) {
841
+ echo (string)$nonce_field;
842
  }
843
 
844
  return $nonce_field;
905
  *
906
  * @param string $content
907
  * @param string $string
908
+ * @param bool $normalize
909
  * @return bool|false|int
910
  */
911
+ public static function findStr($content, $string, $normalize = false) {
912
+ if($normalize) {
913
+ //Check if the search requires char normalization
914
+ $content = SQ_Classes_Helpers_Sanitize::normalizeChars($content);
915
+ $string = SQ_Classes_Helpers_Sanitize::normalizeChars($string);
916
+ }else{
917
+ //decode the content to match quotes and special chars
918
+ $content = html_entity_decode($content, ENT_QUOTES);
919
+ $string = html_entity_decode($string, ENT_QUOTES);
920
+ }
921
+
922
  if (function_exists('mb_stripos')) {
923
  return mb_stripos($content, $string);
924
  } else {
925
+ SQ_Classes_Error::setMessage(esc_html__("For better text comparison you need to install PHP mbstring extension.", _SQ_PLUGIN_NAME_));
926
 
927
  return stripos($content, $string);
928
  }
1111
  $url .= join('&', $args);
1112
  }
1113
 
1114
+ return apply_filters('sq_menu_url', esc_url($url), $page, $tab, $args);
1115
  }
1116
 
1117
  }
config.json CHANGED
@@ -258,7 +258,8 @@
258
  "name": "SQ_Core_BlockSupport",
259
  "actions": {
260
  "action": [
261
- "sq_feedback"
 
262
  ]
263
  },
264
  "admin": "1",
258
  "name": "SQ_Core_BlockSupport",
259
  "actions": {
260
  "action": [
261
+ "sq_feedback",
262
+ "sq_uninstall_feedback"
263
  ]
264
  },
265
  "admin": "1",
config/config.php CHANGED
@@ -26,41 +26,41 @@ defined('SQ_OPTION') || define('SQ_OPTION', 'sq_options');
26
  defined('SQ_TASKS') || define('SQ_TASKS', 'sq_tasks');
27
  defined('_SQ_DB_') || define('_SQ_DB_', 'qss');
28
 
29
- define('SQ_ALL_PATTERNS', json_encode(array(
30
- '{{sep}}' => __("Places a separator between the elements of the post description", _SQ_PLUGIN_NAME_),
31
- '{{title}}' => __("Adds the title of the post/page/term once it’s published", _SQ_PLUGIN_NAME_),
32
- '{{excerpt}}' => __("Will display an excerpt from the post/page/term (if not customized, the excerpt will be auto-generated)", _SQ_PLUGIN_NAME_),
33
- '{{excerpt_only}}' => __("Will display an excerpt from the post/page (no auto-generation)", _SQ_PLUGIN_NAME_),
34
- '{{keyword}}' => __("Adds the post's keyword to the post description", _SQ_PLUGIN_NAME_),
35
- '{{page}}' => __("Displays the number of the current page (i.e. 1 of 6)", _SQ_PLUGIN_NAME_),
36
- '{{sitename}}' => __("Adds the site's name to the post description", _SQ_PLUGIN_NAME_),
37
- '{{sitedesc}}' => __("Adds the tagline/description of your site", _SQ_PLUGIN_NAME_),
38
- '{{category}}' => __("Adds the post category (several categories will be comma-separated)", _SQ_PLUGIN_NAME_),
39
- '{{primary_category}}' => __("Adds the primary category of the post/page", _SQ_PLUGIN_NAME_),
40
- '{{category_description}}' => __("Adds the category description to the post description", _SQ_PLUGIN_NAME_),
41
- '{{tag}}' => __("Adds the current tag(s) (several tags will be comma-separated)", _SQ_PLUGIN_NAME_),
42
- '{{tag_description}}' => __("Adds the tag description", _SQ_PLUGIN_NAME_),
43
- '{{term_title}}' => __("Adds the term name", _SQ_PLUGIN_NAME_),
44
- '{{term_description}}' => __("Adds the term description", _SQ_PLUGIN_NAME_),
45
- '{{searchphrase}}' => __("Displays the search phrase (if it appears in the post)", _SQ_PLUGIN_NAME_),
46
- '{{modified}}' => __("Replaces the publication date of a post/page with the modified one", _SQ_PLUGIN_NAME_),
47
- '{{name}}' => __("Displays the author's nicename", _SQ_PLUGIN_NAME_),
48
- '{{user_description}}' => __("Adds the author's biographical info to the post description", _SQ_PLUGIN_NAME_),
49
- '{{currentdate}}' => __("Displays the current date", _SQ_PLUGIN_NAME_),
50
- '{{date}}' => __("Displays the date of the post/page once it's published", _SQ_PLUGIN_NAME_),
51
- '{{currentday}}' => __("Adds the current day", _SQ_PLUGIN_NAME_),
52
- '{{currentmonth}}' => __("Adds the current month", _SQ_PLUGIN_NAME_),
53
- '{{currentyear}}' => __("Adds the current year", _SQ_PLUGIN_NAME_),
54
- '{{parent_title}}' => __('Adds the title of a page\'s parent page', _SQ_PLUGIN_NAME_),
55
- '{{product_name}}' => __('Adds the product name from Woocommerce for the current product', _SQ_PLUGIN_NAME_),
56
- '{{product_price}}' => __('Adds the product price from Woocommerce for the current product', _SQ_PLUGIN_NAME_),
57
- '{{product_sale}}' => __('Adds the product sale price from Woocommerce for the current product', _SQ_PLUGIN_NAME_),
58
- '{{product_currency}}' => __('Adds the product price currency from Woocommerce for the current product', _SQ_PLUGIN_NAME_),
59
  )));
60
 
61
- define('SQ_ALL_JSONLD_TYPES', json_encode(array('website','profile','article','book','music','product','video')));
62
 
63
- define('SQ_ALL_SEP', json_encode(array(
64
  'sc-dash' => '-',
65
  'sc-ndash' => '&ndash;',
66
  'sc-mdash' => '&mdash;',
26
  defined('SQ_TASKS') || define('SQ_TASKS', 'sq_tasks');
27
  defined('_SQ_DB_') || define('_SQ_DB_', 'qss');
28
 
29
+ define('SQ_ALL_PATTERNS', wp_json_encode(array(
30
+ '{{sep}}' => esc_html__("Places a separator between the elements of the post description", _SQ_PLUGIN_NAME_),
31
+ '{{title}}' => esc_html__("Adds the title of the post/page/term once it’s published", _SQ_PLUGIN_NAME_),
32
+ '{{excerpt}}' => esc_html__("Will display an excerpt from the post/page/term (if not customized, the excerpt will be auto-generated)", _SQ_PLUGIN_NAME_),
33
+ '{{excerpt_only}}' => esc_html__("Will display an excerpt from the post/page (no auto-generation)", _SQ_PLUGIN_NAME_),
34
+ '{{keyword}}' => esc_html__("Adds the post's keyword to the post description", _SQ_PLUGIN_NAME_),
35
+ '{{page}}' => esc_html__("Displays the number of the current page (i.e. 1 of 6)", _SQ_PLUGIN_NAME_),
36
+ '{{sitename}}' => esc_html__("Adds the site's name to the post description", _SQ_PLUGIN_NAME_),
37
+ '{{sitedesc}}' => esc_html__("Adds the tagline/description of your site", _SQ_PLUGIN_NAME_),
38
+ '{{category}}' => esc_html__("Adds the post category (several categories will be comma-separated)", _SQ_PLUGIN_NAME_),
39
+ '{{primary_category}}' => esc_html__("Adds the primary category of the post/page", _SQ_PLUGIN_NAME_),
40
+ '{{category_description}}' => esc_html__("Adds the category description to the post description", _SQ_PLUGIN_NAME_),
41
+ '{{tag}}' => esc_html__("Adds the current tag(s) (several tags will be comma-separated)", _SQ_PLUGIN_NAME_),
42
+ '{{tag_description}}' => esc_html__("Adds the tag description", _SQ_PLUGIN_NAME_),
43
+ '{{term_title}}' => esc_html__("Adds the term name", _SQ_PLUGIN_NAME_),
44
+ '{{term_description}}' => esc_html__("Adds the term description", _SQ_PLUGIN_NAME_),
45
+ '{{searchphrase}}' => esc_html__("Displays the search phrase (if it appears in the post)", _SQ_PLUGIN_NAME_),
46
+ '{{modified}}' => esc_html__("Replaces the publication date of a post/page with the modified one", _SQ_PLUGIN_NAME_),
47
+ '{{name}}' => esc_html__("Displays the author's nicename", _SQ_PLUGIN_NAME_),
48
+ '{{user_description}}' => esc_html__("Adds the author's biographical info to the post description", _SQ_PLUGIN_NAME_),
49
+ '{{currentdate}}' => esc_html__("Displays the current date", _SQ_PLUGIN_NAME_),
50
+ '{{date}}' => esc_html__("Displays the date of the post/page once it's published", _SQ_PLUGIN_NAME_),
51
+ '{{currentday}}' => esc_html__("Adds the current day", _SQ_PLUGIN_NAME_),
52
+ '{{currentmonth}}' => esc_html__("Adds the current month", _SQ_PLUGIN_NAME_),
53
+ '{{currentyear}}' => esc_html__("Adds the current year", _SQ_PLUGIN_NAME_),
54
+ '{{parent_title}}' => esc_html__("Adds the title of a page's parent page", _SQ_PLUGIN_NAME_),
55
+ '{{product_name}}' => esc_html__("Adds the product name from Woocommerce for the current product", _SQ_PLUGIN_NAME_),
56
+ '{{product_price}}' => esc_html__("Adds the product price from Woocommerce for the current product", _SQ_PLUGIN_NAME_),
57
+ '{{product_sale}}' => esc_html__("Adds the product sale price from Woocommerce for the current product", _SQ_PLUGIN_NAME_),
58
+ '{{product_currency}}' => esc_html__("Adds the product price currency from Woocommerce for the current product", _SQ_PLUGIN_NAME_),
59
  )));
60
 
61
+ define('SQ_ALL_JSONLD_TYPES', wp_json_encode(array('website','profile','article','book','music','product','video')));
62
 
63
+ define('SQ_ALL_SEP', wp_json_encode(array(
64
  'sc-dash' => '-',
65
  'sc-ndash' => '&ndash;',
66
  'sc-mdash' => '&mdash;',
config/paths.php CHANGED
@@ -12,7 +12,7 @@ defined('SQ_CHECK_SSL') || define('SQ_CHECK_SSL', SQ_SSL);
12
  defined('SQ_URI') || define('SQ_URI', 'wp530');
13
  defined('_SQ_DASH_URL_') || define('_SQ_DASH_URL_', 'https://cloud.squirrly.co/');
14
  defined('_SQ_APIV2_URL_') || define('_SQ_APIV2_URL_', SQ_SSL . '//api.squirrly.co/v2/');
15
- define('_SQ_SITE_HOST_', @parse_url(home_url(), PHP_URL_HOST));
16
 
17
  define('_SQ_SUPPORT_EMAIL_', 'support@squirrly.co');
18
  defined('_SQ_STATIC_API_URL_') || define('_SQ_STATIC_API_URL_', '//storage.googleapis.com/squirrly/');
@@ -43,22 +43,23 @@ $upload_dir = array();
43
  $upload_dir['baseurl'] = WP_CONTENT_URL . '/uploads';
44
  $upload_dir['basedir'] = WP_CONTENT_DIR . '/uploads';
45
 
46
- $upload_path = '';
47
- if (is_dir($upload_dir['basedir'])) {
48
- $upload_path = $upload_dir['basedir'] . '/' . _SQ_NAME_ . '/';
 
 
 
49
  }
50
 
51
- if ($upload_path <> '') {
52
- if (!is_dir($upload_path)) {
53
- wp_mkdir_p($upload_path);
54
- }
55
 
56
- if (is_dir($upload_path) && function_exists('wp_is_writable') && wp_is_writable($upload_path)) {
57
- defined('_SQ_CACHE_DIR_') || define('_SQ_CACHE_DIR_', realpath($upload_path) . '/');
58
- defined('_SQ_CACHE_URL_') || define('_SQ_CACHE_URL_', $upload_dir['baseurl'] . '/' . _SQ_NAME_ . '/');
59
- }
60
  }
61
 
62
- defined('_SQ_CACHE_DIR_') || define('_SQ_CACHE_DIR_', _SQ_ROOT_DIR_ . '/cache/');
63
- defined('_SQ_CACHE_URL_') || define('_SQ_CACHE_URL_', _SQ_URL_ . '/cache/');
64
 
12
  defined('SQ_URI') || define('SQ_URI', 'wp530');
13
  defined('_SQ_DASH_URL_') || define('_SQ_DASH_URL_', 'https://cloud.squirrly.co/');
14
  defined('_SQ_APIV2_URL_') || define('_SQ_APIV2_URL_', SQ_SSL . '//api.squirrly.co/v2/');
15
+ define('_SQ_SITE_HOST_', parse_url(home_url(), PHP_URL_HOST));
16
 
17
  define('_SQ_SUPPORT_EMAIL_', 'support@squirrly.co');
18
  defined('_SQ_STATIC_API_URL_') || define('_SQ_STATIC_API_URL_', '//storage.googleapis.com/squirrly/');
43
  $upload_dir['baseurl'] = WP_CONTENT_URL . '/uploads';
44
  $upload_dir['basedir'] = WP_CONTENT_DIR . '/uploads';
45
 
46
+ if (!defined('UPLOADS')) {
47
+ $basedir = WP_CONTENT_DIR . '/uploads/' . _SQ_NAME_;
48
+ $baseurl = rtrim(content_url(), '/') . '/uploads/' . _SQ_NAME_;
49
+ } else {
50
+ $basedir = rtrim(ABSPATH, '/') . '/' . trim(UPLOADS, '/') . '/' . _SQ_NAME_;
51
+ $baseurl = home_url() . '/' . trim(UPLOADS, '/') . '/' . _SQ_NAME_;
52
  }
53
 
54
+ if (!is_dir($basedir)) {
55
+ @wp_mkdir_p($basedir);
56
+ }
 
57
 
58
+ if (!is_dir($basedir) || !function_exists('wp_is_writable') || !wp_is_writable($basedir)) {
59
+ $basedir = _SQ_ROOT_DIR_ . 'cache';
60
+ $baseurl = _SQ_URL_ . 'cache';
 
61
  }
62
 
63
+ defined('_SQ_CACHE_DIR_') || define('_SQ_CACHE_DIR_', $basedir . '/');
64
+ defined('_SQ_CACHE_URL_') || define('_SQ_CACHE_URL_', $baseurl . '/');
65
 
controllers/Account.php CHANGED
@@ -28,7 +28,7 @@ class SQ_Controllers_Account extends SQ_Classes_FrontController {
28
  $json['error'] = SQ_Classes_Error::getError();
29
  }
30
 
31
- echo json_encode($json);
32
  exit();
33
  }
34
 
28
  $json['error'] = SQ_Classes_Error::getError();
29
  }
30
 
31
+ echo wp_json_encode($json);
32
  exit();
33
  }
34
 
controllers/Api.php CHANGED
@@ -63,10 +63,10 @@ class SQ_Controllers_Api extends SQ_Classes_FrontController {
63
  }
64
 
65
  if ($this->token <> $token) {
66
- exit(json_encode(array('connected' => false, 'error' => __('Invalid Token. Please try again', _SQ_PLUGIN_NAME_))));
67
  }
68
 
69
- echo json_encode(array('connected' => true, 'error' => false));
70
  exit();
71
  }
72
 
@@ -84,7 +84,7 @@ class SQ_Controllers_Api extends SQ_Classes_FrontController {
84
  }
85
 
86
  if ($this->token <> $token) {
87
- exit(json_encode(array('error' => __('Connection expired. Please try again', _SQ_PLUGIN_NAME_))));
88
  }
89
 
90
  $post = $request->get_param('post');
@@ -97,25 +97,25 @@ class SQ_Controllers_Api extends SQ_Classes_FrontController {
97
  if ($user = get_user_by('email', $post->post_author)) {
98
  $post->post_author = $user->ID;
99
  } else {
100
- exit(json_encode(array('error' => __('Author not found', _SQ_PLUGIN_NAME_))));
101
  }
102
  } else {
103
- exit(json_encode(array('error' => __('Author not found', _SQ_PLUGIN_NAME_))));
104
  }
105
  } else {
106
- exit(json_encode(array('error' => __('Author not found', _SQ_PLUGIN_NAME_))));
107
  }
108
 
109
  $post_ID = wp_insert_post($post->to_array());
110
  if (is_wp_error($post_ID)) {
111
- echo json_encode(array('error' => $post_ID->get_error_message()));
112
  } else {
113
- echo json_encode(array('saved' => true, 'post_ID' => $post_ID, 'permalink' => get_permalink($post_ID)));
114
  }
115
  exit();
116
  }
117
  }
118
- echo json_encode(array('error' => true));
119
  exit();
120
  }
121
 
@@ -136,7 +136,7 @@ class SQ_Controllers_Api extends SQ_Classes_FrontController {
136
  }
137
 
138
  if ($this->token <> $token) {
139
- exit(json_encode(array('error' => __('Connection expired. Please try again', _SQ_PLUGIN_NAME_))));
140
  }
141
 
142
  $select = $request->get_param('select');
@@ -146,7 +146,7 @@ class SQ_Controllers_Api extends SQ_Classes_FrontController {
146
  case 'innerlinks':
147
  $url = $request->get_param('url');
148
  if ($url == '') {
149
- exit(json_encode(array('error' => __('Wrong Params', _SQ_PLUGIN_NAME_))));
150
  }
151
 
152
  //get post inner links
@@ -168,7 +168,7 @@ class SQ_Controllers_Api extends SQ_Classes_FrontController {
168
  case 'post':
169
  $url = $request->get_param('url');
170
  if ($url == '') {
171
- exit(json_encode(array('error' => __('Wrong Params', _SQ_PLUGIN_NAME_))));
172
  }
173
  //get Squirrly SEO post metas
174
  if ($post = SQ_Classes_ObjController::getClass('SQ_Models_Snippet')->setPostByURL($url)) {
@@ -184,7 +184,7 @@ class SQ_Controllers_Api extends SQ_Classes_FrontController {
184
 
185
  break;
186
  }
187
- echo json_encode($response);
188
 
189
  exit();
190
 
63
  }
64
 
65
  if ($this->token <> $token) {
66
+ exit(wp_json_encode(array('connected' => false, 'error' => esc_html__("Invalid Token. Please try again", _SQ_PLUGIN_NAME_))));
67
  }
68
 
69
+ echo wp_json_encode(array('connected' => true, 'error' => false));
70
  exit();
71
  }
72
 
84
  }
85
 
86
  if ($this->token <> $token) {
87
+ exit(wp_json_encode(array('error' => esc_html__("Connection expired. Please try again", _SQ_PLUGIN_NAME_))));
88
  }
89
 
90
  $post = $request->get_param('post');
97
  if ($user = get_user_by('email', $post->post_author)) {
98
  $post->post_author = $user->ID;
99
  } else {
100
+ exit(wp_json_encode(array('error' => esc_html__("Author not found", _SQ_PLUGIN_NAME_))));
101
  }
102
  } else {
103
+ exit(wp_json_encode(array('error' => esc_html__("Author not found", _SQ_PLUGIN_NAME_))));
104
  }
105
  } else {
106
+ exit(wp_json_encode(array('error' => esc_html__("Author not found", _SQ_PLUGIN_NAME_))));
107
  }
108
 
109
  $post_ID = wp_insert_post($post->to_array());
110
  if (is_wp_error($post_ID)) {
111
+ echo wp_json_encode(array('error' => $post_ID->get_error_message()));
112
  } else {
113
+ echo wp_json_encode(array('saved' => true, 'post_ID' => $post_ID, 'permalink' => get_permalink($post_ID)));
114
  }
115
  exit();
116
  }
117
  }
118
+ echo wp_json_encode(array('error' => true));
119
  exit();
120
  }
121
 
136
  }
137
 
138
  if ($this->token <> $token) {
139
+ exit(wp_json_encode(array('error' => esc_html__("Connection expired. Please try again.", _SQ_PLUGIN_NAME_))));
140
  }
141
 
142
  $select = $request->get_param('select');
146
  case 'innerlinks':
147
  $url = $request->get_param('url');
148
  if ($url == '') {
149
+ exit(wp_json_encode(array('error' => esc_html__("Wrong Params", _SQ_PLUGIN_NAME_))));
150
  }
151
 
152
  //get post inner links
168
  case 'post':
169
  $url = $request->get_param('url');
170
  if ($url == '') {
171
+ exit(wp_json_encode(array('error' => esc_html__("Wrong Params", _SQ_PLUGIN_NAME_))));
172
  }
173
  //get Squirrly SEO post metas
174
  if ($post = SQ_Classes_ObjController::getClass('SQ_Models_Snippet')->setPostByURL($url)) {
184
 
185
  break;
186
  }
187
+ echo wp_json_encode($response);
188
 
189
  exit();
190
 
controllers/Assistant.php CHANGED
@@ -66,7 +66,7 @@ class SQ_Controllers_Assistant extends SQ_Classes_FrontController {
66
  $this->keywords = $json->keywords;
67
  } else {
68
 
69
- $this->error = __('No keyword found.', _SQ_PLUGIN_NAME_);
70
 
71
  }
72
 
@@ -105,15 +105,15 @@ class SQ_Controllers_Assistant extends SQ_Classes_FrontController {
105
  }
106
 
107
  //show the saved message
108
- SQ_Classes_Error::setMessage(__('Saved', _SQ_PLUGIN_NAME_));
109
 
110
  break;
111
 
112
  case 'sq_ajax_assistant':
113
  if (!current_user_can('sq_manage_snippets')) {
114
- $response['error'] = SQ_Classes_Error::showNotices(__("You do not have permission to perform this action", _SQ_PLUGIN_NAME_), 'sq_error');
115
  SQ_Classes_Helpers_Tools::setHeader('json');
116
- echo json_encode($response);
117
  exit();
118
  }
119
 
@@ -129,16 +129,16 @@ class SQ_Controllers_Assistant extends SQ_Classes_FrontController {
129
  if ($category_name <> '' && $name <> '') {
130
  if (!$option) $option = 'active';
131
  $dbtasks[$category_name][$name][$option] = $value;
132
- update_option(SQ_TASKS, json_encode($dbtasks));
133
  }
134
 
135
- $response['data'] = SQ_Classes_Error::showNotices(__('Saved', _SQ_PLUGIN_NAME_), 'sq_success');
136
- echo json_encode($response);
137
  exit;
138
  }
139
 
140
- $response['data'] = SQ_Classes_Error::showNotices(__('Error: Could not save the data.', _SQ_PLUGIN_NAME_), 'sq_error');
141
- echo json_encode($response);
142
  exit();
143
 
144
 
66
  $this->keywords = $json->keywords;
67
  } else {
68
 
69
+ $this->error = esc_html__("No keyword found.", _SQ_PLUGIN_NAME_);
70
 
71
  }
72
 
105
  }
106
 
107
  //show the saved message
108
+ SQ_Classes_Error::setMessage(esc_html__("Saved", _SQ_PLUGIN_NAME_));
109
 
110
  break;
111
 
112
  case 'sq_ajax_assistant':
113
  if (!current_user_can('sq_manage_snippets')) {
114
+ $response['error'] = SQ_Classes_Error::showNotices(esc_html__("You do not have permission to perform this action", _SQ_PLUGIN_NAME_), 'sq_error');
115
  SQ_Classes_Helpers_Tools::setHeader('json');
116
+ echo wp_json_encode($response);
117
  exit();
118
  }
119
 
129
  if ($category_name <> '' && $name <> '') {
130
  if (!$option) $option = 'active';
131
  $dbtasks[$category_name][$name][$option] = $value;
132
+ update_option(SQ_TASKS, wp_json_encode($dbtasks));
133
  }
134
 
135
+ $response['data'] = SQ_Classes_Error::showNotices(esc_html__("Saved", _SQ_PLUGIN_NAME_), 'sq_success');
136
+ echo wp_json_encode($response);
137
  exit;
138
  }
139
 
140
+ $response['data'] = SQ_Classes_Error::showNotices(esc_html__("Error: Could not save the data.", _SQ_PLUGIN_NAME_), 'sq_error');
141
+ echo wp_json_encode($response);
142
  exit();
143
 
144
 
controllers/Audits.php CHANGED
@@ -133,7 +133,7 @@ class SQ_Controllers_Audits extends SQ_Classes_FrontController {
133
  }
134
 
135
  } else {
136
- SQ_Classes_Error::setError(__('The audit was not found. Please load another audit.', _SQ_PLUGIN_NAME_));
137
 
138
  }
139
 
@@ -166,7 +166,7 @@ class SQ_Controllers_Audits extends SQ_Classes_FrontController {
166
  $this->audit = SQ_Classes_RemoteController::getAudit(array('days_back' => $days_back));
167
 
168
  if (is_wp_error($this->audit)) {
169
- SQ_Classes_Error::setError(__('Could not load the Audit Page.', _SQ_PLUGIN_NAME_));
170
  } elseif ($auditpages = SQ_Classes_RemoteController::getAuditPages()) {
171
 
172
  if (is_wp_error($auditpages)) {
@@ -255,7 +255,7 @@ class SQ_Controllers_Audits extends SQ_Classes_FrontController {
255
  if (SQ_Classes_Helpers_Tools::getValue('sq_debug') == 'on') {
256
  return;
257
  }
258
- echo json_encode($json);
259
  exit();
260
  }
261
  break;
@@ -280,17 +280,17 @@ class SQ_Controllers_Audits extends SQ_Classes_FrontController {
280
  $args['permalink'] = $post->url;
281
  if ($auditpage = SQ_Classes_RemoteController::addAuditPage($args)) {
282
  if (!is_wp_error($auditpage)) {
283
- SQ_Classes_Error::setError(__('Audit page is added. The audit may take a while so please be patient.', _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
284
  set_transient('sq_auditpage_all', time());
285
  } elseif ($auditpage->get_error_message() == 'limit_exceed') {
286
- SQ_Classes_Error::setError(__('You reached the maximum number of audit pages for your account.', _SQ_PLUGIN_NAME_) . " <br /> ");
287
  }
288
  } else {
289
- SQ_Classes_Error::setError(__('Error! Could not add the audit page.', _SQ_PLUGIN_NAME_) . " <br /> ");
290
  }
291
 
292
  } else {
293
- SQ_Classes_Error::setError(__('Error! Could not find the audit page in your website.', _SQ_PLUGIN_NAME_) . " <br /> ");
294
  }
295
  break;
296
  case 'sq_audits_update':
@@ -300,13 +300,13 @@ class SQ_Controllers_Audits extends SQ_Classes_FrontController {
300
 
301
  if ($auditpage = SQ_Classes_RemoteController::updateAudit()) {
302
  if (!is_wp_error($auditpage)) {
303
- SQ_Classes_Error::setError(__('Audit page sent for recheck. It may take a while so please be patient.', _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
304
  set_transient('sq_auditpage_all', time());
305
  } elseif ($auditpage->get_error_message() == 'too_many_attempts') {
306
- SQ_Classes_Error::setError(__("The audit for all pages can be made once an hour.", _SQ_PLUGIN_NAME_) . " <br /> ");
307
  }
308
  } else {
309
- SQ_Classes_Error::setError(__("The audit for all pages can be made once an hour.", _SQ_PLUGIN_NAME_) . " <br /> ");
310
  }
311
  break;
312
  case 'sq_audits_delete':
@@ -316,9 +316,9 @@ class SQ_Controllers_Audits extends SQ_Classes_FrontController {
316
 
317
  if ($user_post_id = SQ_Classes_Helpers_Tools::getValue('id', false)) {
318
  SQ_Classes_RemoteController::deleteAuditPage(array('user_post_id' => $user_post_id));
319
- SQ_Classes_Error::setError(__('The audit page is deleted', _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
320
  } else {
321
- SQ_Classes_Error::setError(__('Invalid params!', _SQ_PLUGIN_NAME_) . " <br /> ");
322
  }
323
 
324
  break;
@@ -339,9 +339,9 @@ class SQ_Controllers_Audits extends SQ_Classes_FrontController {
339
  ///////////////////////////////
340
 
341
  //show the saved message
342
- SQ_Classes_Error::setMessage(__('Saved', _SQ_PLUGIN_NAME_));
343
  } else {
344
- SQ_Classes_Error::setError(__('Not a valid email address', _SQ_PLUGIN_NAME_));
345
 
346
  }
347
 
133
  }
134
 
135
  } else {
136
+ SQ_Classes_Error::setError(esc_html__("The audit was not found. Please load another audit.", _SQ_PLUGIN_NAME_));
137
 
138
  }
139
 
166
  $this->audit = SQ_Classes_RemoteController::getAudit(array('days_back' => $days_back));
167
 
168
  if (is_wp_error($this->audit)) {
169
+ SQ_Classes_Error::setError(esc_html__("Could not load the Audit Page.", _SQ_PLUGIN_NAME_));
170
  } elseif ($auditpages = SQ_Classes_RemoteController::getAuditPages()) {
171
 
172
  if (is_wp_error($auditpages)) {
255
  if (SQ_Classes_Helpers_Tools::getValue('sq_debug') == 'on') {
256
  return;
257
  }
258
+ echo wp_json_encode($json);
259
  exit();
260
  }
261
  break;
280
  $args['permalink'] = $post->url;
281
  if ($auditpage = SQ_Classes_RemoteController::addAuditPage($args)) {
282
  if (!is_wp_error($auditpage)) {
283
+ SQ_Classes_Error::setError(esc_html__("Audit page is added. The audit may take a while so please be patient.", _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
284
  set_transient('sq_auditpage_all', time());
285
  } elseif ($auditpage->get_error_message() == 'limit_exceed') {
286
+ SQ_Classes_Error::setError(esc_html__("You reached the maximum number of audit pages for your account.", _SQ_PLUGIN_NAME_) . " <br /> ");
287
  }
288
  } else {
289
+ SQ_Classes_Error::setError(esc_html__("Error! Could not add the audit page.", _SQ_PLUGIN_NAME_) . " <br /> ");
290
  }
291
 
292
  } else {
293
+ SQ_Classes_Error::setError(esc_html__("Error! Could not find the audit page in your website.", _SQ_PLUGIN_NAME_) . " <br /> ");
294
  }
295
  break;
296
  case 'sq_audits_update':
300
 
301
  if ($auditpage = SQ_Classes_RemoteController::updateAudit()) {
302
  if (!is_wp_error($auditpage)) {
303
+ SQ_Classes_Error::setError(esc_html__("Audit page sent for recheck. It may take a while so please be patient.", _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
304
  set_transient('sq_auditpage_all', time());
305
  } elseif ($auditpage->get_error_message() == 'too_many_attempts') {
306
+ SQ_Classes_Error::setError(esc_html__("The audit for all pages can be made once an hour.", _SQ_PLUGIN_NAME_) . " <br /> ");
307
  }
308
  } else {
309
+ SQ_Classes_Error::setError(esc_html__("The audit for all pages can be made once an hour.", _SQ_PLUGIN_NAME_) . " <br /> ");
310
  }
311
  break;
312
  case 'sq_audits_delete':
316
 
317
  if ($user_post_id = SQ_Classes_Helpers_Tools::getValue('id', false)) {
318
  SQ_Classes_RemoteController::deleteAuditPage(array('user_post_id' => $user_post_id));
319
+ SQ_Classes_Error::setError(esc_html__("The audit page is deleted.", _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
320
  } else {
321
+ SQ_Classes_Error::setError(esc_html__("Invalid params!", _SQ_PLUGIN_NAME_) . " <br /> ");
322
  }
323
 
324
  break;
339
  ///////////////////////////////
340
 
341
  //show the saved message
342
+ SQ_Classes_Error::setMessage(esc_html__("Saved", _SQ_PLUGIN_NAME_));
343
  } else {
344
+ SQ_Classes_Error::setError(esc_html__("Not a valid email address.", _SQ_PLUGIN_NAME_));
345
 
346
  }
347
 
controllers/BulkSeo.php CHANGED
@@ -72,8 +72,8 @@ class SQ_Controllers_BulkSeo extends SQ_Classes_FrontController {
72
 
73
  $response = array();
74
  if (!current_user_can('sq_manage_snippet')) {
75
- $response['error'] = SQ_Classes_Error::showNotices(__("You do not have permission to perform this action", _SQ_PLUGIN_NAME_), 'sq_error');
76
- echo json_encode($response);
77
  exit();
78
  }
79
 
@@ -103,7 +103,7 @@ class SQ_Controllers_BulkSeo extends SQ_Classes_FrontController {
103
  }
104
  $json['assistant_dest'] = "#sq_assistant_" . $this->post->hash;
105
 
106
- echo json_encode($json);
107
  exit();
108
 
109
  }
72
 
73
  $response = array();
74
  if (!current_user_can('sq_manage_snippet')) {
75
+ $response['error'] = SQ_Classes_Error::showNotices(esc_html__("You do not have permission to perform this action", _SQ_PLUGIN_NAME_), 'sq_error');
76
+ echo wp_json_encode($response);
77
  exit();
78
  }
79
 
103
  }
104
  $json['assistant_dest'] = "#sq_assistant_" . $this->post->hash;
105
 
106
+ echo wp_json_encode($json);
107
  exit();
108
 
109
  }
controllers/CheckSeo.php CHANGED
@@ -48,6 +48,8 @@ class SQ_Controllers_CheckSeo extends SQ_Classes_FrontController {
48
  //Load the tasks from database and filter them
49
  $tasks = $this->model->getTasks();
50
 
 
 
51
  if (!empty($report)) {
52
 
53
  if (!isset($this->model->dbtasks['count_tasks_for_today'])) {
@@ -262,7 +264,7 @@ class SQ_Controllers_CheckSeo extends SQ_Classes_FrontController {
262
  switch (SQ_Classes_Helpers_Tools::getValue('action')) {
263
 
264
  case 'sq_checkseo':
265
- SQ_Classes_Error::setMessage(__('Done!', _SQ_PLUGIN_NAME_));
266
  //Check all the SEO
267
  //Process all the tasks and save the report
268
  $this->model->checkSEO();
@@ -272,7 +274,7 @@ class SQ_Controllers_CheckSeo extends SQ_Classes_FrontController {
272
  $this->model->dbtasks['tasks_for_today'] = array();
273
  $this->model->saveDbTasks();
274
 
275
- SQ_Classes_Error::setMessage(__('Done!', _SQ_PLUGIN_NAME_));
276
  //Check all the SEO
277
  //Process all the tasks and save the report
278
  $this->model->checkSEO();
@@ -289,25 +291,25 @@ class SQ_Controllers_CheckSeo extends SQ_Classes_FrontController {
289
  //Process all the tasks and save the report
290
  $this->model->checkSEO();
291
 
292
- SQ_Classes_Error::setMessage(__('Fixed!', _SQ_PLUGIN_NAME_));
293
  return;
294
  }
295
  }
296
 
297
- SQ_Classes_Error::setError(__('Could not fix it. You need to change it manually.', _SQ_PLUGIN_NAME_));
298
  break;
299
  case 'sq_donetask':
300
  $name = SQ_Classes_Helpers_Tools::getValue('name', false);
301
 
302
  $this->model->doneTask($name);
303
 
304
- SQ_Classes_Error::setMessage(__('Saved! Task marked as done.', _SQ_PLUGIN_NAME_));
305
  break;
306
  case 'sq_resetignored':
307
  //Remove ignored tasks
308
  $this->model->clearIgnoredTasks();
309
 
310
- SQ_Classes_Error::setMessage(__('Saved!', _SQ_PLUGIN_NAME_));
311
 
312
  break;
313
  case 'sq_ajax_checkseo':
@@ -322,7 +324,7 @@ class SQ_Controllers_CheckSeo extends SQ_Classes_FrontController {
322
  $json['error'] = SQ_Classes_Error::getError();
323
  }
324
 
325
- echo json_encode($json);
326
  exit();
327
  case 'sq_ajax_getgoals':
328
  SQ_Classes_Helpers_Tools::setHeader('json');
@@ -341,7 +343,7 @@ class SQ_Controllers_CheckSeo extends SQ_Classes_FrontController {
341
  $json['error'] = SQ_Classes_Error::getError();
342
  }
343
 
344
- echo json_encode($json);
345
  exit();
346
  }
347
 
48
  //Load the tasks from database and filter them
49
  $tasks = $this->model->getTasks();
50
 
51
+ // $this->model->dbtasks['tasks_for_today'] = array();
52
+ // $this->model->dbtasks['count_tasks_for_today'] = 300;
53
  if (!empty($report)) {
54
 
55
  if (!isset($this->model->dbtasks['count_tasks_for_today'])) {
264
  switch (SQ_Classes_Helpers_Tools::getValue('action')) {
265
 
266
  case 'sq_checkseo':
267
+ SQ_Classes_Error::setMessage(esc_html__("Done!", _SQ_PLUGIN_NAME_));
268
  //Check all the SEO
269
  //Process all the tasks and save the report
270
  $this->model->checkSEO();
274
  $this->model->dbtasks['tasks_for_today'] = array();
275
  $this->model->saveDbTasks();
276
 
277
+ SQ_Classes_Error::setMessage(esc_html__("Done!", _SQ_PLUGIN_NAME_));
278
  //Check all the SEO
279
  //Process all the tasks and save the report
280
  $this->model->checkSEO();
291
  //Process all the tasks and save the report
292
  $this->model->checkSEO();
293
 
294
+ SQ_Classes_Error::setMessage(esc_html__("Fixed!", _SQ_PLUGIN_NAME_));
295
  return;
296
  }
297
  }
298
 
299
+ SQ_Classes_Error::setError(esc_html__("Could not fix it. You need to change it manually.", _SQ_PLUGIN_NAME_));
300
  break;
301
  case 'sq_donetask':
302
  $name = SQ_Classes_Helpers_Tools::getValue('name', false);
303
 
304
  $this->model->doneTask($name);
305
 
306
+ SQ_Classes_Error::setMessage(esc_html__("Saved! Task marked as done.", _SQ_PLUGIN_NAME_));
307
  break;
308
  case 'sq_resetignored':
309
  //Remove ignored tasks
310
  $this->model->clearIgnoredTasks();
311
 
312
+ SQ_Classes_Error::setMessage(esc_html__("Saved!", _SQ_PLUGIN_NAME_));
313
 
314
  break;
315
  case 'sq_ajax_checkseo':
324
  $json['error'] = SQ_Classes_Error::getError();
325
  }
326
 
327
+ echo wp_json_encode($json);
328
  exit();
329
  case 'sq_ajax_getgoals':
330
  SQ_Classes_Helpers_Tools::setHeader('json');
343
  $json['error'] = SQ_Classes_Error::getError();
344
  }
345
 
346
+ echo wp_json_encode($json);
347
  exit();
348
  }
349
 
controllers/Dashboard.php CHANGED
@@ -33,7 +33,7 @@ class SQ_Controllers_Dashboard extends SQ_Classes_FrontController {
33
  //Process all the tasks and save the report
34
  SQ_Classes_ObjController::getClass('SQ_Models_CheckSeo')->checkSEO();
35
 
36
- echo json_encode(array('data' => $this->getView('Blocks/Dashboard')));
37
  exit();
38
 
39
  }
33
  //Process all the tasks and save the report
34
  SQ_Classes_ObjController::getClass('SQ_Models_CheckSeo')->checkSEO();
35
 
36
+ echo wp_json_encode(array('data' => $this->getView('Blocks/Dashboard')));
37
  exit();
38
 
39
  }
controllers/FocusPages.php CHANGED
@@ -150,7 +150,7 @@ class SQ_Controllers_FocusPages extends SQ_Classes_FrontController {
150
  $this->focuspages[] = SQ_Classes_ObjController::getClass('SQ_Models_FocusPages')->parseFocusPage($focuspage, $labels)->getFocusPage();
151
 
152
  } elseif ($focuspage->user_post_id) {
153
- SQ_Classes_Error::setError(__('Focus Page does not exist or was deleted from your website.', _SQ_PLUGIN_NAME_));
154
  SQ_Classes_RemoteController::deleteFocusPage(array('user_post_id' => $focuspage->user_post_id));
155
  }
156
  }
@@ -297,7 +297,7 @@ class SQ_Controllers_FocusPages extends SQ_Classes_FrontController {
297
  $json['error'] = SQ_Classes_Error::getError();
298
  }
299
 
300
- echo json_encode($json);
301
  exit();
302
 
303
  case 'sq_focuspages_getpage':
@@ -318,7 +318,7 @@ class SQ_Controllers_FocusPages extends SQ_Classes_FrontController {
318
  $json['error'] = SQ_Classes_Error::getError();
319
  }
320
 
321
- echo json_encode($json);
322
  exit();
323
  case 'sq_focuspages_addnew':
324
  if (!current_user_can('sq_manage_focuspages')) {
@@ -342,24 +342,24 @@ class SQ_Controllers_FocusPages extends SQ_Classes_FrontController {
342
  $args['permalink'] = $post->url;
343
  if ($focuspage = SQ_Classes_RemoteController::addFocusPage($args)) {
344
  if (!is_wp_error($focuspage)) {
345
- SQ_Classes_Error::setError(__('Focus page is added. The audit may take a while so please be patient.', _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
346
  if (isset($focuspage->user_post_id)) {
347
  set_transient('sq_auditpage_' . $focuspage->user_post_id, time());
348
 
349
  SQ_Classes_Helpers_Tools::saveOptions('seoreport_time', false);
350
  }
351
  } elseif ($focuspage->get_error_message() == 'limit_exceed') {
352
- SQ_Classes_Error::setError(__('You reached the maximum number of focus pages for all your websites.', _SQ_PLUGIN_NAME_) . " <br /> ");
353
  }
354
  } else {
355
- SQ_Classes_Error::setError(__('Error! Could not add the focus page.', _SQ_PLUGIN_NAME_) . " <br /> ");
356
  }
357
  } else {
358
- SQ_Classes_Error::setError(__('Error! This focus page is not public.', _SQ_PLUGIN_NAME_) . " <br /> ");
359
  }
360
 
361
  } else {
362
- SQ_Classes_Error::setError(__('Error! Could not find the focus page in your website.', _SQ_PLUGIN_NAME_) . " <br /> ");
363
  }
364
  break;
365
  case 'sq_focuspages_update':
@@ -386,19 +386,19 @@ class SQ_Controllers_FocusPages extends SQ_Classes_FrontController {
386
  if ($focuspage = SQ_Classes_RemoteController::updateFocusPage($args)) {
387
 
388
  if (!is_wp_error($focuspage)) {
389
- SQ_Classes_Error::setError(__('Focus page sent for recheck. It may take a while so please be patient.', _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
390
  set_transient('sq_auditpage_' . $user_post_id, time());
391
  } elseif ($focuspage->get_error_message() == 'too_many_attempts') {
392
- SQ_Classes_Error::setError(__("You've made too many requests, please wait a few minutes.", _SQ_PLUGIN_NAME_) . " <br /> ");
393
  }
394
 
395
  } else {
396
- SQ_Classes_Error::setError(__("You've made too many requests, please wait a few minutes.", _SQ_PLUGIN_NAME_) . " <br /> ");
397
  set_transient('sq_auditpage_' . $user_post_id, time());
398
  }
399
 
400
  } else {
401
- SQ_Classes_Error::setError(__('Error! Could not find the focus page in your website.', _SQ_PLUGIN_NAME_) . " <br /> ");
402
  }
403
  }
404
  break;
@@ -409,9 +409,9 @@ class SQ_Controllers_FocusPages extends SQ_Classes_FrontController {
409
 
410
  if ($user_post_id = SQ_Classes_Helpers_Tools::getValue('id', false)) {
411
  SQ_Classes_RemoteController::deleteFocusPage(array('user_post_id' => $user_post_id));
412
- SQ_Classes_Error::setError(__('The focus page is deleted', _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
413
  } else {
414
- SQ_Classes_Error::setError(__('Invalid params!', _SQ_PLUGIN_NAME_) . " <br /> ");
415
  }
416
 
417
  break;
150
  $this->focuspages[] = SQ_Classes_ObjController::getClass('SQ_Models_FocusPages')->parseFocusPage($focuspage, $labels)->getFocusPage();
151
 
152
  } elseif ($focuspage->user_post_id) {
153
+ SQ_Classes_Error::setError(esc_html__("Focus Page does not exist or was deleted from your website.", _SQ_PLUGIN_NAME_));
154
  SQ_Classes_RemoteController::deleteFocusPage(array('user_post_id' => $focuspage->user_post_id));
155
  }
156
  }
297
  $json['error'] = SQ_Classes_Error::getError();
298
  }
299
 
300
+ echo wp_json_encode($json);
301
  exit();
302
 
303
  case 'sq_focuspages_getpage':
318
  $json['error'] = SQ_Classes_Error::getError();
319
  }
320
 
321
+ echo wp_json_encode($json);
322
  exit();
323
  case 'sq_focuspages_addnew':
324
  if (!current_user_can('sq_manage_focuspages')) {
342
  $args['permalink'] = $post->url;
343
  if ($focuspage = SQ_Classes_RemoteController::addFocusPage($args)) {
344
  if (!is_wp_error($focuspage)) {
345
+ SQ_Classes_Error::setError(esc_html__("Focus page is added. The audit may take a while so please be patient.", _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
346
  if (isset($focuspage->user_post_id)) {
347
  set_transient('sq_auditpage_' . $focuspage->user_post_id, time());
348
 
349
  SQ_Classes_Helpers_Tools::saveOptions('seoreport_time', false);
350
  }
351
  } elseif ($focuspage->get_error_message() == 'limit_exceed') {
352
+ SQ_Classes_Error::setError(esc_html__("You reached the maximum number of focus pages for all your websites.", _SQ_PLUGIN_NAME_) . " <br /> ");
353
  }
354
  } else {
355
+ SQ_Classes_Error::setError(esc_html__("Error! Could not add the focus page.", _SQ_PLUGIN_NAME_) . " <br /> ");
356
  }
357
  } else {
358
+ SQ_Classes_Error::setError(esc_html__("Error! This focus page is not public.", _SQ_PLUGIN_NAME_) . " <br /> ");
359
  }
360
 
361
  } else {
362
+ SQ_Classes_Error::setError(esc_html__("Error! Could not find the focus page in your website.", _SQ_PLUGIN_NAME_) . " <br /> ");
363
  }
364
  break;
365
  case 'sq_focuspages_update':
386
  if ($focuspage = SQ_Classes_RemoteController::updateFocusPage($args)) {
387
 
388
  if (!is_wp_error($focuspage)) {
389
+ SQ_Classes_Error::setError(esc_html__("Focus page sent for recheck. It may take a while so please be patient.", _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
390
  set_transient('sq_auditpage_' . $user_post_id, time());
391
  } elseif ($focuspage->get_error_message() == 'too_many_attempts') {
392
+ SQ_Classes_Error::setError(esc_html__("You've made too many requests, please wait a few minutes.", _SQ_PLUGIN_NAME_) . " <br /> ");
393
  }
394
 
395
  } else {
396
+ SQ_Classes_Error::setError(esc_html__("You've made too many requests, please wait a few minutes.", _SQ_PLUGIN_NAME_) . " <br /> ");
397
  set_transient('sq_auditpage_' . $user_post_id, time());
398
  }
399
 
400
  } else {
401
+ SQ_Classes_Error::setError(esc_html__("Error! Could not find the focus page in your website.", _SQ_PLUGIN_NAME_) . " <br /> ");
402
  }
403
  }
404
  break;
409
 
410
  if ($user_post_id = SQ_Classes_Helpers_Tools::getValue('id', false)) {
411
  SQ_Classes_RemoteController::deleteFocusPage(array('user_post_id' => $user_post_id));
412
+ SQ_Classes_Error::setError(esc_html__("The focus page is deleted", _SQ_PLUGIN_NAME_) . " <br /> ", 'success');
413
  } else {
414
+ SQ_Classes_Error::setError(esc_html__("Invalid params!", _SQ_PLUGIN_NAME_) . " <br /> ");
415
  }
416
 
417
  break;
controllers/Frontend.php CHANGED
@@ -130,7 +130,7 @@ class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
130
  if (is_feed()) {
131
  $find = $replace = $urls = array();
132
 
133
- @preg_match_all('/<img[^>]*src=[\'"]([^\'"]+)[\'"][^>]*>/i', $content, $out);
134
  if (is_array($out)) {
135
  if (!is_array($out[1]) || empty($out[1]))
136
  return $content;
@@ -144,7 +144,7 @@ class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
144
  }
145
  }
146
 
147
- @preg_match_all('/<a[^>]*href=[\'"]([^\'"]+)[\'"][^>]*>/i', $content, $out);
148
  if (is_array($out)) {
149
  if (!is_array($out[1]) || empty($out[1]))
150
  return $content;
@@ -179,7 +179,7 @@ class SQ_Controllers_Frontend extends SQ_Classes_FrontController {
179
  * Hook the footer
180
  */
181
  public function hookFrontfooter() {
182
- echo $this->model->getFooter();
183
  }
184
 
185
  /**
130
  if (is_feed()) {
131
  $find = $replace = $urls = array();
132
 
133
+ preg_match_all('/<img[^>]*src=[\'"]([^\'"]+)[\'"][^>]*>/i', $content, $out);
134
  if (is_array($out)) {
135
  if (!is_array($out[1]) || empty($out[1]))
136
  return $content;
144
  }
145
  }
146
 
147
+ preg_match_all('/<a[^>]*href=[\'"]([^\'"]+)[\'"][^>]*>/i', $content, $out);
148
  if (is_array($out)) {
149
  if (!is_array($out[1]) || empty($out[1]))
150
  return $content;
179
  * Hook the footer
180
  */
181
  public function hookFrontfooter() {
182
+ echo (string)$this->model->getFooter();
183
  }
184
 
185
  /**
controllers/Menu.php CHANGED
@@ -29,6 +29,12 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
29
  //Hook the Frontend Editors
30
  $this->hookBuilders();
31
  }
 
 
 
 
 
 
32
  }
33
 
34
  /**
@@ -120,7 +126,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
120
  flush_rewrite_rules();
121
  }
122
  } catch (Exception $e) {
123
- SQ_Classes_Error::setMessage(sprintf(__("An error occurred during activation. If this error persists, please contact us at: %s", _SQ_PLUGIN_NAME_), _SQ_SUPPORT_URL_));
124
  }
125
 
126
 
@@ -159,7 +165,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
159
  $wp_admin_bar->add_node(array(
160
  'parent' => 'site-name',
161
  'id' => 'dashboard',
162
- 'title' => __('Dashboard'),
163
  'href' => admin_url(),
164
  ));
165
  }
@@ -184,7 +190,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
184
 
185
  $wp_admin_bar->add_node(array(
186
  'id' => 'sq_toolbar',
187
- 'title' => '<span class="sq_logo" style="margin-right: 2px"></span>' . __('Squirrly SEO', _SQ_PLUGIN_NAME_) . (($errors) ? '<span class="sq_errorcount">' . $errors . '</span>' : ''),
188
  'href' => SQ_Classes_Helpers_Tools::getAdminUrl('sq_dashboard'),
189
  'parent' => false
190
  ));
@@ -258,7 +264,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
258
  }
259
 
260
  $this->model->addMeta(array('sq_blocksnippet',
261
- ucfirst(_SQ_NAME_) . ' ' . __('SEO Snippet', _SQ_PLUGIN_NAME_),
262
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Snippet'), 'init'),
263
  null,
264
  'normal',
@@ -273,7 +279,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
273
 
274
  $wp_admin_bar->add_node(array(
275
  'id' => 'sq_bar_menu',
276
- 'title' => $style . '<span class="sq_logo"></span> ' . __('Custom SEO', _SQ_PLUGIN_NAME_),
277
  'parent' => 'top-secondary',
278
  ));
279
 
@@ -295,7 +301,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
295
  public function hookDashboardSetup() {
296
  wp_add_dashboard_widget(
297
  'sq_dashboard_widget',
298
- __('Squirrly SEO', _SQ_PLUGIN_NAME_),
299
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Dashboard'), 'dashboard')
300
  );
301
 
@@ -330,7 +336,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
330
 
331
  ///////////////
332
  $this->model->addMenu(array(ucfirst(_SQ_NAME_),
333
- __('Squirrly SEO', _SQ_PLUGIN_NAME_) . (($errors) ? '<span class="sq_errorcount">' . $errors . '</span>' : ''),
334
  'edit_posts',
335
  'sq_dashboard',
336
  null,
@@ -338,8 +344,8 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
338
  ));
339
 
340
  $this->model->addSubmenu(array('sq_none',
341
- __('Squirrly Onboarding', _SQ_PLUGIN_NAME_),
342
- __('Onboarding', _SQ_PLUGIN_NAME_),
343
  'edit_posts',
344
  'sq_onboarding',
345
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Onboarding'), 'init')
@@ -368,8 +374,8 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
368
  }
369
 
370
  $this->model->addSubmenu(array('sq_dashboard',
371
- __("Import & Export SEO", _SQ_PLUGIN_NAME_),
372
- __("Import SEO", _SQ_PLUGIN_NAME_),
373
  'sq_manage_settings',
374
  'sq_import',
375
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_SeoSettings'), 'init')
@@ -379,8 +385,8 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
379
  if (current_user_can('sq_manage_settings')) {
380
  if (SQ_Classes_Helpers_Tools::getMenuVisible('show_account_info')) {
381
  $this->model->addSubmenu(array('sq_dashboard',
382
- __('Squirrly Account Info', _SQ_PLUGIN_NAME_),
383
- __('Account Info', _SQ_PLUGIN_NAME_),
384
  'manage_options',
385
  'sq_account',
386
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Account'), 'init')
@@ -389,8 +395,8 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
389
  }
390
 
391
  $this->model->addSubmenu(array('sq_dashboard',
392
- __('Squirrly How To & Support', _SQ_PLUGIN_NAME_),
393
- __('Help & Support', _SQ_PLUGIN_NAME_),
394
  'edit_posts',
395
  'sq_help',
396
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Help'), 'init')
29
  //Hook the Frontend Editors
30
  $this->hookBuilders();
31
  }
32
+
33
+ add_action( 'current_screen', function () {
34
+ if (in_array( get_current_screen()->id, array('plugins', 'plugins-network') )) {
35
+ SQ_Classes_ObjController::getClass('SQ_Controllers_Uninstall');
36
+ }
37
+ } );
38
  }
39
 
40
  /**
126
  flush_rewrite_rules();
127
  }
128
  } catch (Exception $e) {
129
+ SQ_Classes_Error::setMessage(sprintf(esc_html__("An error occurred during activation. If this error persists, please contact us at: %s", _SQ_PLUGIN_NAME_), _SQ_SUPPORT_URL_));
130
  }
131
 
132
 
165
  $wp_admin_bar->add_node(array(
166
  'parent' => 'site-name',
167
  'id' => 'dashboard',
168
+ 'title' => esc_html__("Dashboard"),
169
  'href' => admin_url(),
170
  ));
171
  }
190
 
191
  $wp_admin_bar->add_node(array(
192
  'id' => 'sq_toolbar',
193
+ 'title' => '<span class="sq_logo" style="margin-right: 2px"></span>' . esc_html__("Squirrly SEO", _SQ_PLUGIN_NAME_) . (($errors) ? '<span class="sq_errorcount">' . $errors . '</span>' : ''),
194
  'href' => SQ_Classes_Helpers_Tools::getAdminUrl('sq_dashboard'),
195
  'parent' => false
196
  ));
264
  }
265
 
266
  $this->model->addMeta(array('sq_blocksnippet',
267
+ ucfirst(_SQ_NAME_) . ' ' . esc_html__("SEO Snippet", _SQ_PLUGIN_NAME_),
268
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Snippet'), 'init'),
269
  null,
270
  'normal',
279
 
280
  $wp_admin_bar->add_node(array(
281
  'id' => 'sq_bar_menu',
282
+ 'title' => $style . '<span class="sq_logo"></span> ' . esc_html__("Custom SEO", _SQ_PLUGIN_NAME_),
283
  'parent' => 'top-secondary',
284
  ));
285
 
301
  public function hookDashboardSetup() {
302
  wp_add_dashboard_widget(
303
  'sq_dashboard_widget',
304
+ esc_html__("Squirrly SEO", _SQ_PLUGIN_NAME_),
305
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Dashboard'), 'dashboard')
306
  );
307
 
336
 
337
  ///////////////
338
  $this->model->addMenu(array(ucfirst(_SQ_NAME_),
339
+ esc_html__("Squirrly SEO", _SQ_PLUGIN_NAME_) . (($errors) ? '<span class="sq_errorcount">' . $errors . '</span>' : ''),
340
  'edit_posts',
341
  'sq_dashboard',
342
  null,
344
  ));
345
 
346
  $this->model->addSubmenu(array('sq_none',
347
+ esc_html__("Squirrly Onboarding", _SQ_PLUGIN_NAME_),
348
+ esc_html__("Onboarding", _SQ_PLUGIN_NAME_),
349
  'edit_posts',
350
  'sq_onboarding',
351
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Onboarding'), 'init')
374
  }
375
 
376
  $this->model->addSubmenu(array('sq_dashboard',
377
+ esc_html__("Import & Export SEO", _SQ_PLUGIN_NAME_),
378
+ esc_html__("Import SEO", _SQ_PLUGIN_NAME_),
379
  'sq_manage_settings',
380
  'sq_import',
381
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_SeoSettings'), 'init')
385
  if (current_user_can('sq_manage_settings')) {
386
  if (SQ_Classes_Helpers_Tools::getMenuVisible('show_account_info')) {
387
  $this->model->addSubmenu(array('sq_dashboard',
388
+ esc_html__("Squirrly Account Info", _SQ_PLUGIN_NAME_),
389
+ esc_html__("Account Info", _SQ_PLUGIN_NAME_),
390
  'manage_options',
391
  'sq_account',
392
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Account'), 'init')
395
  }
396
 
397
  $this->model->addSubmenu(array('sq_dashboard',
398
+ esc_html__("Squirrly How To & Support", _SQ_PLUGIN_NAME_),
399
+ esc_html__("Help & Support", _SQ_PLUGIN_NAME_),
400
  'edit_posts',
401
  'sq_help',
402
  array(SQ_Classes_ObjController::getClass('SQ_Controllers_Help'), 'init')
controllers/Overview.php CHANGED
@@ -53,7 +53,7 @@ class SQ_Controllers_Overview extends SQ_Classes_FrontController {
53
  <input type="hidden" name="alert" value="sq_alert_overview"/>
54
  <button type="submit" class="btn float-right bg-transparent p-0 m-0">x</button>
55
  </form>
56
- <?php echo sprintf(__("Detected %s: We encourage you to %sImport the Settings and SEO%s from %s and deactivate %s to increase the page loading speed for better Google ranking.", _SQ_PLUGIN_NAME_), '<strong>' . $plugin . '</strong>', '<a href="' . SQ_Classes_Helpers_Tools::getAdminUrl('sq_seosettings', 'backup') . '" style="font-weight: bold;" >', '</a>', $plugin, $plugin); ?>
57
  </div>
58
  <?php
59
  break;
53
  <input type="hidden" name="alert" value="sq_alert_overview"/>
54
  <button type="submit" class="btn float-right bg-transparent p-0 m-0">x</button>
55
  </form>
56
+ <?php echo sprintf(esc_html__("Detected %s: We encourage you to %sImport the Settings and SEO%s from %s and deactivate %s to increase the page loading speed for better Google ranking.", _SQ_PLUGIN_NAME_), '<strong>' . $plugin . '</strong>', '<a href="' . SQ_Classes_Helpers_Tools::getAdminUrl('sq_seosettings', 'backup') . '" style="font-weight: bold;" >', '</a>', $plugin, $plugin); ?>
57
  </div>
58
  <?php
59
  break;
controllers/Patterns.php CHANGED
@@ -7,20 +7,20 @@ class SQ_Controllers_Patterns extends SQ_Classes_FrontController {
7
  public $patterns;
8
 
9
  public function init() {
10
- if(is_rtl()){
11
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('sqbootstrap.rtl', array('trigger' => true, 'media' => 'all'));
12
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('rtl', array('trigger' => true, 'media' => 'all'));
13
- }else{
14
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('sqbootstrap', array('trigger' => true, 'media' => 'all'));
15
  }
16
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('patterns', array('trigger' => true, 'media' => 'all'));
17
 
18
  echo '
19
  <script>
20
- jQuery.sq_patterns_list = jQuery.parseJSON("' . addslashes(SQ_ALL_PATTERNS) . '");
21
- var __sq_save_message = "' . __('Saved!', _SQ_PLUGIN_NAME_) . '";
22
- var __sq_save_message_preview = "' . __('Saved! This is how the preview looks like', _SQ_PLUGIN_NAME_) . '";
23
- </script>';
24
  }
25
 
26
  /**
@@ -72,16 +72,18 @@ class SQ_Controllers_Patterns extends SQ_Classes_FrontController {
72
  $object->$name = preg_replace('/%%([^\%]+)%%/s', '{{$1}}', $object->$name);
73
  }
74
 
75
- if (@strpos($value, '{{') !== false && @strpos($value, '}}') !== false) {
76
- $sq_with_patterns[$name] = $value;
 
 
77
  }
78
  }
79
  }
80
  if (!empty($sq_with_patterns)) {
81
  foreach ($this->patterns->getPatterns() as $key => $pattern) {
82
  foreach ($sq_with_patterns as $name => $value) {
83
- if ($name <> '' && $value <> '') {
84
- if (@strpos($value, $pattern) !== false) {
85
  $object->$name = str_replace($pattern, $this->patterns->$key, $object->$name);
86
  }
87
  }
@@ -102,9 +104,9 @@ class SQ_Controllers_Patterns extends SQ_Classes_FrontController {
102
  parent::action();
103
 
104
  if (!current_user_can('sq_manage_snippet')) {
105
- $response['error'] = SQ_Classes_Error::showNotices(__("You do not have permission to perform this action", _SQ_PLUGIN_NAME_), 'sq_error');
106
  SQ_Classes_Helpers_Tools::setHeader('json');
107
- echo json_encode($response);
108
  exit();
109
  }
110
 
@@ -138,7 +140,7 @@ class SQ_Controllers_Patterns extends SQ_Classes_FrontController {
138
  SQ_Classes_Helpers_Tools::setHeader('json');
139
 
140
  if (SQ_Classes_Helpers_Tools::getValue('sq_debug') !== 'on') {
141
- echo json_encode(array('json' => json_encode($all_patterns)));
142
  } else {
143
  SQ_Debug::dump($all_patterns, $patterns);
144
  }
7
  public $patterns;
8
 
9
  public function init() {
10
+ if (is_rtl()) {
11
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('sqbootstrap.rtl', array('trigger' => true, 'media' => 'all'));
12
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('rtl', array('trigger' => true, 'media' => 'all'));
13
+ } else {
14