SEO SQUIRRLY™ - Version 9.2.12

Version Description

  • 09/17/2019 =
  • SEO Update - Tested and Compatible with WordPress 5.2.3
  • SEO Update - Added Yandex SEO support for Yandex.com
  • Fix - ranking assistant to set all green on average possitions
  • Fix - Fixed the Squirrly SEO Admin role
  • Fix - Fixed the Russian chars in Focus Pages, Bulk SEO and Squirrly SEO Snippet
Download this release

Release Info

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

Code changes from version 9.2.10 to 9.2.12

classes/ObjController.php CHANGED
@@ -9,9 +9,9 @@ class SQ_Classes_ObjController {
9
  public static $instances;
10
 
11
  /**
12
- * @param $className
13
  * @param array $args
14
- * @return bool|mixed
15
  */
16
  public static function getClass($className, $args = array()) {
17
 
9
  public static $instances;
10
 
11
  /**
12
+ * @param $className $className
13
  * @param array $args
14
+ * @return object|false
15
  */
16
  public static function getClass($className, $args = array()) {
17
 
classes/helpers/Tools.php CHANGED
@@ -843,6 +843,24 @@ class SQ_Classes_Helpers_Tools {
843
  return (isset($_GET[$key]) || isset($_POST[$key]));
844
  }
845
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
846
  /**
847
  * Load the multilanguage support from .mo
848
  */
843
  return (isset($_GET[$key]) || isset($_POST[$key]));
844
  }
845
 
846
+
847
+ /**
848
+ * Find the string in the content
849
+ *
850
+ * @param string $content
851
+ * @param string $string
852
+ * @return bool|false|int
853
+ */
854
+ public static function findStr($content, $string) {
855
+ if (function_exists('mb_stripos')) {
856
+ return mb_stripos($content, $string);
857
+ } else {
858
+ SQ_Classes_Error::setMessage(sprintf(__("For better text comparison you need to install PHP mbstring extension.", _SQ_PLUGIN_NAME_), _QSS_PLUGIN_NAME_));
859
+
860
+ return stripos($content, $string);
861
+ }
862
+ }
863
+
864
  /**
865
  * Load the multilanguage support from .mo
866
  */
config.json CHANGED
@@ -45,7 +45,6 @@
45
  "actions": {
46
  "action": [
47
  "sq_save_ogimage",
48
- "sq_get_keyword",
49
  "sq_create_demo",
50
  "sq_ajax_type_click",
51
  "sq_ajax_search_blog"
45
  "actions": {
46
  "action": [
47
  "sq_save_ogimage",
 
48
  "sq_create_demo",
49
  "sq_ajax_type_click",
50
  "sq_ajax_search_blog"
controllers/FocusPages.php CHANGED
@@ -94,7 +94,7 @@ class SQ_Controllers_FocusPages extends SQ_Classes_FrontController {
94
  if ($post = SQ_Classes_ObjController::getClass('SQ_Models_Snippet')->setPostByID($post)) {
95
  //Search the Squirrly Title, Description and URL if search is set
96
  if ($search <> '') {
97
- if (stripos($post->post_title, $search) === false && stripos($post->sq->title, $search) === false && stripos($post->sq->description, $search) === false && stripos($post->url, $search) === false) {
98
  continue;
99
  }
100
  }
@@ -136,7 +136,7 @@ class SQ_Controllers_FocusPages extends SQ_Classes_FrontController {
136
  //Get the audits for the focus pages
137
  $audits = SQ_Classes_RemoteController::getFocusAudits();
138
 
139
- if(!empty($focuspages)) {
140
  foreach ($focuspages as $focuspage) {
141
  //Add the audit data if exists
142
  if (isset($focuspage->user_post_id) && !empty($audits)) {
94
  if ($post = SQ_Classes_ObjController::getClass('SQ_Models_Snippet')->setPostByID($post)) {
95
  //Search the Squirrly Title, Description and URL if search is set
96
  if ($search <> '') {
97
+ if (SQ_Classes_Helpers_Tools::findStr($post->post_title, $search) === false && SQ_Classes_Helpers_Tools::findStr($post->sq->title, $search) === false && SQ_Classes_Helpers_Tools::findStr($post->sq->description, $search) === false && SQ_Classes_Helpers_Tools::findStr($post->url, $search) === false) {
98
  continue;
99
  }
100
  }
136
  //Get the audits for the focus pages
137
  $audits = SQ_Classes_RemoteController::getFocusAudits();
138
 
139
+ if (!empty($focuspages)) {
140
  foreach ($focuspages as $focuspage) {
141
  //Add the audit data if exists
142
  if (isset($focuspage->user_post_id) && !empty($audits)) {
controllers/Patterns.php CHANGED
@@ -33,6 +33,10 @@ class SQ_Controllers_Patterns extends SQ_Classes_FrontController {
33
 
34
  //Foreach SQ, if has patterns, replace them
35
  if ($sq_array = $post->sq->toArray()) {
 
 
 
 
36
  $post->sq = $this->processPatterns($sq_array, $post->sq);
37
  }
38
  }
33
 
34
  //Foreach SQ, if has patterns, replace them
35
  if ($sq_array = $post->sq->toArray()) {
36
+
37
+ //set the keywords from sq and not from post
38
+ $this->patterns->keywords = $post->sq->keywords;
39
+
40
  $post->sq = $this->processPatterns($sq_array, $post->sq);
41
  }
42
  }
controllers/Post.php CHANGED
@@ -211,16 +211,6 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
211
  get_post_status($postarr['ID']) != 'auto-draft' &&
212
  get_post_status($postarr['ID']) != 'inherit'
213
  ) {
214
- //Save the keyword for this post
215
- if ($json = $this->model->getKeyword($postarr['ID'])) {
216
- $json->keyword = addslashes(SQ_Classes_Helpers_Tools::getValue('sq_keyword'));
217
- $this->model->saveKeyword($postarr['ID'], $json);
218
- } else {
219
- $args = array();
220
- $args['keyword'] = addslashes(SQ_Classes_Helpers_Tools::getValue('sq_keyword'));
221
- $this->model->saveKeyword($postarr['ID'], json_decode(json_encode($args)));
222
- }
223
-
224
  //Save the snippet in case is edited in backend and not saved
225
  SQ_Classes_ObjController::getClass('SQ_Models_Snippet')->saveSEO();
226
 
@@ -270,23 +260,6 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
270
  echo json_encode($return);
271
  exit();
272
 
273
- case 'sq_get_keyword':
274
- if (!current_user_can('sq_manage_snippet')) {
275
- $response['error'] = SQ_Classes_Error::showNotices(__("You do not have permission to perform this action", _SQ_PLUGIN_NAME_), 'sq_error');
276
- SQ_Classes_Helpers_Tools::setHeader('json');
277
- echo json_encode($response);
278
- exit();
279
- }
280
-
281
- SQ_Classes_Helpers_Tools::setHeader('json');
282
- if (SQ_Classes_Helpers_Tools::getIsset('post_id')) {
283
- echo json_encode($this->model->getKeywordsFromPost(SQ_Classes_Helpers_Tools::getValue('post_id')));
284
- } else {
285
- echo json_encode(array('error' => true));
286
- }
287
- SQ_Classes_Helpers_Tools::emptyCache();
288
- break;
289
-
290
  case 'sq_create_demo':
291
  $post_type = 'post';
292
  if (post_type_exists($post_type)) {
@@ -294,6 +267,8 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
294
  $json = json_decode(file_get_contents(_SQ_ROOT_DIR_ . 'demo.json'));
295
 
296
  if (isset($json->demo->title) && isset($json->demo->content)) {
 
 
297
  $args = array();
298
  $args['s'] = '"' . addslashes($json->demo->title) . '"';
299
  $args['post_type'] = $post_type;
@@ -314,10 +289,6 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
314
 
315
  if ($post_id = wp_insert_post($post)) {
316
  if (!is_wp_error($post_id)) {
317
- $args = array();
318
- $args['keyword'] = $json->demo->keyword;
319
- $this->model->saveKeyword($post_id, json_decode(json_encode($args)));
320
-
321
  wp_redirect(admin_url("post.php?post=" . $post_id . "&action=edit&post_type=" . $post_type));
322
  exit();
323
 
@@ -381,6 +352,11 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
381
  private function _checkBriefcaseKeywords($post_id) {
382
  if (SQ_Classes_Helpers_Tools::getIsset('sq_hash')) {
383
  $keywords = SQ_Classes_Helpers_Tools::getValue('sq_briefcase_keyword', array());
 
 
 
 
 
384
  if (!empty($keywords)) {
385
  $sq_hash = SQ_Classes_Helpers_Tools::getValue('sq_hash', md5($post_id));
386
  $url = SQ_Classes_Helpers_Tools::getValue('sq_url', get_permalink($post_id));
211
  get_post_status($postarr['ID']) != 'auto-draft' &&
212
  get_post_status($postarr['ID']) != 'inherit'
213
  ) {
 
 
 
 
 
 
 
 
 
 
214
  //Save the snippet in case is edited in backend and not saved
215
  SQ_Classes_ObjController::getClass('SQ_Models_Snippet')->saveSEO();
216
 
260
  echo json_encode($return);
261
  exit();
262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  case 'sq_create_demo':
264
  $post_type = 'post';
265
  if (post_type_exists($post_type)) {
267
  $json = json_decode(file_get_contents(_SQ_ROOT_DIR_ . 'demo.json'));
268
 
269
  if (isset($json->demo->title) && isset($json->demo->content)) {
270
+ @setrawcookie('sq_keyword', rawurlencode($json->demo->keyword), strtotime('+1 hour'), COOKIEPATH, COOKIE_DOMAIN, is_ssl());
271
+
272
  $args = array();
273
  $args['s'] = '"' . addslashes($json->demo->title) . '"';
274
  $args['post_type'] = $post_type;
289
 
290
  if ($post_id = wp_insert_post($post)) {
291
  if (!is_wp_error($post_id)) {
 
 
 
 
292
  wp_redirect(admin_url("post.php?post=" . $post_id . "&action=edit&post_type=" . $post_type));
293
  exit();
294
 
352
  private function _checkBriefcaseKeywords($post_id) {
353
  if (SQ_Classes_Helpers_Tools::getIsset('sq_hash')) {
354
  $keywords = SQ_Classes_Helpers_Tools::getValue('sq_briefcase_keyword', array());
355
+
356
+ if (empty($keywords)) { //if not from brifcase, check the keyword
357
+ $keywords[] = SQ_Classes_Helpers_Tools::getValue('sq_keyword');
358
+ }
359
+
360
  if (!empty($keywords)) {
361
  $sq_hash = SQ_Classes_Helpers_Tools::getValue('sq_hash', md5($post_id));
362
  $url = SQ_Classes_Helpers_Tools::getValue('sq_url', get_permalink($post_id));
controllers/SeoSettings.php CHANGED
@@ -120,7 +120,7 @@ class SQ_Controllers_SeoSettings extends SQ_Classes_FrontController {
120
  if ($page->url <> '') {
121
  //Search the Squirrly Title, Description and URL if search is set
122
  if ($search <> '' && $search <> '#all') {
123
- if (stripos($page->sq->title, $search) === false && stripos($page->sq->description, $search) === false && stripos($page->url, $search) === false) {
124
  continue;
125
  }
126
  }
@@ -166,7 +166,7 @@ class SQ_Controllers_SeoSettings extends SQ_Classes_FrontController {
166
  if ($page = SQ_Classes_ObjController::getClass('SQ_Models_BulkSeo')->parsePage($post, $labels)->getPage()) {
167
  if ($page->url <> '') {
168
  if ($search <> '') {
169
- if (stripos($category->name, $search) === false && stripos($category->slug, $search) === false && stripos($page->sq->title, $search) === false) {
170
  continue;
171
  }
172
  }
120
  if ($page->url <> '') {
121
  //Search the Squirrly Title, Description and URL if search is set
122
  if ($search <> '' && $search <> '#all') {
123
+ if (SQ_Classes_Helpers_Tools::findStr($page->sq->title, $search) === false && SQ_Classes_Helpers_Tools::findStr($page->sq->description, $search) === false && SQ_Classes_Helpers_Tools::findStr($page->url, $search) === false) {
124
  continue;
125
  }
126
  }
166
  if ($page = SQ_Classes_ObjController::getClass('SQ_Models_BulkSeo')->parsePage($post, $labels)->getPage()) {
167
  if ($page->url <> '') {
168
  if ($search <> '') {
169
+ if (SQ_Classes_Helpers_Tools::findStr($category->name, $search) === false && SQ_Classes_Helpers_Tools::findStr($category->slug, $search) === false && SQ_Classes_Helpers_Tools::findStr($page->sq->title, $search) === false) {
170
  continue;
171
  }
172
  }
debug/index.php CHANGED
@@ -196,7 +196,7 @@ class SQ_Debug {
196
  }
197
 
198
 
199
- echo '<pre><div id="wpcontent">' . $debug . '</div></pre>';
200
  }
201
 
202
  public static function showLoadingTime() {
196
  }
197
 
198
 
199
+ echo '<style>#wpwrap{display: table;}</style><pre><div id="wpcontent">' . $debug . '</div></pre>';
200
  }
201
 
202
  public static function showLoadingTime() {
models/Post.php CHANGED
@@ -227,239 +227,4 @@ class SQ_Models_Post {
227
  return false;
228
  }
229
 
230
- /**
231
- * Save/Update Meta in database
232
- *
233
- * @param integer $post_id
234
- * @param array $metas [key,value]
235
- * @return array|boolean
236
- */
237
- public function savePostMeta($post_id, $metas = array()) {
238
- global $wpdb;
239
-
240
- if ((int)$post_id == 0 || empty($metas))
241
- return false;
242
-
243
- foreach ($metas as $meta) {
244
- $sql = "SELECT `meta_value`
245
- FROM `" . $wpdb->postmeta . "`
246
- WHERE `meta_key` = '" . $meta['key'] . "' AND `post_id`=" . (int)$post_id;
247
-
248
- if ($wpdb->get_row($sql)) {
249
- $sql = "UPDATE `" . $wpdb->postmeta . "`
250
- SET `meta_value` = '" . addslashes($meta['value']) . "'
251
- WHERE `meta_key` = '" . $meta['key'] . "' AND `post_id`=" . (int)$post_id;
252
- } else {
253
- $sql = "INSERT INTO `" . $wpdb->postmeta . "`
254
- (`post_id`,`meta_key`,`meta_value`)
255
- VALUES (" . (int)$post_id . ",'" . $meta['key'] . "','" . addslashes($meta['value']) . "')";
256
- }
257
- $wpdb->query($sql);
258
- }
259
-
260
- return $metas;
261
- }
262
-
263
- /**
264
- * check if there are keywords saved
265
- * @global object $wpdb
266
- * @return integer|false
267
- */
268
- public function countKeywords() {
269
- global $wpdb;
270
-
271
- if ($posts = $wpdb->get_row("SELECT count(`post_id`) as count
272
- FROM `" . $wpdb->postmeta . "`
273
- WHERE (`meta_key` = '_sq_post_keyword')")) {
274
-
275
- return $posts->count;
276
- }
277
-
278
- return false;
279
- }
280
-
281
- /**
282
- * check if there are keywords saved
283
- * @global object $wpdb
284
- * @return integer|false
285
- */
286
- public function getPostWithKeywords($filter = '', $ord = 'meta_id') {
287
- global $wpdb;
288
-
289
- if ($filter <> '') {
290
- $filter = ' AND (' . $filter . ') ';
291
- }
292
-
293
- if ($posts = $wpdb->get_results("SELECT `post_id`, `meta_value`
294
- FROM `" . $wpdb->postmeta . "`
295
- WHERE (`meta_key` = '_sq_post_keyword')"
296
- . $filter .
297
- 'ORDER BY `' . $ord . '`')) {
298
-
299
- $posts = array_map(array($this, 'jsonDecodeValue'), $posts);
300
-
301
- return $posts;
302
- }
303
-
304
- return false;
305
- }
306
-
307
- public function jsonDecodeValue($post) {
308
- $post->meta_value = json_decode($post->meta_value);
309
- return $post;
310
- }
311
-
312
- /**
313
- * get the keyword
314
- * @global object $wpdb
315
- * @param integer $post_id
316
- * @return boolean
317
- */
318
- public function getKeyword($post_id) {
319
- global $wpdb;
320
-
321
- if ($row = $wpdb->get_row("SELECT `post_id`, `meta_value`
322
- FROM `" . $wpdb->postmeta . "`
323
- WHERE (`meta_key` = '_sq_post_keyword' AND `post_id`=" . (int)$post_id . ")
324
- ORDER BY `meta_id` DESC")) {
325
-
326
- return json_decode($row->meta_value);
327
- }
328
-
329
- return false;
330
- }
331
-
332
- /**
333
- * Save the post keyword
334
- * @param integer $post_id
335
- * @param object $args
336
- */
337
- public function saveKeyword($post_id, $args) {
338
- $args->update = current_time('timestamp');
339
-
340
- $meta[] = array('key' => '_sq_post_keyword',
341
- 'value' => json_encode($args));
342
-
343
- $this->savePostMeta($post_id, $meta);
344
-
345
- return json_encode($args);
346
- }
347
-
348
- public function getKeywordsFromPost($id) {
349
- $post = get_post($id);
350
- return $this->_getKeywordsbyDensity($post);
351
- }
352
-
353
- /**
354
- * Get keyword by density from post
355
- *
356
- * @return array
357
- */
358
- private function _getKeywordsbyDensity($post) {
359
- $keywords = array();
360
- $content = '';
361
-
362
- if (function_exists('preg_replace')) {
363
- $content = strtolower(preg_replace('/[^a-zA-Z0-9-.]/', ' ', strip_tags($post->post_content)));
364
- } else {
365
- $content = strtolower(strip_tags($post->post_content));
366
- }
367
-
368
- $words = explode(" ", $content);
369
- $phrases = $this->searchPhrase($content);
370
-
371
- if ($post->post_title == '' || count((array)$words) < 5) {
372
- return false;
373
- }
374
-
375
- $common_words = "a,at,i,he,she,it,and,me,my,you,the,tags,hash,to,that,this,they,their";
376
- $common_words = strtolower($common_words);
377
- $common_words = explode(",", $common_words);
378
- // Get keywords
379
- $words_sum = 0;
380
- foreach ($words as $value) {
381
- $common = false;
382
- $value = $this->trimReplace($value);
383
- if (strlen($value) >= 3) {
384
- foreach ($common_words as $common_word) {
385
- if ($common_word == $value) {
386
- $common = true;
387
- }
388
- }
389
- if ($common != true) {
390
- if (!preg_match("/http/i", $value) && !preg_match("/mailto:/i", $value)) {
391
- $keywords[] = SQ_Classes_Tools::i18n($value);
392
- $words_sum++;
393
- }
394
- }
395
- }
396
- }
397
-
398
- $results = $results1 = $results2 = array();
399
- if (is_array($keywords) && !empty($keywords)) {
400
- // Do some maths and write array
401
- $keywords = array_count_values($keywords);
402
- arsort($keywords);
403
-
404
- foreach ($keywords as $key => $value) {
405
- $percent = 100 / $words_sum * $value;
406
- if ($percent > 1) {
407
- foreach ($phrases as $phrase => $count) {
408
- if (strpos($phrase, $key) !== false && !in_array($phrase, $results)) {
409
- if (strpos(strtolower($post->post_title), $phrase) !== false) {
410
- return $phrase;
411
- }
412
- }
413
- }
414
- }
415
- }
416
- }
417
- // Return array
418
- return false;
419
- }
420
-
421
- public function searchPhrase($text) {
422
- $words = explode(".", strtolower($text));
423
- //print_r($words);
424
- $frequencies = array();
425
- foreach ($words as $str) {
426
- $phrases = $this->twoWordPhrases($str);
427
-
428
- foreach ($phrases as $phrase) {
429
- $key = join(' ', $phrase);
430
- if (!isset($frequencies[$key])) {
431
- $frequencies[$key] = 0;
432
- }
433
- $frequencies[$key]++;
434
- }
435
- }
436
- arsort($frequencies);
437
- if (sizeof($frequencies) > 10) {
438
- $frequencies = array_slice($frequencies, 0, 10);
439
- }
440
- return $frequencies;
441
- }
442
-
443
- public function twoWordPhrases($str) {
444
- $words = preg_split('#\s+#', $str, -1, PREG_SPLIT_NO_EMPTY);
445
-
446
- $phrases = array();
447
- if (count((array)$words) > 2) {
448
- foreach (range(0, count((array)$words) - 2) as $offset) {
449
- $phrases[] = array_slice($words, $offset, 2);
450
- }
451
- }
452
- return $phrases;
453
- }
454
-
455
- /**
456
- * Get the newlines out
457
- *
458
- * @return string
459
- */
460
- private function trimReplace($string) {
461
- $string = trim($string);
462
- return (string)str_replace(array("\r", "\r\n", "\n"), '', $string);
463
- }
464
-
465
  }
227
  return false;
228
  }
229
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  }
models/abstract/Seo.php CHANGED
@@ -226,6 +226,10 @@ abstract class SQ_Models_Abstract_Seo {
226
  return SQ_Classes_ObjController::getClass('SQ_Models_Frontend')->isHomePage();
227
  }
228
 
 
 
 
 
229
  public function getPost() {
230
  return SQ_Classes_ObjController::getClass('SQ_Models_Frontend')->getPost();
231
  }
226
  return SQ_Classes_ObjController::getClass('SQ_Models_Frontend')->isHomePage();
227
  }
228
 
229
+ /**
230
+ * Get the current post from Frontend
231
+ * @return SQ_Models_Domain_Post
232
+ */
233
  public function getPost() {
234
  return SQ_Classes_ObjController::getClass('SQ_Models_Frontend')->getPost();
235
  }
models/bulkseo/Metas.php CHANGED
@@ -25,12 +25,6 @@ class SQ_Models_Bulkseo_Metas extends SQ_Models_Abstract_Assistant {
25
 
26
  $this->_keyword = $this->_post->sq->keywords;
27
 
28
- if (!$this->_keyword) {
29
- if (isset($this->_post->ID) && $json = SQ_Classes_ObjController::getClass('SQ_Models_Post')->getKeyword($this->_post->ID)) {
30
- $this->_keyword = $json->keyword;
31
- }
32
- }
33
-
34
  //Get all the patterns
35
  $this->_patterns = SQ_Classes_Helpers_Tools::getOption('patterns');
36
 
@@ -255,7 +249,7 @@ class SQ_Models_Bulkseo_Metas extends SQ_Models_Abstract_Assistant {
255
  $keywords = preg_split('/,/', $this->_keyword);
256
  if (!empty($keywords)) {
257
  foreach ($keywords as $keyword) {
258
- if ($keyword <> '' && (stripos($this->_post->sq->title, $keyword) !== false)) {
259
  $task['completed'] = true;
260
  return $task;
261
  }
@@ -368,7 +362,7 @@ class SQ_Models_Bulkseo_Metas extends SQ_Models_Abstract_Assistant {
368
  $keywords = preg_split('/,/', $this->_keyword);
369
  if (!empty($keywords)) {
370
  foreach ($keywords as $keyword) {
371
- if ($keyword <> '' && (stripos($this->_post->sq->description, $keyword) !== false)) {
372
  $task['completed'] = true;
373
  return $task;
374
  }
@@ -461,10 +455,14 @@ class SQ_Models_Bulkseo_Metas extends SQ_Models_Abstract_Assistant {
461
 
462
  private function _strWordCount($string) {
463
  if (!$count = str_word_count($string)) {
464
- @mb_internal_encoding('UTF-8');
465
- @mb_regex_encoding('UTF-8');
 
466
 
467
- $words = mb_split('[^\x{0600}-\x{06FF}]', $string);
 
 
 
468
 
469
  $count = count((array)$words);
470
  }
25
 
26
  $this->_keyword = $this->_post->sq->keywords;
27
 
 
 
 
 
 
 
28
  //Get all the patterns
29
  $this->_patterns = SQ_Classes_Helpers_Tools::getOption('patterns');
30
 
249
  $keywords = preg_split('/,/', $this->_keyword);
250
  if (!empty($keywords)) {
251
  foreach ($keywords as $keyword) {
252
+ if ($keyword <> '' && (SQ_Classes_Helpers_Tools::findStr($this->_post->sq->title, $keyword) !== false)) {
253
  $task['completed'] = true;
254
  return $task;
255
  }
362
  $keywords = preg_split('/,/', $this->_keyword);
363
  if (!empty($keywords)) {
364
  foreach ($keywords as $keyword) {
365
+ if ($keyword <> '' && (SQ_Classes_Helpers_Tools::findStr($this->_post->sq->description, $keyword) !== false)) {
366
  $task['completed'] = true;
367
  return $task;
368
  }
455
 
456
  private function _strWordCount($string) {
457
  if (!$count = str_word_count($string)) {
458
+ if (function_exists('mb_split')) {
459
+ @mb_internal_encoding('UTF-8');
460
+ @mb_regex_encoding('UTF-8');
461
 
462
+ $words = mb_split('[^\x{0600}-\x{06FF}]', $string);
463
+ } else {
464
+ return 1;
465
+ }
466
 
467
  $count = count((array)$words);
468
  }
models/domain/Patterns.php CHANGED
@@ -466,34 +466,21 @@ class SQ_Models_Domain_Patterns extends SQ_Models_Abstract_Domain {
466
  }
467
 
468
  protected $_caption; //Attachment caption
 
 
 
469
  protected $_keyword; //Replaced with the posts focus keyword
470
  protected $_focuskw; //Same as keyword
471
 
472
- public function getKeyword() {
473
- if (!isset($this->_keyword) || $this->_keyword == '') {
474
- if (isset($this->id) && (int)$this->id > 0) {
475
- if ($json = SQ_Classes_ObjController::getClass('SQ_Models_Post')->getKeyword($this->id)) {
476
- $this->_focuskw = $this->_keyword = SQ_Classes_Helpers_Sanitize::i18n($json->keyword);
477
- return $this->_keyword;
478
- }
479
- }
480
- $this->_keyword = '';
481
- }
482
 
 
483
  return $this->_keyword;
484
  }
485
 
486
  public function getFocuskw() {
487
- if (!isset($this->_focuskw) || $this->_focuskw == '') {
488
- if (isset($this->id) && (int)$this->id > 0) {
489
- if ($json = SQ_Classes_ObjController::getClass('SQ_Models_Post')->getKeyword($this->id)) {
490
- $this->_focuskw = $this->_keyword = SQ_Classes_Helpers_Sanitize::i18n($json->keyword);
491
- return $this->_focuskw;
492
- }
493
- }
494
- $this->_focuskw = '';
495
- }
496
-
497
  return $this->_focuskw;
498
  }
499
 
466
  }
467
 
468
  protected $_caption; //Attachment caption
469
+
470
+ //handle keywords
471
+ protected $_keywords;
472
  protected $_keyword; //Replaced with the posts focus keyword
473
  protected $_focuskw; //Same as keyword
474
 
475
+ public function setKeywords($value) {
476
+ $this->_focuskw = $this->_keyword =$value;
477
+ }
 
 
 
 
 
 
 
478
 
479
+ public function getKeyword() {
480
  return $this->_keyword;
481
  }
482
 
483
  public function getFocuskw() {
 
 
 
 
 
 
 
 
 
 
484
  return $this->_focuskw;
485
  }
486
 
models/focuspages/Image.php CHANGED
@@ -117,7 +117,7 @@ class SQ_Models_Focuspages_Image extends SQ_Models_Abstract_Assistant {
117
  } elseif (!empty($this->_images)) {
118
  foreach ($this->_images as $image) {
119
  $image = str_replace(array('_', '-', '/', '.'), ' ', $image);
120
- if (stripos($image, $this->_keyword) !== false) {
121
  $task['completed'] = true;
122
  }
123
  }
117
  } elseif (!empty($this->_images)) {
118
  foreach ($this->_images as $image) {
119
  $image = str_replace(array('_', '-', '/', '.'), ' ', $image);
120
+ if (SQ_Classes_Helpers_Tools::findStr($image, $this->_keyword) !== false) {
121
  $task['completed'] = true;
122
  }
123
  }
readme.txt CHANGED
@@ -295,6 +295,13 @@ Type a keyword to the right of the screen and start using Squirrly Seo. Enjoy!
295
  Squirrly SEO 9.1.00 it's a big update. We've re-designed the UX and added many new features. If you don't want to change the current experience you have with Squirrly you can remain on the current stable version of Squirrly SEO.
296
 
297
  == Changelog ==
 
 
 
 
 
 
 
298
  = 9.2.10 - 09/03/2019 =
299
  * Update - Squirrly Live Assistant for multiple languages
300
  * Update - my.squirrly.co to post on WordPress through a secure connection
@@ -304,7 +311,6 @@ Squirrly SEO 9.1.00 it's a big update. We've re-designed the UX and added many n
304
  * Fix - User Role Management when Admin has multiple roles
305
  * Fix - Sitemap terms exclude empty tags and categories
306
  * Fix - Sitemap taxonomi limit included to prevent timeouts
307
- * Fix - Fixed the Squirrly SEO Admin role
308
  * Fix - Fix small bugs
309
 
310
  = 9.2.01 - 08/20/2019 =
@@ -1182,6 +1188,9 @@ nofollow external links
1182
  nofollow links plugin
1183
  structured data plugin
1184
  google structured data
 
 
 
1185
 
1186
  * Changelog Archive: <a href="https://plugin.squirrly.co/squirrly-seo-changelog/">https://plugin.squirrly.co/squirrly-seo-changelog/</a>
1187
 
295
  Squirrly SEO 9.1.00 it's a big update. We've re-designed the UX and added many new features. If you don't want to change the current experience you have with Squirrly you can remain on the current stable version of Squirrly SEO.
296
 
297
  == Changelog ==
298
+ = 9.2.12 - 09/17/2019 =
299
+ * SEO Update - Tested and Compatible with WordPress 5.2.3
300
+ * SEO Update - Added Yandex SEO support for Yandex.com
301
+ * Fix - ranking assistant to set all green on average possitions
302
+ * Fix - Fixed the Squirrly SEO Admin role
303
+ * Fix - Fixed the Russian chars in Focus Pages, Bulk SEO and Squirrly SEO Snippet
304
+
305
  = 9.2.10 - 09/03/2019 =
306
  * Update - Squirrly Live Assistant for multiple languages
307
  * Update - my.squirrly.co to post on WordPress through a secure connection
311
  * Fix - User Role Management when Admin has multiple roles
312
  * Fix - Sitemap terms exclude empty tags and categories
313
  * Fix - Sitemap taxonomi limit included to prevent timeouts
 
314
  * Fix - Fix small bugs
315
 
316
  = 9.2.01 - 08/20/2019 =
1188
  nofollow links plugin
1189
  structured data plugin
1190
  google structured data
1191
+ yandex seo optimization
1192
+ yandex seo metas
1193
+ google seo metas
1194
 
1195
  * Changelog Archive: <a href="https://plugin.squirrly.co/squirrly-seo-changelog/">https://plugin.squirrly.co/squirrly-seo-changelog/</a>
1196
 
squirrly.php CHANGED
@@ -7,14 +7,14 @@
7
  Plugin URI: https://www.squirrly.co
8
  Description: SEO By Squirrly is for the NON-SEO experts. Get Excellent Seo with Better Content, Ranking and Analytics. For Both Humans and Search Bots.<BR> <a href="http://my.squirrly.co/user" target="_blank"><strong>Check your profile</strong></a>
9
  Author: Squirrly SEO
10
- Version: 9.2.10
11
  Author URI: https://www.squirrly.co
12
  */
13
  if (!defined('SQ_VERSION')) {
14
  /* SET THE CURRENT VERSION ABOVE AND BELOW */
15
  define('SQ_VERSION', '9.2.10');
16
  //The last stable version
17
- define('SQ_STABLE_VERSION', '9.2.00');
18
  // Call config files
19
  try {
20
  require_once(dirname(__FILE__) . '/config/config.php');
7
  Plugin URI: https://www.squirrly.co
8
  Description: SEO By Squirrly is for the NON-SEO experts. Get Excellent Seo with Better Content, Ranking and Analytics. For Both Humans and Search Bots.<BR> <a href="http://my.squirrly.co/user" target="_blank"><strong>Check your profile</strong></a>
9
  Author: Squirrly SEO
10
+ Version: 9.2.12
11
  Author URI: https://www.squirrly.co
12
  */
13
  if (!defined('SQ_VERSION')) {
14
  /* SET THE CURRENT VERSION ABOVE AND BELOW */
15
  define('SQ_VERSION', '9.2.10');
16
  //The last stable version
17
+ define('SQ_STABLE_VERSION', '9.2.10');
18
  // Call config files
19
  try {
20
  require_once(dirname(__FILE__) . '/config/config.php');
view/Blocks/SLASearch.php CHANGED
@@ -24,18 +24,14 @@
24
  </div>
25
  <div class="sq_keyword">
26
  <?php
27
- global $post;
28
- $sq_keyword = '';
29
- if (isset($post->ID) && $json = SQ_Classes_ObjController::getClass('SQ_Models_Post')->getKeyword($post->ID)) {
30
- $sq_keyword = SQ_Classes_Helpers_Sanitize::i18n($json->keyword);
31
- } elseif (SQ_Classes_Helpers_Tools::getOption('sq_keyword_help')) {
32
  ?>
33
  <div id="sq_keyword_help" style="display:none">
34
  <span></span><?php _e('Enter a keyword', _SQ_PLUGIN_NAME_); ?>
35
  <p><?php _e('for Squirrly Live SEO optimization', _SQ_PLUGIN_NAME_); ?></p></div><?php
36
  }
37
  ?>
38
- <input type="text" id="sq_keyword" name="sq_keyword" value="<?php echo $sq_keyword ?>" autocomplete="off" placeholder="<?php echo __('Type in your keyword...', _SQ_PLUGIN_NAME_) ?>"/>
39
  <input type="button" id="sq_keyword_check" value=">"/>
40
 
41
  <div id="sq_suggestion" style="display:none">
24
  </div>
25
  <div class="sq_keyword">
26
  <?php
27
+ if (SQ_Classes_Helpers_Tools::getOption('sq_keyword_help')) {
 
 
 
 
28
  ?>
29
  <div id="sq_keyword_help" style="display:none">
30
  <span></span><?php _e('Enter a keyword', _SQ_PLUGIN_NAME_); ?>
31
  <p><?php _e('for Squirrly Live SEO optimization', _SQ_PLUGIN_NAME_); ?></p></div><?php
32
  }
33
  ?>
34
+ <input type="text" id="sq_keyword" name="sq_keyword" value="" autocomplete="off" placeholder="<?php echo __('Type in your keyword...', _SQ_PLUGIN_NAME_) ?>"/>
35
  <input type="button" id="sq_keyword_check" value=">"/>
36
 
37
  <div id="sq_suggestion" style="display:none">