SEO SQUIRRLY™ - Version 9.2.18

Version Description

  • 02/12/2020 =
  • Updated Squirrly Live Assistant and Briefcase for Google 2020
  • Fixed the Json-LD for Woocommerce websites
  • Fixed Squirrly to load Google API only for Squirrly settings pages
Download this release

Release Info

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

Code changes from version 9.2.16 to 9.2.18

classes/ActionController.php CHANGED
@@ -42,9 +42,8 @@ class SQ_Classes_ActionController extends SQ_Classes_FrontController {
42
  * @return void
43
  */
44
  public function hookHead() {
45
- echo '<script type="text/javascript" src="https://www.google.com/jsapi"></script>
46
- <script>
47
- var sqQuery = {
48
  "adminurl": "' . admin_url() . '",
49
  "ajaxurl": "' . admin_url('admin-ajax.php') . '",
50
  "adminposturl": "' . admin_url('post.php') . '",
42
  * @return void
43
  */
44
  public function hookHead() {
45
+ echo '<script>
46
+ var sqQuery = {
 
47
  "adminurl": "' . admin_url() . '",
48
  "ajaxurl": "' . admin_url('admin-ajax.php') . '",
49
  "adminposturl": "' . admin_url('post.php') . '",
classes/RemoteController.php CHANGED
@@ -32,7 +32,7 @@ class SQ_Classes_RemoteController {
32
  $options = array_merge(
33
  array(
34
  'method' => self::$apimethod,
35
- 'sslverify' => (SQ_SSL ? true : false),
36
  'timeout' => 10,
37
  'headers' => array(
38
  'USER-TOKEN' => SQ_Classes_Helpers_Tools::getOption('sq_api'),
32
  $options = array_merge(
33
  array(
34
  'method' => self::$apimethod,
35
+ 'sslverify' => SQ_CHECK_SSL,
36
  'timeout' => 10,
37
  'headers' => array(
38
  'USER-TOKEN' => SQ_Classes_Helpers_Tools::getOption('sq_api'),
config/paths.php CHANGED
@@ -9,6 +9,7 @@ define('_SQ_DB_', 'QSS');
9
  define('_SQ_PLUGIN_NAME_', 'squirrly-seo'); //THIS LINE WILL BE CHANGED WITH THE USER SETTINGS
10
 
11
  defined('SQ_SSL') || define('SQ_SSL', (((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") || (defined('FORCE_SSL_ADMIN') && FORCE_SSL_ADMIN) || (function_exists('is_ssl') && is_ssl())) ? 'https:' : 'http:')); //CHECK SSL
 
12
  defined('SQ_URI') || define('SQ_URI', 'wp500');
13
  defined('_SQ_DASH_URL_') || define('_SQ_DASH_URL_', 'https://my.squirrly.co/');
14
  defined('_SQ_API_URL_') || define('_SQ_API_URL_', SQ_SSL . '//api.squirrly.co/sq/');
9
  define('_SQ_PLUGIN_NAME_', 'squirrly-seo'); //THIS LINE WILL BE CHANGED WITH THE USER SETTINGS
10
 
11
  defined('SQ_SSL') || define('SQ_SSL', (((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") || (defined('FORCE_SSL_ADMIN') && FORCE_SSL_ADMIN) || (function_exists('is_ssl') && is_ssl())) ? 'https:' : 'http:')); //CHECK SSL
12
+ defined('SQ_CHECK_SSL') || define('SQ_CHECK_SSL', SQ_SSL);
13
  defined('SQ_URI') || define('SQ_URI', 'wp500');
14
  defined('_SQ_DASH_URL_') || define('_SQ_DASH_URL_', 'https://my.squirrly.co/');
15
  defined('_SQ_API_URL_') || define('_SQ_API_URL_', SQ_SSL . '//api.squirrly.co/sq/');
controllers/Menu.php CHANGED
@@ -389,6 +389,7 @@ class SQ_Controllers_Menu extends SQ_Classes_FrontController {
389
  if (SQ_Classes_Helpers_Tools::getIsset('page')) {
390
  if (in_array(SQ_Classes_Helpers_Tools::getValue('page', ''), $this->sq_pages)) {
391
  $sq_fullscreen = true;
 
392
  echo '<div id="sq_preloader" class="sq_loading"></div>';
393
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('fullwidth', array('trigger' => true, 'media' => 'all'));
394
  } elseif (SQ_Classes_Helpers_Tools::getValue('page', '') == 'sq_dashboard') {
389
  if (SQ_Classes_Helpers_Tools::getIsset('page')) {
390
  if (in_array(SQ_Classes_Helpers_Tools::getValue('page', ''), $this->sq_pages)) {
391
  $sq_fullscreen = true;
392
+ echo '<script type="text/javascript" src="//www.google.com/jsapi"></script>';
393
  echo '<div id="sq_preloader" class="sq_loading"></div>';
394
  SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia('fullwidth', array('trigger' => true, 'media' => 'all'));
395
  } elseif (SQ_Classes_Helpers_Tools::getValue('page', '') == 'sq_dashboard') {
controllers/Post.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
 
3
  class SQ_Controllers_Post extends SQ_Classes_FrontController {
4
 
@@ -27,7 +28,7 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
27
  add_filter('wp_insert_post_data', array($this, 'checkSeo'), 11, 2);
28
  add_filter('wp_insert_post_data', array($this, 'removeHighlight'), 12, 2);
29
  add_filter('wp_insert_post_data', array($this, 'checkImage'), 13, 2);
30
- add_filter('save_post', array($this, 'sendSeo'), 11, 2);
31
 
32
  //Hook the Move To Trash action
33
  add_action('wp_trash_post', array(SQ_Classes_ObjController::getClass('SQ_Models_PostsList'), 'hookUpdateStatus'));
@@ -147,8 +148,13 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
147
  return $post_data;
148
  }
149
 
150
- public function sendSeo($postID, $post) {
151
- if (!isset($post->ID)) {
 
 
 
 
 
152
  return;
153
  }
154
 
@@ -157,41 +163,9 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
157
  get_post_status($post->ID) != 'auto-draft' &&
158
  get_post_status($post->ID) != 'inherit'
159
  ) {
160
-
161
- $args = array();
162
-
163
- $seo = SQ_Classes_Helpers_Tools::getValue('sq_seo', '');
164
-
165
- if (is_array($seo) && count((array)$seo) > 0)
166
- $args['seo'] = implode(',', $seo);
167
-
168
- $args['keyword'] = SQ_Classes_Helpers_Tools::getValue('sq_keyword', '');
169
-
170
- $args['status'] = $post->post_status;
171
- $args['permalink'] = get_permalink($post->ID);
172
- $args['author'] = $post->post_author;
173
- $args['post_id'] = $post->ID;
174
-
175
- if ($args['permalink']) {
176
- if (SQ_Classes_Helpers_Tools::getOption('sq_force_savepost')) {
177
- SQ_Classes_RemoteController::savePost($args);
178
- } else {
179
- $process = array();
180
- if (get_option('sq_seopost') !== false) {
181
- $process = json_decode(get_option('sq_seopost'), true);
182
- }
183
-
184
- $process[] = $args;
185
-
186
- //save for later send to api
187
- update_option('sq_seopost', json_encode($process));
188
- wp_schedule_single_event(time(), 'sq_cron_process_single');
189
-
190
- //If the queue is too big ... means that the cron is not working
191
- if (count((array)$process) > 5) SQ_Classes_Helpers_Tools::saveOptions('sq_force_savepost', 1);
192
- }
193
- }
194
  }
 
195
  }
196
 
197
  /**
@@ -214,6 +188,15 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
214
  //Save the snippet in case is edited in backend and not saved
215
  SQ_Classes_ObjController::getClass('SQ_Models_Snippet')->saveSEO();
216
 
 
 
 
 
 
 
 
 
 
217
  //check for custom SEO
218
  $this->_checkBriefcaseKeywords($postarr['ID']);
219
  }
@@ -221,6 +204,31 @@ class SQ_Controllers_Post extends SQ_Classes_FrontController {
221
  return $post_data;
222
  }
223
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  /**
225
  * Called when Post action is triggered
226
  *
1
  <?php
2
+ defined('ABSPATH') || die('Cheatin\' uh?');
3
 
4
  class SQ_Controllers_Post extends SQ_Classes_FrontController {
5
 
28
  add_filter('wp_insert_post_data', array($this, 'checkSeo'), 11, 2);
29
  add_filter('wp_insert_post_data', array($this, 'removeHighlight'), 12, 2);
30
  add_filter('wp_insert_post_data', array($this, 'checkImage'), 13, 2);
31
+ add_filter('save_post', array($this, 'savePost'), 11, 2);
32
 
33
  //Hook the Move To Trash action
34
  add_action('wp_trash_post', array(SQ_Classes_ObjController::getClass('SQ_Models_PostsList'), 'hookUpdateStatus'));
148
  return $post_data;
149
  }
150
 
151
+ /**
152
+ * Hook the posts save
153
+ * @param $postID
154
+ * @param $post
155
+ */
156
+ public function savePost($postID, $post) {
157
+ if ($postID && !isset($post->ID)) {
158
  return;
159
  }
160
 
163
  get_post_status($post->ID) != 'auto-draft' &&
164
  get_post_status($post->ID) != 'inherit'
165
  ) {
166
+ $this->sendSeo($post);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  }
168
+
169
  }
170
 
171
  /**
188
  //Save the snippet in case is edited in backend and not saved
189
  SQ_Classes_ObjController::getClass('SQ_Models_Snippet')->saveSEO();
190
 
191
+ if ($post_data['post_type'] == 'attachment') {
192
+
193
+ global $post;
194
+
195
+ if(isset($post->ID)) {
196
+ $this->sendSeo($post);
197
+ }
198
+
199
+ }
200
  //check for custom SEO
201
  $this->_checkBriefcaseKeywords($postarr['ID']);
202
  }
204
  return $post_data;
205
  }
206
 
207
+ /**
208
+ * Send the Post to Squirrly API
209
+ * @param $post
210
+ */
211
+ public function sendSeo($post) {
212
+ $args = array();
213
+
214
+ $seo = SQ_Classes_Helpers_Tools::getValue('sq_seo', '');
215
+
216
+ if (is_array($seo) && count((array)$seo) > 0)
217
+ $args['seo'] = implode(',', $seo);
218
+
219
+ $args['keyword'] = SQ_Classes_Helpers_Tools::getValue('sq_keyword', '');
220
+
221
+ $args['status'] = $post->post_status;
222
+ $args['permalink'] = get_permalink($post->ID);
223
+ $args['author'] = $post->post_author;
224
+ $args['post_id'] = $post->ID;
225
+
226
+ if ($args['permalink']) {
227
+ SQ_Classes_RemoteController::savePost($args);
228
+ }
229
+
230
+ }
231
+
232
  /**
233
  * Called when Post action is triggered
234
  *
controllers/PostsList.php CHANGED
@@ -104,7 +104,6 @@ class SQ_Controllers_PostsList extends SQ_Classes_FrontController {
104
  }
105
  }
106
 
107
-
108
  /**
109
  * Add the Squirrly column in the Post List
110
  *
104
  }
105
  }
106
 
 
107
  /**
108
  * Add the Squirrly column in the Post List
109
  *
models/FocusPages.php CHANGED
@@ -97,17 +97,7 @@ class SQ_Models_FocusPages {
97
 
98
  $audit = $this->_focuspage->getAudit();
99
 
100
- //Set the focus page audit as success
101
- $this->_focuspage->audit_error = false;
102
- if (isset($audit->properties) && isset($audit->properties->created_at->date)) {
103
- $this->_focuspage->audit_datetime = date(get_option('date_format') . ' ' . get_option('time_format'), strtotime($audit->properties->created_at->date));
104
- //Set the audit as error in case it was a process error
105
- if(!$audit->properties->successCrawl){
106
- $this->_focuspage->audit_error = true;
107
- }
108
- } else {
109
- $this->_focuspage->audit_datetime = __('Audit in progress', _SQ_PLUGIN_NAME_);
110
- }
111
 
112
  if(!isset($audit->properties) || !isset($audit->data->sq_seo_keywords->value) || $audit->data->sq_seo_keywords->value == ''){
113
  $this->_focuspage->visibility = 'N/A';
97
 
98
  $audit = $this->_focuspage->getAudit();
99
 
100
+
 
 
 
 
 
 
 
 
 
 
101
 
102
  if(!isset($audit->properties) || !isset($audit->data->sq_seo_keywords->value) || $audit->data->sq_seo_keywords->value == ''){
103
  $this->_focuspage->visibility = 'N/A';
models/Frontend.php CHANGED
@@ -366,14 +366,13 @@ class SQ_Models_Frontend {
366
  return $post;
367
  }
368
 
369
- if ($post->post_type == 'post' || $post->post_type == 'page' || $post->post_type == 'product') {
370
  $post->debug = 'post/page/product:' . $post->ID;
371
  $post->hash = md5($post->ID);
372
  $post->url = get_permalink($post->ID);
373
  return $post;
374
  }
375
 
376
-
377
  if ($post->post_type == 'attachment') {
378
  $post->debug = 'attachment:' . $post->ID;
379
  $post->hash = md5($post->ID);
366
  return $post;
367
  }
368
 
369
+ if (in_array($post->post_type, array('post', 'page', 'product', 'cartflows_step'))) {
370
  $post->debug = 'post/page/product:' . $post->ID;
371
  $post->hash = md5($post->ID);
372
  $post->url = get_permalink($post->ID);
373
  return $post;
374
  }
375
 
 
376
  if ($post->post_type == 'attachment') {
377
  $post->debug = 'attachment:' . $post->ID;
378
  $post->hash = md5($post->ID);
models/ImportExport.php CHANGED
@@ -115,6 +115,18 @@ class SQ_Models_ImportExport {
115
  'noindex' => '_su_meta_robots_noindex',
116
  'nofollow' => '_su_meta_robots_nofollow',
117
  ),
 
 
 
 
 
 
 
 
 
 
 
 
118
  'wordpress-seo' => array(
119
  'title' => '_yoast_wpseo_title',
120
  'description' => '_yoast_wpseo_metadesc',
@@ -280,6 +292,24 @@ class SQ_Models_ImportExport {
280
  }
281
  }
282
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  if ($platform == 'squirrly-seo') {
284
  if ($options = json_decode(get_option('sq_options'), true)) {
285
  $socials = SQ_Classes_Helpers_Tools::getOption('socials');
@@ -371,7 +401,7 @@ class SQ_Models_ImportExport {
371
  if ($encoding = mb_detect_encoding($value)) {
372
  if ($encoding <> 'UTF-8') {
373
  $value = iconv($encoding, 'UTF-8', $value);
374
- if(strpos($value,'%%') !== false) {
375
  $value = preg_replace('/%%([^\%]+)%%/', '{{$1}}', $value);
376
  }
377
  }
@@ -453,7 +483,7 @@ class SQ_Models_ImportExport {
453
  }
454
 
455
  foreach ($values as &$value) {
456
- if(strpos($value,'%%') !== false) {
457
  $value = preg_replace('/%%([^\%]+)%%/', '{{$1}}', $value);
458
  }
459
  }
115
  'noindex' => '_su_meta_robots_noindex',
116
  'nofollow' => '_su_meta_robots_nofollow',
117
  ),
118
+ 'rank-math' => array(
119
+ 'title' => 'rank_math_title',
120
+ 'description' => 'rank_math_description',
121
+ 'keywords' => 'rank_math_focus_keyword',
122
+ 'canonical' => 'rank_math_canonical_url',
123
+ 'og_title' => 'rank_math_facebook_title',
124
+ 'og_description' => 'rank_math_facebook_description',
125
+ 'og_media' => 'rank_math_facebook_image',
126
+ 'tw_title' => 'rank_math_twitter_title',
127
+ 'tw_description' => 'rank_math_twitter_description',
128
+ 'tw_media' => 'rank_math_twitter_image',
129
+ ),
130
  'wordpress-seo' => array(
131
  'title' => '_yoast_wpseo_title',
132
  'description' => '_yoast_wpseo_metadesc',
292
  }
293
  }
294
 
295
+ if ($platform == 'rank-math') {
296
+ if ($options = get_option('rank-math-options-general')) {
297
+ $codes = SQ_Classes_Helpers_Tools::getOption('codes');
298
+
299
+ if (isset($options['attachment_redirect_urls'])) {
300
+ SQ_Classes_Helpers_Tools::saveOptions('sq_attachment_redirect', ($options['attachment_redirect_urls'] == 'on'));
301
+ }
302
+
303
+ if (isset($options['google_verify']) && $options['google_verify'] <> '') $codes['google_wt'] = $options['google_verify'];
304
+ if (isset($options['bing_verify']) && $options['bing_verify'] <> '') $codes['bing_wt'] = $options['bing_verify'];
305
+ if (isset($options['pinterest_verify']) && $options['pinterest_verify'] <> '') $codes['pinterest_verify'] = $options['pinterest_verify'];
306
+
307
+ SQ_Classes_Helpers_Tools::saveOptions('codes', $codes);
308
+
309
+ $imported = true;
310
+ }
311
+ }
312
+
313
  if ($platform == 'squirrly-seo') {
314
  if ($options = json_decode(get_option('sq_options'), true)) {
315
  $socials = SQ_Classes_Helpers_Tools::getOption('socials');
401
  if ($encoding = mb_detect_encoding($value)) {
402
  if ($encoding <> 'UTF-8') {
403
  $value = iconv($encoding, 'UTF-8', $value);
404
+ if (strpos($value, '%%') !== false) {
405
  $value = preg_replace('/%%([^\%]+)%%/', '{{$1}}', $value);
406
  }
407
  }
483
  }
484
 
485
  foreach ($values as &$value) {
486
+ if (strpos($value, '%%') !== false) {
487
  $value = preg_replace('/%%([^\%]+)%%/', '{{$1}}', $value);
488
  }
489
  }
models/abstract/Seo.php CHANGED
@@ -99,11 +99,11 @@ abstract class SQ_Models_Abstract_Seo {
99
  if (wp_attachment_is_image($this->_post->ID)) {
100
  $attachment = get_post($this->_post->ID);
101
  $this->_post->post_title = ((isset($attachment->post_title) && strlen($attachment->post_title) > 10) ? $attachment->post_title : '');
102
- $this->_post->post_excerpt = (isset($attachment->post_excerpt) ? $attachment->post_excerpt : isset($attachment->post_content) ? $attachment->post_content : '');
103
  } elseif (has_post_thumbnail($this->_post->ID)) {
104
  $attachment = get_post(get_post_thumbnail_id($this->_post->ID));
105
  $this->_post->post_title = ((isset($attachment->post_title) && strlen($attachment->post_title) > 10) ? $attachment->post_title : '');
106
- $this->_post->post_excerpt = (isset($attachment->post_excerpt) ? $attachment->post_excerpt : isset($attachment->post_content) ? $attachment->post_content : '');
107
  }
108
 
109
  if (isset($attachment->ID)) {
99
  if (wp_attachment_is_image($this->_post->ID)) {
100
  $attachment = get_post($this->_post->ID);
101
  $this->_post->post_title = ((isset($attachment->post_title) && strlen($attachment->post_title) > 10) ? $attachment->post_title : '');
102
+ $this->_post->post_excerpt = ((isset($attachment->post_excerpt) ? $attachment->post_excerpt : isset($attachment->post_content)) ? $attachment->post_content : '');
103
  } elseif (has_post_thumbnail($this->_post->ID)) {
104
  $attachment = get_post(get_post_thumbnail_id($this->_post->ID));
105
  $this->_post->post_title = ((isset($attachment->post_title) && strlen($attachment->post_title) > 10) ? $attachment->post_title : '');
106
+ $this->_post->post_excerpt = ((isset($attachment->post_excerpt) ? $attachment->post_excerpt : isset($attachment->post_content)) ? $attachment->post_content : '');
107
  }
108
 
109
  if (isset($attachment->ID)) {
models/focuspages/Image.php CHANGED
@@ -115,10 +115,20 @@ class SQ_Models_Focuspages_Image extends SQ_Models_Abstract_Assistant {
115
  $task['error_message'] = __("No image found", _SQ_PLUGIN_NAME_);
116
  $task['completed'] = false;
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
  }
124
  }
115
  $task['error_message'] = __("No image found", _SQ_PLUGIN_NAME_);
116
  $task['completed'] = false;
117
  } elseif (!empty($this->_images)) {
118
+ $words = explode(' ', $this->_keyword);
119
  foreach ($this->_images as $image) {
120
+ //Check if all words are present in the image URL
121
+ $allwords = true;
122
+ foreach ($words as $word) {
123
+ if (SQ_Classes_Helpers_Tools::findStr($image, $word) === false) {
124
+ $allwords = false;
125
+ }
126
+ }
127
+
128
+ //Complete task if all words are found
129
+ if ($allwords) {
130
  $task['completed'] = true;
131
+ break;
132
  }
133
  }
134
  }
models/focuspages/Indexability.php CHANGED
@@ -35,6 +35,11 @@ class SQ_Models_Focuspages_Indexability extends SQ_Models_Abstract_Assistant {
35
  $this->_canonical = $this->_audit->data->sq_seo_meta->canonical;
36
  }
37
 
 
 
 
 
 
38
  //get the local permalink
39
  $this->_permalink = (isset($this->_post->url) && $this->_post->url <> '' ? $this->_post->url : $this->_audit->permalink);
40
  }
35
  $this->_canonical = $this->_audit->data->sq_seo_meta->canonical;
36
  }
37
 
38
+ if (isset($this->_audit->data->serp_checker->position) && $this->_audit->data->serp_checker->position) {
39
+ $this->_dbtasks[$this->_category]['gscindex'][$this->_post->ID] = true;
40
+ $this->saveDBTasks();
41
+ }
42
+
43
  //get the local permalink
44
  $this->_permalink = (isset($this->_post->url) && $this->_post->url <> '' ? $this->_post->url : $this->_audit->permalink);
45
  }
models/focuspages/Innerlinks.php CHANGED
@@ -5,7 +5,6 @@ class SQ_Models_Focuspages_Innerlinks extends SQ_Models_Abstract_Assistant {
5
  protected $_category = 'innerlinks';
6
  public $_permalink = false;
7
  public $_inner_links = false;
8
- public $_total_posts = false;
9
 
10
  const INNERS_MINVAL = 5;
11
  const INNERS_RECOMMENDED = 20;
@@ -21,23 +20,26 @@ class SQ_Models_Focuspages_Innerlinks extends SQ_Models_Abstract_Assistant {
21
 
22
  $this->_permalink = (isset($this->_post->url) && $this->_post->url <> '' ? $this->_post->url : $this->_audit->permalink);
23
  $path = parse_url($this->_permalink, PHP_URL_PATH);
24
- if($path == '') $path = $this->_permalink;
25
 
26
  if ($this->_permalink <> '') {
27
  global $wpdb;
28
 
29
- if ($row = $wpdb->get_row("SELECT COUNT(`ID`) as count FROM " . $wpdb->posts . " WHERE `post_status` = 'publish'")) {
30
- $this->_total_posts = $row->count;
31
- }
32
- if ($row = $wpdb->get_row("SELECT COUNT(`ID`) as count FROM " . $wpdb->posts . " WHERE `post_content` LIKE '%" . $path . "%' AND `post_status` = 'publish'")) {
33
- $this->_inner_links = $row->count;
34
- }
35
 
36
- if (isset($this->_audit->data->sq_seo_innerlinks->value)) {
37
- $this->_inner_links = max((int)$this->_inner_links, (int)$this->_audit->data->sq_seo_innerlinks->value);
 
 
 
 
 
 
 
38
  }
39
 
40
- SQ_Debug::dump($this->_inner_links, $this->_total_posts);
41
  }
42
 
43
  }
@@ -45,12 +47,12 @@ class SQ_Models_Focuspages_Innerlinks extends SQ_Models_Abstract_Assistant {
45
  public function setTasks($tasks) {
46
  parent::setTasks($tasks);
47
  $path = parse_url($this->_permalink, PHP_URL_PATH);
48
- if($path == '') $path = $this->_permalink;
49
 
50
  $this->_tasks[$this->_category] = array(
51
  'innerlinks' => array(
52
  'title' => sprintf(__("Get %s inner links", _SQ_PLUGIN_NAME_), self::INNERS_MINVAL),
53
- 'value' => (int)$this->_inner_links . ' ' . __('inner links', _SQ_PLUGIN_NAME_) . ' ' .__('to', _SQ_PLUGIN_NAME_) . ': ' . $path,
54
  'penalty' => 5,
55
  'description' => sprintf(__("Get %s Inner Links %s Recommended is: %s %s Inner Links are links that you send from one URL of your site to another URL of your site. %s Since your Focus Pages are the most important pages in your site, you should make sure that you link to them from many pages of your website. %s Note! We check the links present in the content of each post of your website.", _SQ_PLUGIN_NAME_), self::INNERS_MINVAL, '<br /><br />', self::INNERS_RECOMMENDED, '<br /><br />', '<br /><br />', '<br /><br />'),
56
  ),
@@ -82,7 +84,7 @@ class SQ_Models_Focuspages_Innerlinks extends SQ_Models_Abstract_Assistant {
82
  * @return bool|WP_Error
83
  */
84
  public function checkInnerlinks($task) {
85
- if($this->_permalink <> '') {
86
  $task['completed'] = ((int)$this->_inner_links && (int)$this->_inner_links >= self::INNERS_MINVAL);
87
  return $task;
88
  }
5
  protected $_category = 'innerlinks';
6
  public $_permalink = false;
7
  public $_inner_links = false;
 
8
 
9
  const INNERS_MINVAL = 5;
10
  const INNERS_RECOMMENDED = 20;
20
 
21
  $this->_permalink = (isset($this->_post->url) && $this->_post->url <> '' ? $this->_post->url : $this->_audit->permalink);
22
  $path = parse_url($this->_permalink, PHP_URL_PATH);
23
+ if ($path == '') $path = $this->_permalink;
24
 
25
  if ($this->_permalink <> '') {
26
  global $wpdb;
27
 
28
+ if ($this->_audit->data->sq_seo_innerlinks) {
29
+
30
+ if (!isset($this->_audit->data->sq_seo_innerlinks->inner_links)) {
 
 
 
31
 
32
+ if ($row = $wpdb->get_row("SELECT COUNT(`ID`) as count FROM " . $wpdb->posts . " WHERE `post_content` LIKE '%" . $path . "%' AND `post_status` = 'publish'")) {
33
+ $this->_inner_links = $row->count;
34
+ }
35
+
36
+ } else{
37
+ $this->_inner_links = (int)$this->_audit->data->sq_seo_innerlinks->inner_links;
38
+ }
39
+ } else {
40
+ $this->_error = true;
41
  }
42
 
 
43
  }
44
 
45
  }
47
  public function setTasks($tasks) {
48
  parent::setTasks($tasks);
49
  $path = parse_url($this->_permalink, PHP_URL_PATH);
50
+ if ($path == '') $path = $this->_permalink;
51
 
52
  $this->_tasks[$this->_category] = array(
53
  'innerlinks' => array(
54
  'title' => sprintf(__("Get %s inner links", _SQ_PLUGIN_NAME_), self::INNERS_MINVAL),
55
+ 'value' => (int)$this->_inner_links . ' ' . __('inner links', _SQ_PLUGIN_NAME_) . ' ' . __('to', _SQ_PLUGIN_NAME_) . ': ' . $path,
56
  'penalty' => 5,
57
  'description' => sprintf(__("Get %s Inner Links %s Recommended is: %s %s Inner Links are links that you send from one URL of your site to another URL of your site. %s Since your Focus Pages are the most important pages in your site, you should make sure that you link to them from many pages of your website. %s Note! We check the links present in the content of each post of your website.", _SQ_PLUGIN_NAME_), self::INNERS_MINVAL, '<br /><br />', self::INNERS_RECOMMENDED, '<br /><br />', '<br /><br />', '<br /><br />'),
58
  ),
84
  * @return bool|WP_Error
85
  */
86
  public function checkInnerlinks($task) {
87
+ if ($this->_permalink <> '') {
88
  $task['completed'] = ((int)$this->_inner_links && (int)$this->_inner_links >= self::INNERS_MINVAL);
89
  return $task;
90
  }
models/focuspages/Keyword.php CHANGED
@@ -30,7 +30,7 @@ class SQ_Models_Focuspages_Keyword extends SQ_Models_Abstract_Assistant {
30
  $this->_keyword = $this->_audit->data->sq_seo_keywords->value;
31
  }
32
 
33
- if (isset($this->_audit->data->sq_seo_keywords->research)) {
34
  $this->_competition = $this->_audit->data->sq_seo_keywords->research->sc;
35
  $this->_trend = $this->_audit->data->sq_seo_keywords->research->td;
36
  $this->_volume = $this->_audit->data->sq_seo_keywords->research->sv;
30
  $this->_keyword = $this->_audit->data->sq_seo_keywords->value;
31
  }
32
 
33
+ if (isset($this->_audit->data->sq_seo_keywords->research->sc)) {
34
  $this->_competition = $this->_audit->data->sq_seo_keywords->research->sc;
35
  $this->_trend = $this->_audit->data->sq_seo_keywords->research->td;
36
  $this->_volume = $this->_audit->data->sq_seo_keywords->research->sv;
models/focuspages/Traffic.php CHANGED
@@ -30,12 +30,21 @@ class SQ_Models_Focuspages_Traffic extends SQ_Models_Abstract_Assistant {
30
  }
31
  if (isset($this->_audit->data->sq_analytics_google->page_views)) {
32
  $this->_page_views = $this->_audit->data->sq_analytics_google->page_views;
 
 
 
33
  }
34
  if (isset($this->_audit->data->sq_analytics_google->page_sessions)) {
35
  $this->_page_sessions = $this->_audit->data->sq_analytics_google->page_sessions;
 
 
 
36
  }
37
  if (isset($this->_audit->data->sq_analytics_google->page_newvisits)) {
38
  $this->_page_newvisits = $this->_audit->data->sq_analytics_google->page_newvisits;
 
 
 
39
  }
40
  if (isset($this->_audit->data->sq_analytics_google->page_time)) {
41
  $this->_page_time = $this->_audit->data->sq_analytics_google->page_time;
@@ -59,13 +68,13 @@ class SQ_Models_Focuspages_Traffic extends SQ_Models_Abstract_Assistant {
59
  ),
60
  'avgtime' => array(
61
  'title' => sprintf(__("Time on page is %s minutes", _SQ_PLUGIN_NAME_), self::AVGTIME_MINVAL),
62
- 'value' => ($this->_page_time > 0 ? $this->_page_time : 0) . ' ' . __('minutes', _SQ_PLUGIN_NAME_),
63
  'penalty' => 10,
64
  'description' => sprintf(__('Make sure that visitors spend on average at least %s minutes on your site. %s Get an average time on page of minimum %s minutes for this focus page. You can do this by editing the content and making it more appealing to visitors. %s In the Best Practices section you\'ll find a plugin for WordPress that will help your Google Analytics tracker to track the real time on page for people. Sometimes, Google Analytics tracks this lower than it should. %s If your visitors don\'t spend at 2 minutes on your Focus Page, it can mean that the page is not important enough for them, or that the content from the page is boring, or hard to read, or the page just loads too slow.', _SQ_PLUGIN_NAME_), self::AVGTIME_MINVAL, self::AVGTIME_MINVAL, '<br /><br />', '<br /><br />', '<br /><br />'),
65
  ),
66
  'visits' => array(
67
  'title' => sprintf(__("%s visitors / day / page", _SQ_PLUGIN_NAME_), self::VISITS_MINVAL),
68
- 'value' => $this->_page_sessions . ' ' . __('unique views', _SQ_PLUGIN_NAME_),
69
  'description' => sprintf(__("For this task, we're looking at unique page views from your Google Analytics. %s If you don't get %s visitors / day / page, then this Focus Page is not yet popular enough on your site. %s You should make sure that more people end up visiting it.", _SQ_PLUGIN_NAME_), '<br /><br />', self::VISITS_MINVAL, '<br /><br />'),
70
  ),
71
  'gacode' => array(
30
  }
31
  if (isset($this->_audit->data->sq_analytics_google->page_views)) {
32
  $this->_page_views = $this->_audit->data->sq_analytics_google->page_views;
33
+ if($this->_page_views > 0){
34
+ $this->_page_views = ceil(($this->_page_views / 7));
35
+ }
36
  }
37
  if (isset($this->_audit->data->sq_analytics_google->page_sessions)) {
38
  $this->_page_sessions = $this->_audit->data->sq_analytics_google->page_sessions;
39
+ if($this->_page_sessions > 0){
40
+ $this->_page_sessions = ceil(($this->_page_sessions / 7));
41
+ }
42
  }
43
  if (isset($this->_audit->data->sq_analytics_google->page_newvisits)) {
44
  $this->_page_newvisits = $this->_audit->data->sq_analytics_google->page_newvisits;
45
+ if($this->_page_newvisits > 0){
46
+ $this->_page_newvisits = ceil(($this->_page_newvisits / 7));
47
+ }
48
  }
49
  if (isset($this->_audit->data->sq_analytics_google->page_time)) {
50
  $this->_page_time = $this->_audit->data->sq_analytics_google->page_time;
68
  ),
69
  'avgtime' => array(
70
  'title' => sprintf(__("Time on page is %s minutes", _SQ_PLUGIN_NAME_), self::AVGTIME_MINVAL),
71
+ 'value' => ($this->_page_time > 0 ? $this->_page_time : 0) . ' ' . __('minutes avg.', _SQ_PLUGIN_NAME_),
72
  'penalty' => 10,
73
  'description' => sprintf(__('Make sure that visitors spend on average at least %s minutes on your site. %s Get an average time on page of minimum %s minutes for this focus page. You can do this by editing the content and making it more appealing to visitors. %s In the Best Practices section you\'ll find a plugin for WordPress that will help your Google Analytics tracker to track the real time on page for people. Sometimes, Google Analytics tracks this lower than it should. %s If your visitors don\'t spend at 2 minutes on your Focus Page, it can mean that the page is not important enough for them, or that the content from the page is boring, or hard to read, or the page just loads too slow.', _SQ_PLUGIN_NAME_), self::AVGTIME_MINVAL, self::AVGTIME_MINVAL, '<br /><br />', '<br /><br />', '<br /><br />'),
74
  ),
75
  'visits' => array(
76
  'title' => sprintf(__("%s visitors / day / page", _SQ_PLUGIN_NAME_), self::VISITS_MINVAL),
77
+ 'value' => $this->_page_sessions . ' ' . __('unique views avg.', _SQ_PLUGIN_NAME_),
78
  'description' => sprintf(__("For this task, we're looking at unique page views from your Google Analytics. %s If you don't get %s visitors / day / page, then this Focus Page is not yet popular enough on your site. %s You should make sure that more people end up visiting it.", _SQ_PLUGIN_NAME_), '<br /><br />', self::VISITS_MINVAL, '<br /><br />'),
79
  ),
80
  'gacode' => array(
models/services/JsonLD.php CHANGED
@@ -19,7 +19,6 @@ class SQ_Models_Services_JsonLD extends SQ_Models_Abstract_Seo {
19
  if ($this->_post->post_type == 'product') {
20
  add_filter('sq_json_ld', array($this, 'generate_product_data'), 8);
21
  add_filter('sq_json_ld', array($this, 'generate_order_data'), 8);
22
- add_filter('sq_json_ld', array($this, 'generate_review_data'), 8);
23
  }
24
  }
25
 
@@ -291,39 +290,13 @@ class SQ_Models_Services_JsonLD extends SQ_Models_Abstract_Seo {
291
  "url" => $user_url,
292
  "name" => $display_name,
293
  );
294
- }
295
-
296
- if ($jsonld_type == 'Organization' && isset($jsonld[$jsonld_type])) {
297
  $markup['publisher'] = array(
298
- "@type" => $jsonld_type,
299
- "url" => $this->_post->url,
300
  "name" => $this->getAuthor('display_name'),
301
  );
302
 
303
- foreach ($jsonld[$jsonld_type] as $key => $value) {
304
- if ($value <> '') {
305
- if ($key == 'contactType' || $key == 'telephone' || $key == 'jobTitle') {
306
- continue;
307
- }
308
-
309
- if ($key == 'logo') {
310
- $markup['publisher']['logo'] = array(
311
- "@type" => "ImageObject",
312
- "url" => $value
313
- );
314
-
315
- } else {
316
- $markup['publisher'][$key] = $value;
317
- }
318
- }
319
- }
320
- } elseif ($jsonld_type == 'Person' && isset($jsonld[$jsonld_type])) {
321
- $markup['publisher'] = array(
322
- "@type" => $jsonld_type,
323
- "name" => $this->getAuthor('display_name'),
324
- );
325
-
326
- foreach ($jsonld[$jsonld_type] as $key => $value) {
327
  if ($value <> '') {
328
 
329
  if ($key == 'logo') {
@@ -339,70 +312,14 @@ class SQ_Models_Services_JsonLD extends SQ_Models_Abstract_Seo {
339
  }
340
  }
341
 
342
- if ($this->_post->sq->keywords <> '') {
343
- $markup['keywords'] = $this->_post->sq->keywords;
344
- }
345
- //add current markup
346
- $this->set_data($markup);
347
- } elseif ($this->_post->post_type == 'post' || $this->_post->sq->og_type == 'article') {
348
- $markup['@type'] = 'Article';
349
- $markup['@id'] = $this->_post->url . '#' . 'Article';
350
- $markup['url'] = $this->_post->url;
351
-
352
- if (isset($this->_post->sq->title)) {
353
- $markup['name'] = $this->truncate($this->_post->sq->title, 0, $this->_post->sq->jsonld_title_maxlength);
354
- $markup['name'] = str_replace('"', '\"', $markup['name']);
355
- }
356
-
357
- if (isset($this->_post->sq->description)) {
358
- $markup['headline'] = $this->truncate($this->_post->sq->description, 0, $this->_post->sq->jsonld_description_maxlength);
359
- $markup['headline'] = str_replace('&#034;', '"', $markup['headline']);
360
- }
361
- $markup['mainEntityOfPage'] = array(
362
- '@type' => 'WebPage',
363
- 'url' => $this->_post->url
364
- );
365
-
366
- if ($this->_post->sq->og_media <> '') {
367
- $markup['thumbnailUrl'] = $this->_post->sq->og_media;
368
- }
369
- if (isset($this->_post->post_date)) {
370
- $markup['datePublished'] = date('c', strtotime($this->_post->post_date));
371
- }
372
- if (isset($this->_post->post_modified)) {
373
- $markup['dateModified'] = date('c', strtotime($this->_post->post_modified));
374
- }
375
-
376
- if ($this->_post->sq->og_media <> '') {
377
- $markup['image'] = array(
378
- "@type" => "ImageObject",
379
- "url" => $this->_post->sq->og_media,
380
- "height" => 500,
381
- "width" => 700,
382
- );
383
- } else {
384
- $this->_setMedia($markup);
385
- }
386
-
387
- $user_url = $this->getAuthor('user_url');
388
- $display_name = $this->getAuthor('display_name');
389
-
390
- if ($user_url <> '' && $display_name <> '') {
391
- $markup['author'] = array(
392
- "@type" => "Person",
393
- "url" => $user_url,
394
- "name" => $display_name,
395
- );
396
- }
397
-
398
- if ($jsonld_type == 'Organization' && isset($jsonld[$jsonld_type])) {
399
  $markup['publisher'] = array(
400
- "@type" => $jsonld_type,
401
  "url" => $this->_post->url,
402
  "name" => $this->getAuthor('display_name'),
403
  );
404
 
405
- foreach ($jsonld[$jsonld_type] as $key => $value) {
406
  if ($value <> '') {
407
  if ($key == 'contactType' || $key == 'telephone' || $key == 'jobTitle') {
408
  continue;
@@ -414,26 +331,6 @@ class SQ_Models_Services_JsonLD extends SQ_Models_Abstract_Seo {
414
  "url" => $value
415
  );
416
 
417
- } else {
418
- $markup['publisher'][$key] = $value;
419
- }
420
- }
421
- }
422
- } elseif ($jsonld_type == 'Person' && isset($jsonld[$jsonld_type])) {
423
- $markup['publisher'] = array(
424
- "@type" => $jsonld_type,
425
- "name" => $this->getAuthor('display_name'),
426
- );
427
-
428
- foreach ($jsonld[$jsonld_type] as $key => $value) {
429
- if ($value <> '') {
430
-
431
- if ($key == 'logo') {
432
- $markup['publisher']['image'] = array(
433
- "@type" => "ImageObject",
434
- "url" => $value
435
- );
436
-
437
  } else {
438
  $markup['publisher'][$key] = $value;
439
  }
@@ -683,28 +580,47 @@ class SQ_Models_Services_JsonLD extends SQ_Models_Abstract_Seo {
683
  return;
684
  }
685
 
 
 
 
 
686
  $shop_name = get_bloginfo('name');
687
  $shop_url = home_url();
688
  $currency = get_woocommerce_currency();
689
  $markup = array();
690
  $markup['@type'] = 'Product';
691
- if (method_exists($product, 'get_id')) {
692
- $markup['@id'] = get_permalink($product->get_id());
693
- }
694
- $markup['url'] = $markup['@id'];
695
  if (method_exists($product, 'get_name')) {
696
  $markup['name'] = $product->get_name();
697
  } else {
698
  $markup['name'] = $product->get_title();
699
  }
700
 
 
 
 
 
 
 
 
701
  if (apply_filters('woocommerce_structured_data_product_limit', is_product_taxonomy() || is_shop())) {
702
  $this->set_data(apply_filters('woocommerce_structured_data_product_limited', $markup, $product));
703
  return;
704
  }
705
 
 
 
 
 
 
 
706
  $markup_offer = array(
707
  '@type' => 'Offer',
 
 
 
708
  'priceCurrency' => $currency,
709
  'availability' => 'https://schema.org/' . $stock = ($product->is_in_stock() ? 'InStock' : 'OutOfStock'),
710
  'sku' => (method_exists($product, 'get_sku')) ? $product->get_sku() : '',
@@ -717,6 +633,7 @@ class SQ_Models_Services_JsonLD extends SQ_Models_Abstract_Seo {
717
  ),
718
  );
719
 
 
720
  if ($product->is_type('variable') && method_exists($product, 'get_variation_prices')) {
721
  $prices = $product->get_variation_prices();
722
 
@@ -726,19 +643,59 @@ class SQ_Models_Services_JsonLD extends SQ_Models_Abstract_Seo {
726
  'maxPrice' => wc_format_decimal(end($prices['price']), wc_get_price_decimals()),
727
  'priceCurrency' => $currency,
728
  );
729
- } else {
730
- $markup_offer['price'] = wc_format_decimal($product->get_price(), wc_get_price_decimals());
731
  }
732
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
733
  $markup['offers'] = $markup_offer;
734
 
735
- if ($product->get_rating_count()) {
736
  $markup['aggregateRating'] = array(
737
  '@type' => 'AggregateRating',
738
  'ratingValue' => $product->get_average_rating(),
739
  'ratingCount' => $product->get_rating_count(),
740
  'reviewCount' => $product->get_review_count(),
741
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
742
  }
743
 
744
  $this->set_data($markup);
@@ -750,50 +707,56 @@ class SQ_Models_Services_JsonLD extends SQ_Models_Abstract_Seo {
750
  /**
751
  * Generates Review structured data.
752
  */
753
- public function generate_review_data() {
754
  global $comment;
 
755
 
756
  try {
757
- if (function_exists('get_comments') && function_exists('get_comment_meta')) {
758
- $args = array('post_id' => $this->_post->ID, 'post_type' => 'product');
759
- $comments = get_comments($args);
760
- foreach ($comments as $comment) {
761
- if ($comment->comment_approved == 0) {
762
- continue;
763
- }
764
- //echo '<pre>'.print_R($comment,true).'</pre>';
765
- $markup = array();
766
- $markup['@type'] = 'Review';
767
- $markup['@id'] = get_comment_link($comment->comment_ID);
768
- $markup['datePublished'] = get_comment_date('c', $comment->comment_ID);
769
- $markup['description'] = get_comment_text($comment->comment_ID);
770
- $markup['itemReviewed'] = array(
771
- '@type' => 'Product',
772
- 'name' => get_the_title($comment->comment_post_ID),
773
- );
 
 
 
774
 
775
- if ($rating = get_metadata('comment', $comment->comment_ID, 'rating', true)) {
776
- $markup['reviewRating'] = array(
777
- '@type' => 'rating',
778
- 'ratingValue' => $rating,
 
 
 
 
 
 
 
 
 
 
779
  );
780
 
781
- // Skip replies unless they have a rating.
782
- } elseif ($comment->comment_parent) {
783
- return;
784
  }
785
-
786
- $markup['author'] = array(
787
- '@type' => 'Person',
788
- 'name' => get_comment_author($comment->comment_ID),
789
- );
790
-
791
- $this->set_data($markup);
792
  }
793
  }
794
  } catch (Exception $e) {
795
 
796
  }
 
 
797
  }
798
 
799
  /**
19
  if ($this->_post->post_type == 'product') {
20
  add_filter('sq_json_ld', array($this, 'generate_product_data'), 8);
21
  add_filter('sq_json_ld', array($this, 'generate_order_data'), 8);
 
22
  }
23
  }
24
 
290
  "url" => $user_url,
291
  "name" => $display_name,
292
  );
293
+ }elseif (isset($jsonld['Person'])) {
 
 
294
  $markup['publisher'] = array(
295
+ "@type" => 'Person',
 
296
  "name" => $this->getAuthor('display_name'),
297
  );
298
 
299
+ foreach ($jsonld['Person'] as $key => $value) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  if ($value <> '') {
301
 
302
  if ($key == 'logo') {
312
  }
313
  }
314
 
315
+ if (isset($jsonld['Organization'])) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  $markup['publisher'] = array(
317
+ "@type" => 'Organization',
318
  "url" => $this->_post->url,
319
  "name" => $this->getAuthor('display_name'),
320
  );
321
 
322
+ foreach ($jsonld['Organization'] as $key => $value) {
323
  if ($value <> '') {
324
  if ($key == 'contactType' || $key == 'telephone' || $key == 'jobTitle') {
325
  continue;
331
  "url" => $value
332
  );
333
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  } else {
335
  $markup['publisher'][$key] = $value;
336
  }
580
  return;
581
  }
582
 
583
+ if (!method_exists($product, 'get_id')) {
584
+ return;
585
+ }
586
+
587
  $shop_name = get_bloginfo('name');
588
  $shop_url = home_url();
589
  $currency = get_woocommerce_currency();
590
  $markup = array();
591
  $markup['@type'] = 'Product';
592
+ $markup['url'] = get_permalink($product->get_id());
593
+ $markup['@id'] = $markup['url'] . '#' . 'Product';
594
+
 
595
  if (method_exists($product, 'get_name')) {
596
  $markup['name'] = $product->get_name();
597
  } else {
598
  $markup['name'] = $product->get_title();
599
  }
600
 
601
+ if (method_exists($product, 'get_short_description')) {
602
+ $markup['description'] = wp_strip_all_tags(do_shortcode($product->get_short_description() ? $product->get_short_description() : $product->get_description()));
603
+ }
604
+
605
+ if ($image = wp_get_attachment_url($product->get_image_id())) {
606
+ $markup['image'] = $image;
607
+ }
608
  if (apply_filters('woocommerce_structured_data_product_limit', is_product_taxonomy() || is_shop())) {
609
  $this->set_data(apply_filters('woocommerce_structured_data_product_limited', $markup, $product));
610
  return;
611
  }
612
 
613
+ if (method_exists($product, 'get_date_on_sale_to') && $product->get_date_on_sale_to()) {
614
+ $price_valid_until = date('Y-m-d', $product->get_date_on_sale_to()->getTimestamp());
615
+ } else {
616
+ $price_valid_until = date('Y-m-d', strtotime('+12 Month'));
617
+ }
618
+
619
  $markup_offer = array(
620
  '@type' => 'Offer',
621
+ 'price' => wc_format_decimal($product->get_price(), wc_get_price_decimals()),
622
+ 'priceValidUntil' => $price_valid_until,
623
+ 'url' => get_permalink($product->get_id()),
624
  'priceCurrency' => $currency,
625
  'availability' => 'https://schema.org/' . $stock = ($product->is_in_stock() ? 'InStock' : 'OutOfStock'),
626
  'sku' => (method_exists($product, 'get_sku')) ? $product->get_sku() : '',
633
  ),
634
  );
635
 
636
+
637
  if ($product->is_type('variable') && method_exists($product, 'get_variation_prices')) {
638
  $prices = $product->get_variation_prices();
639
 
643
  'maxPrice' => wc_format_decimal(end($prices['price']), wc_get_price_decimals()),
644
  'priceCurrency' => $currency,
645
  );
 
 
646
  }
647
 
648
+ $categories = $product->get_category_ids();
649
+ if (!empty($categories)) {
650
+ foreach ($categories as $category) {
651
+ $category = get_term($category, 'product_cat');
652
+ if (!is_wp_error($category)) {
653
+ $markup['brand'] = array(
654
+ '@type' => 'Thing',
655
+ 'name' => $category->name,
656
+ );
657
+ }
658
+ }
659
+ }
660
+
661
+ $markup['sku'] = (method_exists($product, 'get_sku')) ? $product->get_sku() : '-';
662
+ $markup['mpn'] = $markup['sku'];
663
+
664
+ if (function_exists('wc_prices_include_tax')) {
665
+ $markup_offer['priceSpecification']['valueAddedTaxIncluded'] = wc_prices_include_tax() ? 'true' : 'false';
666
+ }
667
  $markup['offers'] = $markup_offer;
668
 
669
+ if (method_exists($product, 'get_rating_count') && $product->get_rating_count()) {
670
  $markup['aggregateRating'] = array(
671
  '@type' => 'AggregateRating',
672
  'ratingValue' => $product->get_average_rating(),
673
  'ratingCount' => $product->get_rating_count(),
674
  'reviewCount' => $product->get_review_count(),
675
  );
676
+ $markup['review'] = $this->get_review_data($product);
677
+
678
+ }else{ //add default datas?
679
+ $markup['aggregateRating'] = array(
680
+ '@type' => 'AggregateRating',
681
+ 'ratingValue' => 5,
682
+ 'ratingCount' => 1,
683
+ 'reviewCount' => 1,
684
+ );
685
+
686
+ $markup['review'][] = array(
687
+ '@type' => 'Review',
688
+ 'reviewRating' => array(
689
+ '@type' => 'Rating',
690
+ 'ratingValue' => 5,
691
+ ),
692
+ 'author' => array(
693
+ '@type' => 'Person',
694
+ 'name' => '',
695
+ ),
696
+ 'reviewBody' => '',
697
+ 'datePublished' => (method_exists($product, 'get_date_created') && method_exists($product->get_date_created(), 'getTimestamp')) ? date('Y-m-d', $product->get_date_created()->getTimestamp()) : '',
698
+ );
699
  }
700
 
701
  $this->set_data($markup);
707
  /**
708
  * Generates Review structured data.
709
  */
710
+ public function get_review_data($product) {
711
  global $comment;
712
+ $markup = array();
713
 
714
  try {
715
+ if (function_exists('wc_review_ratings_enabled') && wc_review_ratings_enabled() &&
716
+ function_exists('get_comments') && function_exists('get_comment_meta')) {
717
+ $comments = get_comments(
718
+ array(
719
+ 'number' => 10,
720
+ 'post_id' => $product->get_id(),
721
+ 'status' => 'approve',
722
+ 'post_status' => 'publish',
723
+ 'post_type' => 'product',
724
+ 'parent' => 0,
725
+ 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
726
+ array(
727
+ 'key' => 'rating',
728
+ 'type' => 'NUMERIC',
729
+ 'compare' => '>',
730
+ 'value' => 0,
731
+ ),
732
+ ),
733
+ )
734
+ );
735
 
736
+ if ($comments) {
737
+ foreach ($comments as $comment) {
738
+ $markup[] = array(
739
+ '@type' => 'Review',
740
+ 'reviewRating' => array(
741
+ '@type' => 'Rating',
742
+ 'ratingValue' => get_comment_meta($comment->comment_ID, 'rating', true),
743
+ ),
744
+ 'author' => array(
745
+ '@type' => 'Person',
746
+ 'name' => get_comment_author($comment),
747
+ ),
748
+ 'reviewBody' => get_comment_text($comment),
749
+ 'datePublished' => get_comment_date('c', $comment),
750
  );
751
 
 
 
 
752
  }
 
 
 
 
 
 
 
753
  }
754
  }
755
  } catch (Exception $e) {
756
 
757
  }
758
+ return $markup;
759
+
760
  }
761
 
762
  /**
models/services/OpenGraph.php CHANGED
@@ -149,14 +149,14 @@ class SQ_Models_Services_OpenGraph extends SQ_Models_Abstract_Seo {
149
  }
150
  if (method_exists($product, 'get_sale_price')) {
151
  $sale_price = $product->get_sale_price();
152
- if ($sale_price > 0 && method_exists($product, 'get_date_on_sale_from')) {
153
  $sales_price_from = $product->get_date_on_sale_from();
154
- $sale_price = $product->get_date_on_sale_from();
155
  if (is_a($sales_price_from, 'WC_DateTime') && method_exists($sales_price_from, 'getTimestamp')) {
156
  $sales_price_from = $sales_price_from->getTimestamp();
157
  }
158
- if (is_a($sale_price, 'WC_DateTime') && method_exists($sale_price, 'getTimestamp')) {
159
- $sale_price = $sale_price->getTimestamp();
160
  }
161
  }
162
  }
@@ -183,10 +183,10 @@ class SQ_Models_Services_OpenGraph extends SQ_Models_Abstract_Seo {
183
  $og['product:sale_price:currency'] = $currency;
184
 
185
  if ($sales_price_from > 0) {
186
- $og['product:sale_price:start'] = date("Y-m-d H:i:s", $sales_price_from);
187
  }
188
  if ($sales_price_to) {
189
- $og['product:sale_price:end'] = date("Y-m-d H:i:s", $sales_price_to);
190
  }
191
 
192
  }
149
  }
150
  if (method_exists($product, 'get_sale_price')) {
151
  $sale_price = $product->get_sale_price();
152
+ if ($sale_price > 0 && method_exists($product, 'get_date_on_sale_from') && method_exists($product, 'get_date_on_sale_to')) {
153
  $sales_price_from = $product->get_date_on_sale_from();
154
+ $sales_price_to = $product->get_date_on_sale_to();
155
  if (is_a($sales_price_from, 'WC_DateTime') && method_exists($sales_price_from, 'getTimestamp')) {
156
  $sales_price_from = $sales_price_from->getTimestamp();
157
  }
158
+ if (is_a($sales_price_to, 'WC_DateTime') && method_exists($sales_price_to, 'getTimestamp')) {
159
+ $sales_price_to = $sales_price_to->getTimestamp();
160
  }
161
  }
162
  }
183
  $og['product:sale_price:currency'] = $currency;
184
 
185
  if ($sales_price_from > 0) {
186
+ $og['product:sale_price:start'] = date("Y-m-d", $sales_price_from);
187
  }
188
  if ($sales_price_to) {
189
+ $og['product:sale_price:end'] = date("Y-m-d", $sales_price_to);
190
  }
191
 
192
  }
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
- ===Squirrly SEO 2019 (Strategy)===
2
  Contributors: cifi, calinvingan, florinmuresan, nagy.sorel
3
  Tags: seo, wordpress seo, seo plugin, seo optimization, seo content, seo meta, open graph, e-commerce, plugins, content, marketing, ecommerce, keyword research, content seo, yoast, all in one seo, search engine optimization, XML sitemap for google, multisite SEO, squirrly, meta title, meta description, favicon, mobile, canonical, seo correction, seo title, twitter, woocommerce, feeds, social media, blogging, google-analytics, tracking, best seo tools audit website, content audit tool, ecommerce seo strategy, marketing research tools, research tools for writers, seo audit tool, SEO keyword research tool,duplicate removal tool, ecommerce SEO, facebook open graph wordpress, google keyword planner alternative, Google ranking, how to install facebook pixel on wordpress, JSON-LD structure, Live Assistant, meta duplicate removal, open graph generator, pinterest rich pin validator, related links
4
  Requires at least: 4.2
5
  Requires PHP: 5.3
6
- Tested up to: 5.3
7
  Stable tag: trunk
8
  License: GPLv2 or later
9
  Donate link: https://plugin.squirrly.co/wordpress/seo
@@ -107,7 +107,7 @@ It’s like applying a random treatment regardless of the symptoms, just because
107
 
108
  No.
109
 
110
- It makes absolutely no sense, not when you can use Squirrly SEO 2019 (brand new. complete redesign) which looks at your pages like Google does.
111
 
112
  The revolutionary <a title="The Revolutionary Concept And Method" href="https://plugin.squirrly.co/focus-pages/">concept of Focus Pages</a> is here to transform and innovate the way you optimize your WordPress site because it’s not enough to have a destination (being found on the first page of Google).
113
 
@@ -115,7 +115,7 @@ You also need an updated map for HOW to get there. We built Focus Pages to provi
115
 
116
  Everything from creating human-optimized content to SEO keywords and the user’s experience on your site is checked for in one way or another. Also factors related to quality signals like: impressions, clicks, ctr, social signals, inner links, links from other sites, authority of sites sending links to you.
117
 
118
- In fact, Squirrly SEO 2019 now looks at over 54 critical ranking factors that Google takes into account when analyzing a page and deciding how high to place it in SERPs.
119
 
120
  For every page that you add as a Focus Page inside Squirrly SEO, the plugin will show you exactly what actions to take to rank a particular page higher in Google. You’ll know precisely what to focus on to generate the most impact.
121
 
@@ -127,12 +127,12 @@ This is the only plugin and SEO software capable of adapting to the specifics of
127
 
128
  The amount of data being processed and the way we process the data is a culmination of groundbreaking work.
129
 
130
- With the new Squirrly SEO 2019, we fix problems related to SEO that no other plugin or software can fix. Because we approach things in a way that hasn’t been done before.
131
 
132
 
133
  A 14 Days Journey to Better Ranking
134
 
135
- As part of the new Squirrly SEO 2019, you’ll also be able to start a 14 Days Journey to Better Ranking. If you ever felt like you were stumbling in the dark when trying to rank your pages, embarking on this journey will finally make you feel like you’re making progress.
136
 
137
  During the 14 days, you’ll be able to follow a clear process and receive Daily recipes to help you finally achieve SEO results.
138
 
@@ -150,7 +150,7 @@ Bulk SEO Settings helps you tweak the title, description, JSON-LD, Facebook, Twi
150
 
151
  SEO Automation tools (with Expert-level access) will turn SEO work into something that’s easier than reading the news in a self-driving car on your way to work.
152
 
153
- Squirrly SEO 2019 (Strategy) helps you create and focus on amazing SEO Strategies:
154
 
155
  - Focus Pages
156
  - Bulk SEO Settings
@@ -161,7 +161,7 @@ Squirrly SEO 2019 (Strategy) helps you create and focus on amazing SEO Strategie
161
 
162
  See how we fix common SEO problems with this brand new release: <a title="Years of Bad SEO Can Easily Be Fixed" href="https://www.squirrly.co/most-common-seo-problems-that-we-see-in-customers-sites-time-and-again/">We've made it incredibly easy to fix SEO issues which are found on almost every site you'll see.</a>
163
 
164
- See why Generic WordPress SEO Plugins just aren’t enough anymore (not in 2019) <a title="Generic Plugins for WordPress SEO are dangerous" href="https://www.squirrly.co/how-do-generic-seo-plugins-work-in-wordpress-and-why-is-squirrly-seo-different/">Generic SEO Plugins are dangerous because they let the user believe that SEO involves no work at all.</a>
165
 
166
  See the multiple levels of WordPress SEO. <a title="Levels of SEO: Keyword Competition, Time on Page, Bounce Rate, Exit Rates, Impressions, and a lot more" href="https://www.squirrly.co/all-the-important-levels-of-search-engine-optimization-explained/">Just adding a rich snippet or validating a Twitter card doesn't increase your rankings on Google. Just makes things look nice. To make these elements really work for ranking higher, you need all levels of SEO.</a>
167
 
@@ -366,6 +366,35 @@ Type a keyword to the right of the screen and start using Squirrly Seo. Enjoy!
366
  Squirrly SEO 9.2.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.
367
 
368
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
369
  = 9.2.16 - 12/21/2019 =
370
  * SEO Update - Tested and Compatible with WordPress 5.3.2
371
  * Update JSON-LD for AMP websites
@@ -1443,7 +1472,7 @@ Because our tool focuses on the information your need to better rank on Google n
1443
 
1444
  = I can't log into the Wordpress with my user. Get the message 'An error occured.' What can I do? =
1445
  I see that your host server is not letting you access our remote API.
1446
- Please tell your webmaster to add the IPs 176.9.59.55 and 176.9.112.210 in the white-list for remote access and it should work.
1447
 
1448
  = 100% green in Squirrly Live Assistant but I’m not getting traffic yet =
1449
  Sometimes we receive emails with this question and I want to help everybody have the correct image of Squirrly Live Assistance. The article bellow answers in detail this question.
1
+ ===Squirrly SEO (Strategy)===
2
  Contributors: cifi, calinvingan, florinmuresan, nagy.sorel
3
  Tags: seo, wordpress seo, seo plugin, seo optimization, seo content, seo meta, open graph, e-commerce, plugins, content, marketing, ecommerce, keyword research, content seo, yoast, all in one seo, search engine optimization, XML sitemap for google, multisite SEO, squirrly, meta title, meta description, favicon, mobile, canonical, seo correction, seo title, twitter, woocommerce, feeds, social media, blogging, google-analytics, tracking, best seo tools audit website, content audit tool, ecommerce seo strategy, marketing research tools, research tools for writers, seo audit tool, SEO keyword research tool,duplicate removal tool, ecommerce SEO, facebook open graph wordpress, google keyword planner alternative, Google ranking, how to install facebook pixel on wordpress, JSON-LD structure, Live Assistant, meta duplicate removal, open graph generator, pinterest rich pin validator, related links
4
  Requires at least: 4.2
5
  Requires PHP: 5.3
6
+ Tested up to: 5.4
7
  Stable tag: trunk
8
  License: GPLv2 or later
9
  Donate link: https://plugin.squirrly.co/wordpress/seo
107
 
108
  No.
109
 
110
+ It makes absolutely no sense, not when you can use Squirrly SEO (brand new. complete redesign) which looks at your pages like Google does.
111
 
112
  The revolutionary <a title="The Revolutionary Concept And Method" href="https://plugin.squirrly.co/focus-pages/">concept of Focus Pages</a> is here to transform and innovate the way you optimize your WordPress site because it’s not enough to have a destination (being found on the first page of Google).
113
 
115
 
116
  Everything from creating human-optimized content to SEO keywords and the user’s experience on your site is checked for in one way or another. Also factors related to quality signals like: impressions, clicks, ctr, social signals, inner links, links from other sites, authority of sites sending links to you.
117
 
118
+ In fact, Squirrly SEO now looks at over 54 critical ranking factors that Google takes into account when analyzing a page and deciding how high to place it in SERPs.
119
 
120
  For every page that you add as a Focus Page inside Squirrly SEO, the plugin will show you exactly what actions to take to rank a particular page higher in Google. You’ll know precisely what to focus on to generate the most impact.
121
 
127
 
128
  The amount of data being processed and the way we process the data is a culmination of groundbreaking work.
129
 
130
+ With the new Squirrly SEO, we fix problems related to SEO that no other plugin or software can fix. Because we approach things in a way that hasn’t been done before.
131
 
132
 
133
  A 14 Days Journey to Better Ranking
134
 
135
+ As part of the new Squirrly SEO, you’ll also be able to start a 14 Days Journey to Better Ranking. If you ever felt like you were stumbling in the dark when trying to rank your pages, embarking on this journey will finally make you feel like you’re making progress.
136
 
137
  During the 14 days, you’ll be able to follow a clear process and receive Daily recipes to help you finally achieve SEO results.
138
 
150
 
151
  SEO Automation tools (with Expert-level access) will turn SEO work into something that’s easier than reading the news in a self-driving car on your way to work.
152
 
153
+ Squirrly SEO (Strategy) helps you create and focus on amazing SEO Strategies:
154
 
155
  - Focus Pages
156
  - Bulk SEO Settings
161
 
162
  See how we fix common SEO problems with this brand new release: <a title="Years of Bad SEO Can Easily Be Fixed" href="https://www.squirrly.co/most-common-seo-problems-that-we-see-in-customers-sites-time-and-again/">We've made it incredibly easy to fix SEO issues which are found on almost every site you'll see.</a>
163
 
164
+ See why Generic WordPress SEO Plugins just aren’t enough anymore (not in 2020) <a title="Generic Plugins for WordPress SEO are dangerous" href="https://www.squirrly.co/how-do-generic-seo-plugins-work-in-wordpress-and-why-is-squirrly-seo-different/">Generic SEO Plugins are dangerous because they let the user believe that SEO involves no work at all.</a>
165
 
166
  See the multiple levels of WordPress SEO. <a title="Levels of SEO: Keyword Competition, Time on Page, Bounce Rate, Exit Rates, Impressions, and a lot more" href="https://www.squirrly.co/all-the-important-levels-of-search-engine-optimization-explained/">Just adding a rich snippet or validating a Twitter card doesn't increase your rankings on Google. Just makes things look nice. To make these elements really work for ranking higher, you need all levels of SEO.</a>
167
 
366
  Squirrly SEO 9.2.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.
367
 
368
  == Changelog ==
369
+ = 9.2.22 - 04/21/2020 =
370
+ * Fixed Focus Pages Manual Request Index in case the post is already indexed
371
+ * Fixed Json-LD product publish date compatibility with Woocommerce
372
+ * Fixed GSC connection issue after Google API update
373
+ * Update SEO Assistant in Bulk SEO
374
+
375
+ = 9.2.21 - 04/13/2020 =
376
+ * Fixed Focus Pages audit date and error
377
+ * Fixed AMP issue for JSON-LD
378
+
379
+ = 9.2.20 - 04/03/2020 =
380
+ * SEO Update - Tested and Compatible with WordPress 5.4 stable
381
+ * Live Assistant works well for Media Files
382
+ * Fixed small bugs
383
+
384
+ = 9.2.18 - 02/12/2020 =
385
+ * Updated Squirrly Live Assistant and Briefcase for Google 2020
386
+ * Fixed the Json-LD for Woocommerce websites
387
+ * Fixed Squirrly to load Google API only for Squirrly settings pages
388
+
389
+ = 9.2.17 - 01/22/2020 =
390
+ * Updated the Focus Pages SEO Image, Innerlinks, traffic
391
+ * Fixed compatibility with Starbox plugin
392
+ * Fixed SSL check on remote calls to Squirrly Cloud
393
+ * Update compatibility with the last version of Woocommerce
394
+ * Update compatibility with review plugins
395
+ * Update Open Graph product valability
396
+ * Import from Rank Math plugin
397
+
398
  = 9.2.16 - 12/21/2019 =
399
  * SEO Update - Tested and Compatible with WordPress 5.3.2
400
  * Update JSON-LD for AMP websites
1472
 
1473
  = I can't log into the Wordpress with my user. Get the message 'An error occured.' What can I do? =
1474
  I see that your host server is not letting you access our remote API.
1475
+ Please tell your webmaster to add the IPs 176.9.121.162 and 176.9.112.210 in the white-list for remote access and it should work.
1476
 
1477
  = 100% green in Squirrly Live Assistant but I’m not getting traffic yet =
1478
  Sometimes we receive emails with this question and I want to help everybody have the correct image of Squirrly Live Assistance. The article bellow answers in detail this question.
squirrly.php CHANGED
@@ -1,20 +1,20 @@
1
  <?php
2
  /*
3
- Copyright (c) 2012-2019, SEO Squirrly.
4
  The copyrights to the software code in this file are licensed under the (revised) BSD open source license.
5
 
6
  Plugin Name: Squirrly SEO 2019 (Strategy)
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.16
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.16');
16
  //The last stable version
17
- define('SQ_STABLE_VERSION', '9.2.14');
18
  // Call config files
19
  try {
20
  require_once(dirname(__FILE__) . '/config/config.php');
1
  <?php
2
  /*
3
+ Copyright (c) 2012-2020, SEO Squirrly.
4
  The copyrights to the software code in this file are licensed under the (revised) BSD open source license.
5
 
6
  Plugin Name: Squirrly SEO 2019 (Strategy)
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.22
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.22');
16
  //The last stable version
17
+ define('SQ_STABLE_VERSION', '9.2.18');
18
  // Call config files
19
  try {
20
  require_once(dirname(__FILE__) . '/config/config.php');
view/Dashboard.php CHANGED
@@ -1,3 +1,4 @@
 
1
  <div id="sq_wrap">
2
  <?php SQ_Classes_ObjController::getClass('SQ_Core_BlockToolbar')->init(); ?>
3
 
1
+ <script type="text/javascript" src="//www.google.com/jsapi"></script>
2
  <div id="sq_wrap">
3
  <?php SQ_Classes_ObjController::getClass('SQ_Core_BlockToolbar')->init(); ?>
4
 
view/assets/css/post.css CHANGED
@@ -150,7 +150,7 @@
150
 
151
  #postsquirrly.sq_sticky {
152
  position: fixed !important;
153
- z-index: 999999 !important;
154
  right: 3px;
155
  bottom: 0;
156
  top: auto;
@@ -324,8 +324,7 @@
324
  font-size: 12px;
325
  text-align: center;
326
  color: red;
327
- margin-top: 5px;
328
- margin-bottom: 5px;
329
  }
330
 
331
  #sq_blocklogin #sq_register {
150
 
151
  #postsquirrly.sq_sticky {
152
  position: fixed !important;
153
+ z-index: 90000 !important;
154
  right: 3px;
155
  bottom: 0;
156
  top: auto;
324
  font-size: 12px;
325
  text-align: center;
326
  color: red;
327
+ margin: 5px auto;
 
328
  }
329
 
330
  #sq_blocklogin #sq_register {
view/assets/css/post.min.css CHANGED
@@ -1 +1 @@
1
- @import url(https://fonts.googleapis.com/css?family=Open+Sans);@-ms-keyframes play{0%{background-position:0}to{background-position:-400px}}@-o-keyframes play{0%{background-position:0}to{background-position:-400px}}@keyframes play{0%{background-position:0}to{background-position:-400px}}.sq_minloading{position:relative;opacity:.5}.sq_loading{height:60px;background:url(../img/loading.gif) no-repeat center!important}.sq_minloading:before{position:absolute!important;right:calc(50% - 10px)!important;top:calc(50% - 8px)!important;display:block!important;float:right!important;line-height:30px!important;content:""!important;padding:0!important;margin:0 0 0 5px!important;height:16px!important;width:20px!important;background:url(../img/minloading.png) no-repeat!important;-webkit-animation:play 1s steps(10) infinite;-moz-animation:play 1s steps(10) infinite;-o-animation:play 1s steps(10) infinite;animation:play 1s steps(10) infinite}#sq_preloading{text-align:center;font-size:15px;line-height:24px;color:gray}#postsquirrly{background:0 0;border:0;margin:-20px 0 10px;padding:2px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}#postsquirrly *,#sq_blocksnippet *{box-sizing:border-box}#postsquirrly.closed .inside{display:block}.sq_push{position:absolute;top:-7px;left:30px;font-size:10px;margin:0;border:1px solid #333;background-color:#8b0000;border-radius:50px;-webkit-border-radius:50px;-moz-border-radius:50px;padding:0 1px;width:14px;text-shadow:1px 1px #333;color:#fff;font-family:'Megalopolis',Arial,Helvetica,sans-serif;text-align:center}#sq_options_dasboard .sq_push{left:36px}#postsquirrly div.inside,#postsquirrly p,#postsquirrly td{margin:0;padding:0}#postsquirrly .handlediv,#postsquirrly .hndle{background:gray;opacity:0;height:1px;line-height:0}#postsquirrly .sq_header{color:#a0a0a0;font-size:14px;font-weight:400;padding:5px 7px;margin:0;line-height:20px;border-bottom:1px dashed #d1d1d1;box-shadow:0 1px 2px -1px #ccc;-moz-box-shadow:0 1px 2px -1px #ccc;-webkit-box-shadow:0 1px 2px -1px #ccc}#postsquirrly .sq_box{background-color:#fcfcfc;margin-bottom:15px;box-shadow:0 1px 2px -1px #444;-moz-box-shadow:0 1px 2px -1px #444;-webkit-box-shadow:0 1px 2px -1px #444}#normal-sortables #postsquirrly .sq_box{max-width:490px;margin:auto}#postsquirrly.sq_sticky{position:fixed!important;z-index:999999!important;right:3px;bottom:0;top:auto;height:136px;width:285px!important;padding:1px!important;background:#fff!important;overflow-x:auto!important;box-shadow:0 0 8px 0 #000!important}#postsquirrly.sq_sticky::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.3);background-color:#f5f5f5}#postsquirrly.sq_sticky::-webkit-scrollbar{width:7px;background-color:#f5f5f5}#postsquirrly.sq_sticky::-webkit-scrollbar-thumb{background-color:#bdafba;border:0}#postsquirrly.sq_sticky .hndle,#postsquirrly.sq_sticky.minimized #sq_briefcase_list,#postsquirrly.sq_sticky.minimized #sq_briefcase_topcontent{display:none!important}#postsquirrly.sq_sticky .sq_header{cursor:move}#postsquirrly .sq_box_close,#postsquirrly .sq_box_maximize,#postsquirrly .sq_box_minimize{display:block;float:right;margin:0;cursor:pointer;font-family:Arial,sans-serif;font-weight:400;font-size:17px;color:gray;padding:0 0 0 10px;height:22px}#postsquirrly.sq_sticky.minimized{height:136px!important;overflow:hidden!important}#postsquirrly .inside{position:relative;height:100%}#postsquirrly .sq_box.sq_sticky{position:fixed;top:32px;z-index:99999;height:100%;max-width:291px;overflow-x:auto}#postsquirrly.sq_sticky .sq_box.sq_sticky{position:absolute;top:0;bottom:0;height:100%;margin:0}#postsquirrly .sq_box.sq_sticky>div{margin-bottom:25px}#postsquirrly .sq_box:before{display:block;content:" ";background:url(../img/sprite.png) repeat-x 0 -360px;width:100%;height:5px;border-radius:2px 2px 0 0;opacity:.3}#postsquirrly .sq_box:hover:before{opacity:.8}#postsquirrly .sq_box:hover .sq_header{color:#444}#sq_blocklogin{background-color:#ffffe0}#sq_blocklogin input,#sq_blocklogin textarea{font-family:Arial,Helvetica,sans-serif;font-size:14px;height:30px;padding:6px}#postsquirrly .sq_button,#sq_blocklogin #sq_login{cursor:pointer;background-color:#589ee4;color:#fff;border:0}#postsquirrly .sq_button{display:block;text-decoration:none;line-height:30px;font-weight:700;margin:0;padding:0 15px;vertical-align:top;border-radius:0}#sq_blocklogin #sq_login{min-width:100px;min-height:35px;border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:10px}#sq_blocklogin label{margin-top:0;margin-right:2px;width:72px;display:inline-block}#sq_blocklogin ul li{position:relative;font-family:"Lucida Grande",Arial,Helvetica,sans-serif;font-size:12px;padding:4px 0 4px 5px;margin:5px 0;line-height:16px;text-shadow:1px 1px #fff;text-align:center}#postsquirrly .sq_button,#sq_blocklogin .sq_info{font-size:13px;text-align:center}#sq_blocklogin .sq_error{font-size:12px;text-align:center;color:red;margin-top:5px;margin-bottom:5px}#sq_blocklogin #sq_register{margin:5px 0;font-size:16px;font-weight:700}#sq_blocklogin #sq_register_wait{display:inline-block;margin-left:2px}#sq_blocklogin #sq_autologin{padding:20px 10px 5px}#sq_blocklogin #sq_autologin #sq_loginimage{display:block;background-color:#589ee4;height:auto;width:100px;font-size:15px;color:#fff;font-weight:700;margin:13px;padding:10px 0;text-decoration:none;border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:10px;cursor:pointer}#sq_blocklogin #sq_register_email{text-align:center;width:250px;height:45px;margin:14px auto 11px}#sq_blocklogin #sq_register_email #sq_email{width:160px!important;border:2px solid #589ee4}#sq_blocklogin #sq_signin{color:#11a5c1;margin:5px;cursor:pointer}#sq_options,#sq_options>ul>li{position:relative;float:right;padding:0}#sq_options{height:40px;z-index:13;margin:0}#side-sortables #sq_options{z-index:1003}#postsquirrly #sq_options{float:none;background:0 0;border:0;box-shadow:none}#normal-sortables #postsquirrly #sq_options{display:flex;width:280px;margin:10px auto}#sq_blocksearch ul,#sq_blockseo ul,#sq_options>ul{margin:10px 0;padding:0}#sq_options>ul>li{font-family:"Open Sans",Arial,sans-serif!important;width:102px;color:#444;font-size:14px;margin:0 auto;cursor:pointer}#sq_options li#sq_options_support{margin-left:11px;width:105px}#sq_options_dasboard .sq_text a,#sq_options_support .sq_text{display:block;float:left;font-family:"Open Sans",Arial,sans-serif!important;font-size:12px;color:#333;text-decoration:none;padding:3px 5px;border:1px solid #ccc;border-radius:5px;background:#fff;background:-moz-linear-gradient(top,#fff,#f5f5f5);background:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f5f5f5))}#sq_options .sq_icon{display:block;float:left;background:url(../img/sprite.png) no-repeat;margin:-8px 5px 0 3px}#sq_options>ul>li#sq_options_feedback{width:38px;margin-left:2px}#sq_options_feedback .sq_label_feedback_smiley{display:block;height:37px;width:37px;margin:5px auto;background:url(../img/sprite.png) no-repeat;border:0;cursor:pointer}#sq_options_feedback .sq_feedback_smiley{display:none}#sq_options_feedback .sq_label_feedback_0{background-position:-102px -154px!important}#sq_options_feedback .sq_label_feedback_1{background-position:-148px -154px!important}#sq_options_feedback .sq_label_feedback_2{background-position:-194px -154px!important}#sq_options_feedback .sq_label_feedback_3{background-position:-240px -154px!important}#sq_options_feedback .sq_label_feedback_4{background-position:-284px -154px!important}#sq_options_feedback .sq_icon{height:37px;width:35px;background-position:-194px -154px}#sq_options_support .sq_icon{height:37px;width:30px;background-position:-5px -154px}#sq_options_dasboard .sq_icon{height:39px;width:40px;background-position:-40px -154px}#sq_options_feedback .sq_options_feedback_popup,#sq_options_support .sq_options_support_popup{display:table;min-width:345px;position:absolute;z-index:12;background-color:#fff;padding:5px;margin-top:0;top:33px;border:1px solid #ccc;border-radius:0 7px 7px 7px;-moz-border-radius:0 7px 7px 7px;-webkit-border-radius:0 7px 7px 7px;box-shadow:1px 4px 6px -1px #888;-moz-box-shadow:1px 4px 6px -1px #888;-webkit-box-shadow:1px 4px 6px -1px #888;cursor:default}#side-sortables #sq_options_feedback .sq_options_feedback_popup,#side-sortables #sq_options_support .sq_options_support_popup{z-index:1002}#sq_options_support .sq_options_support_popup{right:0}#sq_options_feedback .sq_options_feedback_popup{left:-101px}#sq_options_feedback table td{text-align:center;color:#999;min-width:50px;height:70px}#sq_options_feedback .sq_options_feedback_popup li,#sq_options_support .sq_options_support_popup li{color:#333;line-height:16px;font-size:13px;font-weight:400;margin:0;padding:3px 5px}#sq_options_feedback #sq_options_feedback_error,#sq_options_support #sq_options_support_error{margin:6px 0}#sq_options_feedback .sq_small_input{width:100%;height:70px}#sq_options_support .sq_small_input{width:100%}#sq_options_feedback .sq_options_feedback_popup #sq_feedback_submit,#sq_options_support .sq_options_support_popup #sq_support_submit{background-color:#589ee4;font-size:12px;font-weight:700;color:#fff;width:100px;margin:10px auto 5px;padding:5px;position:relative;text-shadow:1px 1px #555;border:0;cursor:pointer}#sq_options_feedback #sq_options_feedback_close,#sq_options_support #sq_options_close{position:absolute;right:8px;top:3px;font-size:13px;font-weight:700;color:#999;width:8px;line-height:16px;padding:0 5px 3px;border-radius:10px;cursor:pointer;z-index:2}#sq_options_feedback .sq_options_feedback_popup li{clear:both}#sq_facebook_b{padding:6px 50px;clear:both;display:table}#sq_facebook_b>span{display:block;float:left;font-weight:700;color:#006400}#sq_facebook_b .sq_facebook_title{width:100%;font-size:16px;text-align:center;margin:5px auto}#sq_facebook_b .sq_facebook_image{width:100px;margin:3px 7px 5px 24px}#sq_facebook_b .sq_facebook_image img{width:100px}#sq_facebook_b .sq_facebook_frame{margin-top:35px}
1
+ @import url(https://fonts.googleapis.com/css?family=Open+Sans);@-ms-keyframes play{0%{background-position:0}to{background-position:-400px}}@-o-keyframes play{0%{background-position:0}to{background-position:-400px}}@keyframes play{0%{background-position:0}to{background-position:-400px}}.sq_minloading{position:relative;opacity:.5}.sq_loading{height:60px;background:url(../img/loading.gif) no-repeat center!important}.sq_minloading:before{position:absolute!important;right:calc(50% - 10px)!important;top:calc(50% - 8px)!important;display:block!important;float:right!important;line-height:30px!important;content:""!important;padding:0!important;margin:0 0 0 5px!important;height:16px!important;width:20px!important;background:url(../img/minloading.png) no-repeat!important;-webkit-animation:play 1s steps(10) infinite;-moz-animation:play 1s steps(10) infinite;-o-animation:play 1s steps(10) infinite;animation:play 1s steps(10) infinite}#sq_preloading{text-align:center;font-size:15px;line-height:24px;color:gray}#postsquirrly{background:0 0;border:0;margin:-20px 0 10px;padding:2px;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}#postsquirrly *,#sq_blocksnippet *{box-sizing:border-box}#postsquirrly.closed .inside{display:block}.sq_push{position:absolute;top:-7px;left:30px;font-size:10px;margin:0;border:1px solid #333;background-color:#8b0000;border-radius:50px;-webkit-border-radius:50px;-moz-border-radius:50px;padding:0 1px;width:14px;text-shadow:1px 1px #333;color:#fff;font-family:'Megalopolis',Arial,Helvetica,sans-serif;text-align:center}#sq_options_dasboard .sq_push{left:36px}#postsquirrly div.inside,#postsquirrly p,#postsquirrly td{margin:0;padding:0}#postsquirrly .handlediv,#postsquirrly .hndle{background:gray;opacity:0;height:1px;line-height:0}#postsquirrly .sq_header{color:#a0a0a0;font-size:14px;font-weight:400;padding:5px 7px;margin:0;line-height:20px;border-bottom:1px dashed #d1d1d1;box-shadow:0 1px 2px -1px #ccc;-moz-box-shadow:0 1px 2px -1px #ccc;-webkit-box-shadow:0 1px 2px -1px #ccc}#postsquirrly .sq_box{background-color:#fcfcfc;margin-bottom:15px;box-shadow:0 1px 2px -1px #444;-moz-box-shadow:0 1px 2px -1px #444;-webkit-box-shadow:0 1px 2px -1px #444}#normal-sortables #postsquirrly .sq_box{max-width:490px;margin:auto}#postsquirrly.sq_sticky{position:fixed!important;z-index:90000!important;right:3px;bottom:0;top:auto;height:136px;width:285px!important;padding:1px!important;background:#fff!important;overflow-x:auto!important;box-shadow:0 0 8px 0 #000!important}#postsquirrly.sq_sticky::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.3);background-color:#f5f5f5}#postsquirrly.sq_sticky::-webkit-scrollbar{width:7px;background-color:#f5f5f5}#postsquirrly.sq_sticky::-webkit-scrollbar-thumb{background-color:#bdafba;border:0}#postsquirrly.sq_sticky .hndle,#postsquirrly.sq_sticky.minimized #sq_briefcase_list,#postsquirrly.sq_sticky.minimized #sq_briefcase_topcontent{display:none!important}#postsquirrly.sq_sticky .sq_header{cursor:move}#postsquirrly .sq_box_close,#postsquirrly .sq_box_maximize,#postsquirrly .sq_box_minimize{display:block;float:right;margin:0;cursor:pointer;font-family:Arial,sans-serif;font-weight:400;font-size:17px;color:gray;padding:0 0 0 10px;height:22px}#postsquirrly.sq_sticky.minimized{height:136px!important;overflow:hidden!important}#postsquirrly .inside{position:relative;height:100%}#postsquirrly .sq_box.sq_sticky{position:fixed;top:32px;z-index:99999;height:100%;max-width:291px;overflow-x:auto}#postsquirrly.sq_sticky .sq_box.sq_sticky{position:absolute;top:0;bottom:0;height:100%;margin:0}#postsquirrly .sq_box.sq_sticky>div{margin-bottom:25px}#postsquirrly .sq_box:before{display:block;content:" ";background:url(../img/sprite.png) repeat-x 0 -360px;width:100%;height:5px;border-radius:2px 2px 0 0;opacity:.3}#postsquirrly .sq_box:hover:before{opacity:.8}#postsquirrly .sq_box:hover .sq_header{color:#444}#sq_blocklogin{background-color:#ffffe0}#sq_blocklogin input,#sq_blocklogin textarea{font-family:Arial,Helvetica,sans-serif;font-size:14px;height:30px;padding:6px}#postsquirrly .sq_button,#sq_blocklogin #sq_login{cursor:pointer;background-color:#589ee4;color:#fff;border:0}#postsquirrly .sq_button{display:block;text-decoration:none;line-height:30px;font-weight:700;margin:0;padding:0 15px;border-radius:0;vertical-align:top}#sq_blocklogin #sq_login{min-width:100px;min-height:35px;border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:10px}#sq_blocklogin label{margin-top:0;margin-right:2px;width:72px;display:inline-block}#sq_blocklogin ul li{position:relative;font-family:"Lucida Grande",Arial,Helvetica,sans-serif;font-size:12px;padding:4px 0 4px 5px;margin:5px 0;line-height:16px;text-shadow:1px 1px #fff;text-align:center}#postsquirrly .sq_button,#sq_blocklogin .sq_info{font-size:13px;text-align:center}#sq_blocklogin .sq_error{font-size:12px;text-align:center;color:red;margin:5px auto}#sq_blocklogin #sq_register{margin:5px 0;font-size:16px;font-weight:700}#sq_blocklogin #sq_register_wait{display:inline-block;margin-left:2px}#sq_blocklogin #sq_autologin{padding:20px 10px 5px}#sq_blocklogin #sq_autologin #sq_loginimage{display:block;background-color:#589ee4;height:auto;width:100px;font-size:15px;color:#fff;font-weight:700;margin:13px;padding:10px 0;text-decoration:none;border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:10px;cursor:pointer}#sq_blocklogin #sq_register_email{text-align:center;width:250px;height:45px;margin:14px auto 11px}#sq_blocklogin #sq_register_email #sq_email{width:160px!important;border:2px solid #589ee4}#sq_blocklogin #sq_signin{color:#11a5c1;margin:5px;cursor:pointer}#sq_options,#sq_options>ul>li{position:relative;float:right;padding:0}#sq_options{height:40px;margin:0;z-index:13}#side-sortables #sq_options{z-index:1003}#postsquirrly #sq_options{float:none;background:0 0;border:0;box-shadow:none}#normal-sortables #postsquirrly #sq_options{display:flex;width:280px;margin:10px auto}#sq_blocksearch ul,#sq_blockseo ul,#sq_options>ul{margin:10px 0;padding:0}#sq_options>ul>li{font-family:"Open Sans",Arial,sans-serif!important;width:102px;color:#444;font-size:14px;margin:0 auto;cursor:pointer}#sq_options li#sq_options_support{margin-left:11px;width:105px}#sq_options_dasboard .sq_text a,#sq_options_support .sq_text{display:block;float:left;font-family:"Open Sans",Arial,sans-serif!important;font-size:12px;color:#333;text-decoration:none;padding:3px 5px;border:1px solid #ccc;border-radius:5px;background:#fff;background:-moz-linear-gradient(top,#fff,#f5f5f5);background:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f5f5f5))}#sq_options .sq_icon{display:block;float:left;background:url(../img/sprite.png) no-repeat;margin:-8px 5px 0 3px}#sq_options>ul>li#sq_options_feedback{width:38px;margin-left:2px}#sq_options_feedback .sq_label_feedback_smiley{display:block;height:37px;width:37px;margin:5px auto;background:url(../img/sprite.png) no-repeat;border:0;cursor:pointer}#sq_options_feedback .sq_feedback_smiley{display:none}#sq_options_feedback .sq_label_feedback_0{background-position:-102px -154px!important}#sq_options_feedback .sq_label_feedback_1{background-position:-148px -154px!important}#sq_options_feedback .sq_label_feedback_2{background-position:-194px -154px!important}#sq_options_feedback .sq_label_feedback_3{background-position:-240px -154px!important}#sq_options_feedback .sq_label_feedback_4{background-position:-284px -154px!important}#sq_options_feedback .sq_icon{height:37px;width:35px;background-position:-194px -154px}#sq_options_support .sq_icon{height:37px;width:30px;background-position:-5px -154px}#sq_options_dasboard .sq_icon{height:39px;width:40px;background-position:-40px -154px}#sq_options_feedback .sq_options_feedback_popup,#sq_options_support .sq_options_support_popup{display:table;min-width:345px;position:absolute;z-index:12;background-color:#fff;padding:5px;margin-top:0;top:33px;border:1px solid #ccc;border-radius:0 7px 7px 7px;-moz-border-radius:0 7px 7px 7px;-webkit-border-radius:0 7px 7px 7px;box-shadow:1px 4px 6px -1px #888;-moz-box-shadow:1px 4px 6px -1px #888;-webkit-box-shadow:1px 4px 6px -1px #888;cursor:default}#side-sortables #sq_options_feedback .sq_options_feedback_popup,#side-sortables #sq_options_support .sq_options_support_popup{z-index:1002}#sq_options_support .sq_options_support_popup{right:0}#sq_options_feedback .sq_options_feedback_popup{left:-101px}#sq_options_feedback table td{text-align:center;color:#999;min-width:50px;height:70px}#sq_options_feedback .sq_options_feedback_popup li,#sq_options_support .sq_options_support_popup li{color:#333;line-height:16px;font-size:13px;font-weight:400;margin:0;padding:3px 5px}#sq_options_feedback #sq_options_feedback_error,#sq_options_support #sq_options_support_error{margin:6px 0}#sq_options_feedback .sq_small_input{width:100%;height:70px}#sq_options_support .sq_small_input{width:100%}#sq_options_feedback .sq_options_feedback_popup #sq_feedback_submit,#sq_options_support .sq_options_support_popup #sq_support_submit{background-color:#589ee4;font-size:12px;font-weight:700;color:#fff;width:100px;margin:10px auto 5px;padding:5px;position:relative;text-shadow:1px 1px #555;border:0;cursor:pointer}#sq_options_feedback #sq_options_feedback_close,#sq_options_support #sq_options_close{position:absolute;right:8px;top:3px;font-size:13px;font-weight:700;color:#999;width:8px;line-height:16px;padding:0 5px 3px;border-radius:10px;cursor:pointer;z-index:2}#sq_options_feedback .sq_options_feedback_popup li{clear:both}#sq_facebook_b{padding:6px 50px;clear:both;display:table}#sq_facebook_b>span{display:block;float:left;font-weight:700;color:#006400}#sq_facebook_b .sq_facebook_title{width:100%;font-size:16px;text-align:center;margin:5px auto}#sq_facebook_b .sq_facebook_image{width:100px;margin:3px 7px 5px 24px}#sq_facebook_b .sq_facebook_image img{width:100px}#sq_facebook_b .sq_facebook_frame{margin-top:35px}