Orphans - Version 2.6.6

Version Description

  • 2017-04-30 =

  • Avoid to replace "script" and "styles" content. Props for @m1nified

  • Added a widget title to replacements.

  • Added a widget text to replacements (it work only for the widget text).

Download this release

Release Info

Developer iworks
Plugin Icon 128x128 Orphans
Version 2.6.6
Comparing to
See all releases

Code changes from version 2.6.5 to 2.6.6

assets/images/logo.png ADDED
Binary file
readme.txt CHANGED
@@ -3,15 +3,14 @@ Contributors: iworks
3
  Donate link: http://iworks.pl/donate/sierotki.php
4
  Tags: sierotka, sierotki, spójniki, twarda spacja
5
  Requires at least: 3.3
6
- Tested up to: 4.7
7
- Stable tag: 2.6.5
8
 
9
  Plugin supports some of the grammatical rules of the Polish language.
10
 
11
  == Description ==
12
 
13
- Plugin fix orphans position and replace space after orphan to hard space, to avoid
14
- line break incorrect position.
15
 
16
  = Asset image =
17
 
@@ -97,6 +96,12 @@ function my_orphans_capability($capability)
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
100
  = 2.6.5 - 2016-11-01 =
101
 
102
  * Rollback to 2.6.3, because 2.6.4 broke images.
3
  Donate link: http://iworks.pl/donate/sierotki.php
4
  Tags: sierotka, sierotki, spójniki, twarda spacja
5
  Requires at least: 3.3
6
+ Tested up to: 4.7.4
7
+ Stable tag: 2.6.6
8
 
9
  Plugin supports some of the grammatical rules of the Polish language.
10
 
11
  == Description ==
12
 
13
+ Plugin fix orphans position and replace space after orphan to hard space, to avoid line break incorrect position.
 
14
 
15
  = Asset image =
16
 
96
 
97
  == Changelog ==
98
 
99
+ = 2.6.6 - 2017-04-30 =
100
+
101
+ * Avoid to replace "script" and "styles" content. Props for @m1nified
102
+ * Added a widget title to replacements.
103
+ * Added a widget text to replacements (it work only for the widget text).
104
+
105
  = 2.6.5 - 2016-11-01 =
106
 
107
  * Rollback to 2.6.3, because 2.6.4 broke images.
sierotki.php CHANGED
@@ -5,11 +5,13 @@ Plugin URI: http://iworks.pl/2011/02/16/sierotki/
5
  Text Domain: sierotki
6
  Description: Implement Polish grammar rules with orphans.
7
  Author: Marcin Pietrzak
8
- Version: 2.6.5
9
  Author URI: http://iworks.pl/
10
  */
11
 
12
  require_once( dirname( __FILE__ ) ).'/vendor/iworks/orphan.php';
 
 
13
  new iworks_orphan();
14
 
15
  register_activation_hook( __FILE__, 'iworks_orphan_activate' );
@@ -22,7 +24,6 @@ register_deactivation_hook( __FILE__, 'iworks_orphan_deactivate' );
22
  *
23
  */
24
  function iworks_orphan_activate() {
25
-
26
  iworks_orphan_change_options_autoload_status( 'yes' );
27
  }
28
 
@@ -33,7 +34,6 @@ function iworks_orphan_activate() {
33
  *
34
  */
35
  function iworks_orphan_deactivate() {
36
-
37
  iworks_orphan_change_options_autoload_status( 'no' );
38
  }
39
  /**
@@ -47,7 +47,6 @@ function iworks_orphan_deactivate() {
47
  *
48
  */
49
  function iworks_orphan_change_options_autoload_status( $status ) {
50
-
51
  if ( ! preg_match( '/^(yes|no)$/', $status ) ) {
52
  return;
53
  }
@@ -76,3 +75,11 @@ function iworks_orphan_change_options_autoload_status( $status ) {
76
  }
77
  }
78
 
 
 
 
 
 
 
 
 
5
  Text Domain: sierotki
6
  Description: Implement Polish grammar rules with orphans.
7
  Author: Marcin Pietrzak
8
+ Version: 2.6.6
9
  Author URI: http://iworks.pl/
10
  */
11
 
12
  require_once( dirname( __FILE__ ) ).'/vendor/iworks/orphan.php';
13
+ include_once( dirname( __FILE__ ) ).'/vendor/iworks/rate/rate.php';
14
+
15
  new iworks_orphan();
16
 
17
  register_activation_hook( __FILE__, 'iworks_orphan_activate' );
24
  *
25
  */
26
  function iworks_orphan_activate() {
 
27
  iworks_orphan_change_options_autoload_status( 'yes' );
28
  }
29
 
34
  *
35
  */
36
  function iworks_orphan_deactivate() {
 
37
  iworks_orphan_change_options_autoload_status( 'no' );
38
  }
39
  /**
47
  *
48
  */
49
  function iworks_orphan_change_options_autoload_status( $status ) {
 
50
  if ( ! preg_match( '/^(yes|no)$/', $status ) ) {
51
  return;
52
  }
75
  }
76
  }
77
 
78
+ do_action(
79
+ 'iworks-register-plugin',
80
+ plugin_basename( __FILE__ ),
81
+ __('Orphans',
82
+ 'sierotki' ),
83
+ __( 'https://wordpress.org/plugins/sierotki/', 'sierotki' )
84
+ );
85
+
vendor/iworks/orphan.php CHANGED
@@ -5,7 +5,6 @@ class iworks_orphan
5
  private $admin_page;
6
 
7
  public function __construct() {
8
-
9
  /**
10
  * l10n
11
  */
@@ -17,6 +16,7 @@ class iworks_orphan
17
  add_action( 'init', array( $this, 'init' ) );
18
  add_action( 'admin_init', array( $this, 'admin_init' ) );
19
  add_action( 'admin_menu', array( $this, 'admin_menu' ) );
 
20
  add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
21
 
22
  /**
@@ -47,6 +47,24 @@ class iworks_orphan
47
  'label' => __( 'Enabled the substitution of orphans in the content.', 'sierotki' ),
48
  'sanitize_callback' => 'absint',
49
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  'woocommerce_product_title' => array(
51
  'description' => __( 'Use for WooCommerce product title:', 'sierotki' ),
52
  'type' => 'checkbox',
@@ -75,7 +93,6 @@ class iworks_orphan
75
  }
76
 
77
  public function replace( $content ) {
78
-
79
  if ( empty( $content ) ) {
80
  return;
81
  }
@@ -208,6 +225,20 @@ class iworks_orphan
208
  'żeby',
209
  'żebyś',
210
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  $own_orphans = trim( get_option( 'iworks_orphan_own_orphans', '' ), ' \t,' );
212
  if ( $own_orphans ) {
213
  $own_orphans = preg_replace( '/\,\+/', ',', $own_orphans );
@@ -234,6 +265,16 @@ class iworks_orphan
234
  */
235
  $content = preg_replace( '/(\d+) (r\.)/', '$1 $2', $content );
236
 
 
 
 
 
 
 
 
 
 
 
237
  /**
238
  * return
239
  */
@@ -241,7 +282,6 @@ class iworks_orphan
241
  }
242
 
243
  public function option_page() {
244
-
245
  ?>
246
  <div class="wrap">
247
  <h2><?php _e( 'Orphans', 'sierotki' ) ?></h2>
@@ -332,7 +372,6 @@ foreach ( $this->options as $filter => $option ) {
332
  }
333
 
334
  public function admin_menu() {
335
-
336
  if ( function_exists( 'add_theme_page' ) ) {
337
  $this->admin_page = add_theme_page(
338
  __( 'Orphans', 'sierotki' ),
@@ -357,7 +396,6 @@ foreach ( $this->options as $filter => $option ) {
357
  }
358
 
359
  public function add_help_tab() {
360
-
361
  $screen = get_current_screen();
362
  if ( $screen->id != $this->admin_page ) {
363
  return;
@@ -381,7 +419,6 @@ foreach ( $this->options as $filter => $option ) {
381
  }
382
 
383
  public function admin_init() {
384
-
385
  foreach ( $this->options as $filter => $option ) {
386
  $sanitize_callback = isset( $option['sanitize_callback'] )? $option['sanitize_callback']:null;
387
  register_setting( 'sierotki', 'iworks_orphan_'.$filter, $sanitize_callback );
@@ -390,7 +427,6 @@ foreach ( $this->options as $filter => $option ) {
390
  }
391
 
392
  public function init() {
393
-
394
  if ( 0 == get_option( 'iworks_orphan_initialized', 0 ) ) {
395
  foreach ( $this->options as $filter => $option ) {
396
  if ( ! isset( $option['type'] ) ) {
@@ -417,7 +453,6 @@ foreach ( $this->options as $filter => $option ) {
417
  }
418
 
419
  public function links( $links, $file ) {
420
-
421
  if ( $file == plugin_basename( __FILE__ ) ) {
422
  if ( ! is_multisite() ) {
423
  $dir = explode( '/', dirname( __FILE__ ) );
@@ -446,4 +481,16 @@ foreach ( $this->options as $filter => $option ) {
446
  }
447
  return sprintf( __( 'If you like <strong>Orphans</strong> please leave us a %s&#9733;&#9733;&#9733;&#9733;&#9733;%s rating. A huge thanks in advance!', 'sierotki' ), '<a href="https://wordpress.org/support/plugin/sierotki/reviews/?rate=5#new-post" target="_blank">', '</a>' );
448
  }
 
 
 
 
 
 
 
 
 
 
 
 
449
  }
5
  private $admin_page;
6
 
7
  public function __construct() {
 
8
  /**
9
  * l10n
10
  */
16
  add_action( 'init', array( $this, 'init' ) );
17
  add_action( 'admin_init', array( $this, 'admin_init' ) );
18
  add_action( 'admin_menu', array( $this, 'admin_menu' ) );
19
+ add_action( 'iworks_rate_css', array( $this, 'iworks_rate_css' ) );
20
  add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
21
 
22
  /**
47
  'label' => __( 'Enabled the substitution of orphans in the content.', 'sierotki' ),
48
  'sanitize_callback' => 'absint',
49
  ),
50
+ /**
51
+ * Since 2.6.6
52
+ */
53
+ 'widget_title' => array(
54
+ 'description' => __( 'Use for widget title:', 'sierotki' ),
55
+ 'type' => 'checkbox',
56
+ 'label' => __( 'Enabled the substitution of orphans in the widget title.', 'sierotki' ),
57
+ 'sanitize_callback' => 'absint',
58
+ ),
59
+ /**
60
+ * Since 2.6.6
61
+ */
62
+ 'widget_text' => array(
63
+ 'description' => __( 'Use for widget text:', 'sierotki' ),
64
+ 'type' => 'checkbox',
65
+ 'label' => __( 'Enabled the substitution of orphans in the widget text.', 'sierotki' ),
66
+ 'sanitize_callback' => 'absint',
67
+ ),
68
  'woocommerce_product_title' => array(
69
  'description' => __( 'Use for WooCommerce product title:', 'sierotki' ),
70
  'type' => 'checkbox',
93
  }
94
 
95
  public function replace( $content ) {
 
96
  if ( empty( $content ) ) {
97
  return;
98
  }
225
  'żeby',
226
  'żebyś',
227
  );
228
+
229
+ preg_match_all( '@(<(script|style)[^>]*>.*?(</(script|style)>))@is', $content, $matches );
230
+ $exceptions = '';
231
+
232
+ if ( ! empty( $matches ) && ! empty( $matches[0] ) ) {
233
+ $salt = 'kQc6T9fn5GhEzTM3Sxn7b9TWMV4PO0mOCV06Da7AQJzSJqxYR4z3qBlsW9rtFsWK';
234
+ foreach ( $matches[0] as $one ) {
235
+ $key = sprintf( '<!-- %s %s -->', $salt, md5( $one ) );
236
+ $exceptions[ $key ] = $one;
237
+ $re = sprintf( '@%s@', preg_replace( '/@/', '\@', $one ) );
238
+ $content = preg_replace( $re, $key, $content );
239
+ }
240
+ }
241
+
242
  $own_orphans = trim( get_option( 'iworks_orphan_own_orphans', '' ), ' \t,' );
243
  if ( $own_orphans ) {
244
  $own_orphans = preg_replace( '/\,\+/', ',', $own_orphans );
265
  */
266
  $content = preg_replace( '/(\d+) (r\.)/', '$1&nbsp;$2', $content );
267
 
268
+ /**
269
+ * bring back styles & scripts
270
+ */
271
+ if ( ! empty( $exceptions ) ) {
272
+ foreach ( $exceptions as $key => $one ) {
273
+ $re = sprintf( '/%s/', $key );
274
+ $content = preg_replace( $key, $one, $content );
275
+ }
276
+ }
277
+
278
  /**
279
  * return
280
  */
282
  }
283
 
284
  public function option_page() {
 
285
  ?>
286
  <div class="wrap">
287
  <h2><?php _e( 'Orphans', 'sierotki' ) ?></h2>
372
  }
373
 
374
  public function admin_menu() {
 
375
  if ( function_exists( 'add_theme_page' ) ) {
376
  $this->admin_page = add_theme_page(
377
  __( 'Orphans', 'sierotki' ),
396
  }
397
 
398
  public function add_help_tab() {
 
399
  $screen = get_current_screen();
400
  if ( $screen->id != $this->admin_page ) {
401
  return;
419
  }
420
 
421
  public function admin_init() {
 
422
  foreach ( $this->options as $filter => $option ) {
423
  $sanitize_callback = isset( $option['sanitize_callback'] )? $option['sanitize_callback']:null;
424
  register_setting( 'sierotki', 'iworks_orphan_'.$filter, $sanitize_callback );
427
  }
428
 
429
  public function init() {
 
430
  if ( 0 == get_option( 'iworks_orphan_initialized', 0 ) ) {
431
  foreach ( $this->options as $filter => $option ) {
432
  if ( ! isset( $option['type'] ) ) {
453
  }
454
 
455
  public function links( $links, $file ) {
 
456
  if ( $file == plugin_basename( __FILE__ ) ) {
457
  if ( ! is_multisite() ) {
458
  $dir = explode( '/', dirname( __FILE__ ) );
481
  }
482
  return sprintf( __( 'If you like <strong>Orphans</strong> please leave us a %s&#9733;&#9733;&#9733;&#9733;&#9733;%s rating. A huge thanks in advance!', 'sierotki' ), '<a href="https://wordpress.org/support/plugin/sierotki/reviews/?rate=5#new-post" target="_blank">', '</a>' );
483
  }
484
+
485
+ /**
486
+ * Change logo for "rate" message.
487
+ *
488
+ * @since 2.6.6
489
+ */
490
+ public function iworks_rate_css() {
491
+ $logo = plugin_dir_url( dirname( dirname( __FILE__ ) ) ).'assets/images/logo.png';
492
+ echo '<style type="text/css">';
493
+ printf( '.iworks-notice-sierotki .iworks-notice-logo{background-color:#fed696;background-image:url(%s);}', esc_url( $logo ) );
494
+ echo '</style>';
495
+ }
496
  }
vendor/iworks/rate/admin.css ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ****************************************************************************
2
+ * NOTIFICATION STYLES
3
+ *
4
+ * The styles are identical with the WPMUDEV dashboard CSS (section 22)
5
+ * Any changes made here should also be made to the dashboard CSS!
6
+ */
7
+
8
+ .wrap .iworks-notice.notice {
9
+ padding: 0;
10
+ margin: 5px 0 10px;
11
+ border: 1px solid #E5E5E5;
12
+ background: #FFF;
13
+ overflow: hidden;
14
+ -webkit-border-radius: 6px;
15
+ border-radius: 6px;
16
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
17
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
18
+ position: relative;
19
+ z-index: 1;
20
+ min-height: 80px;
21
+ display: table; /* The magic ingredient! */
22
+ font: 13px "Open Sans", sans-serif;
23
+ }
24
+ .wrap .iworks-notice.notice.loading:before {
25
+ content: attr(data-message);
26
+ position: absolute;
27
+ left: 0;
28
+ right: 0;
29
+ top: 0;
30
+ bottom: 0;
31
+ background-color: rgba(255, 255, 255, 0.7);
32
+ z-index: 5;
33
+ text-align: center;
34
+ line-height: 80px;
35
+ font-size: 22px;
36
+ font-weight: bold;
37
+ }
38
+ .iworks-notice > div {
39
+ display: table-cell; /* The magic ingredient! */
40
+ vertical-align: middle;
41
+ cursor: default;
42
+ }
43
+ .iworks-notice.notice.loading > div {
44
+ -webkit-filter: blur(2px);
45
+ -moz-filter: blur(2px);
46
+ -o-filter: blur(2px);
47
+ -ms-filter: blur(2px);
48
+ filter: blur(2px);
49
+ }
50
+ .iworks-notice-logo {
51
+ background: #ddd url(iworks-logo.svg) no-repeat 50% 50%;
52
+ background-size: 80%;
53
+ }
54
+ .iworks-notice-logo span {
55
+ display: block;
56
+ width: 80px;
57
+ }
58
+ .iworks-notice-message {
59
+ width: 100%;
60
+ padding: 10px 20px;
61
+ color: #444;
62
+ }
63
+ .iworks-notice-message strong {
64
+ color: #000;
65
+ }
66
+ .iworks-notice-cta {
67
+ border-left: 1px solid #E5E5E5;
68
+ background: #F8F8F8;
69
+ padding: 0 30px;
70
+ position: relative;
71
+ white-space: nowrap;
72
+ }
73
+ .wp-core-ui .iworks-notice-cta button,
74
+ .wp-core-ui .iworks-notice-cta .button-primary:active {
75
+ vertical-align: middle;
76
+ }
77
+ .wp-core-ui .iworks-notice-cta input[type="email"] {
78
+ vertical-align: middle;
79
+ line-height: 20px;
80
+ margin: 0;
81
+ min-width: 50px;
82
+ max-width: 320px;
83
+ text-align: center;
84
+ padding-left: 0;
85
+ padding-right: 0;
86
+ }
87
+ .iworks-notice-dismiss {
88
+ background: transparent;
89
+ border: 0;
90
+ cursor: pointer;
91
+ color: #BBB;
92
+ }
93
+ .iworks-notice-dismiss:hover {
94
+ color: #666;
95
+ }
96
+
97
+ @media only all and (max-width: 1200px) {
98
+ .iworks-notice-dismiss {
99
+ display: block;
100
+ margin: 0 auto;
101
+ line-height: 18px;
102
+ padding-top: 8px;
103
+ padding-bottom: 2px;
104
+ }
105
+ }
106
+
107
+ @media only all and (max-width: 1000px) {
108
+ .wrap .iworks-notice.notice {
109
+ display: block;
110
+ font-size: 13px;
111
+ }
112
+ .iworks-notice > .iworks-notice-logo {
113
+ float: left;
114
+ display: inline-block;
115
+ height: 80px;
116
+ margin: 10px;
117
+ border-radius: 4px;
118
+ }
119
+ .iworks-notice > .iworks-notice-message {
120
+ width: auto;
121
+ display: block;
122
+ padding: 10px;
123
+ min-height: 80px;
124
+ }
125
+ .iworks-notice > .iworks-notice-cta {
126
+ display: block;
127
+ border-top: 1px solid #E5E5E5;
128
+ border-left: 0;
129
+ text-align: center;
130
+ white-space: normal;
131
+ line-height: 30px;
132
+ padding: 10px 20px;
133
+ }
134
+ .wp-core-ui .iworks-notice > .iworks-notice-cta > input[type="email"],
135
+ .iworks-notice > .iworks-notice-cta > button {
136
+ font-size: 14px;
137
+ }
138
+ .iworks-notice > .iworks-notice-cta > .iworks-notice-dismiss {
139
+ display: inline-block;
140
+ float: none;
141
+ line-height: 26px;
142
+ padding-top: 0;
143
+ padding-bottom: 0;
144
+ font-size: 13px;
145
+ }
146
+ }
147
+
148
+ @media only all and (max-width: 500px) {
149
+ .wp-core-ui .iworks-notice > .iworks-notice-cta > input[type="email"],
150
+ .iworks-notice > .iworks-notice-cta > button {
151
+ display: block;
152
+ width: 100% !important;
153
+ max-width: none;
154
+ margin-bottom: 4px;
155
+ font-size: 16px;
156
+ height: 34px;
157
+ }
158
+ .iworks-notice > .iworks-notice-cta > .iworks-notice-dismiss {
159
+ margin-top: 5px;
160
+ font-size: 14px;
161
+ height: 23px;
162
+ }
163
+ }
vendor/iworks/rate/admin.js ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function() {
2
+ var el_notice = jQuery( ".iworks-notice" ),
3
+ type = el_notice.find( "input[name=type]" ).val(),
4
+ plugin_id = el_notice.find( "input[name=plugin_id]" ).val(),
5
+ url_wp = el_notice.find( "input[name=url_wp]" ).val(),
6
+ drip_plugin = el_notice.find( "input[name=drip_plugin]" ).val(),
7
+ inp_email = el_notice.find( "input[name=email]" )
8
+ btn_act = el_notice.find( ".iworks-notice-act" ),
9
+ btn_dismiss = el_notice.find( ".iworks-notice-dismiss" )
10
+ ajax_data = {};
11
+
12
+ ajax_data.plugin_id = plugin_id;
13
+ ajax_data.type = type;
14
+
15
+ function init_email() {
16
+ if ( ! inp_email.length ) { return; }
17
+
18
+ // Adjust the size of the email field to its contents.
19
+ function adjust_email_size() {
20
+ var width, tmp = jQuery( "<span></span>" );
21
+
22
+ tmp.addClass( "input-field" ).text( inp_email.val() );
23
+ tmp.appendTo( "body" );
24
+ width = parseInt( tmp.width() );
25
+ tmp.remove();
26
+
27
+ inp_email.width( width + 34 );
28
+ }
29
+
30
+ function email_keycheck( ev ) {
31
+ if ( 13 === ev.keyCode ) {
32
+ btn_act.click();
33
+ } else {
34
+ adjust_email_size();
35
+ }
36
+ }
37
+
38
+ inp_email.keyup( email_keycheck ).focus().select();
39
+ adjust_email_size();
40
+ }
41
+
42
+ // Display the notice after the page was loaded.
43
+ function initialize() {
44
+ el_notice.fadeIn( 500 );
45
+ init_email();
46
+ }
47
+
48
+ // Hide the notice after a CTA button was clicked
49
+ function remove_notice() {
50
+ el_notice.fadeTo( 100 , 0, function() {
51
+ el_notice.slideUp( 100, function() {
52
+ el_notice.remove();
53
+ });
54
+ });
55
+ }
56
+
57
+ // Open a tab to rate the plugin.
58
+ function act_rate() {
59
+ var url = url_wp.replace( /\/plugins\//, "/support/view/plugin-reviews/" ) + "?rate=5#new-post",
60
+ link = jQuery( '<a href="' + url + '" target="_blank">Rate</a>' );
61
+
62
+ link.appendTo( "body" );
63
+ link[0].click();
64
+ link.remove();
65
+ }
66
+
67
+ // Submit the user to our email list.
68
+ function act_email() {
69
+ var email = inp_email.val();
70
+
71
+ // First create a new subscriber.
72
+ _dcq.push([
73
+ "identify",
74
+ { email: email }
75
+ ]);
76
+
77
+ // Then trigger the specified rule.
78
+ _dcq.push([
79
+ "track",
80
+ "Free plugin email course",
81
+ {"Plugin": drip_plugin}
82
+ ]);
83
+ }
84
+
85
+ // Notify WordPress about the users choice and close the message.
86
+ function notify_wordpress( action, message ) {
87
+ el_notice.attr( "data-message", message );
88
+ el_notice.addClass( "loading" );
89
+
90
+ ajax_data.action = action;
91
+ jQuery.post(
92
+ window.ajaxurl,
93
+ ajax_data,
94
+ remove_notice
95
+ );
96
+ }
97
+
98
+ // Handle click on the primary CTA button.
99
+ // Either open the wp.org page or submit the email address.
100
+ btn_act.click(function( ev ) {
101
+ ev.preventDefault();
102
+
103
+ switch ( type ) {
104
+ case 'rate': act_rate(); break;
105
+ case 'email': act_email(); break;
106
+ }
107
+
108
+ notify_wordpress( "iworks_act", btn_act.data( "msg" ) );
109
+ });
110
+
111
+ // Dismiss the notice without any action.
112
+ btn_dismiss.click(function( ev ) {
113
+ ev.preventDefault();
114
+
115
+ notify_wordpress( "iworks_dismiss", btn_dismiss.data( "msg" ) );
116
+ });
117
+
118
+ window.setTimeout( initialize, 500 );
119
+ });
120
+
121
+ // Drip integration
122
+ var _dcq = _dcq || [];
123
+ var _dcs = _dcs || {};
124
+
125
+ _dcs.account = '6994213';
126
+ var dc = document.createElement( 'script' );
127
+ dc.type = 'text/javascript'; dc.async = true;
128
+ dc.src = '//tag.getdrip.com/6994213.js';
129
+ var s = document.getElementsByTagName('script')[0];
130
+ s.parentNode.insertBefore(dc, s);
131
+ // End of drip integration
vendor/iworks/rate/iworks-logo.svg ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
6
+ xmlns:cc="http://creativecommons.org/ns#"
7
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
+ xmlns:svg="http://www.w3.org/2000/svg"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+ id="svg3248"
13
+ version="1.1"
14
+ inkscape:version="0.48.5 r10040"
15
+ width="500"
16
+ height="500"
17
+ xml:space="preserve"
18
+ sodipodi:docname="iworks-logo.svg"><metadata
19
+ id="metadata3254"><rdf:RDF><cc:Work
20
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
21
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
22
+ id="defs3252"><clipPath
23
+ clipPathUnits="userSpaceOnUse"
24
+ id="clipPath3262"><path
25
+ d="m 0,841.89 595.276,0 L 595.276,0 0,0 0,841.89 z"
26
+ id="path3264"
27
+ inkscape:connector-curvature="0" /></clipPath></defs><sodipodi:namedview
28
+ pagecolor="#ffffff"
29
+ bordercolor="#666666"
30
+ borderopacity="1"
31
+ objecttolerance="10"
32
+ gridtolerance="10"
33
+ guidetolerance="10"
34
+ inkscape:pageopacity="0"
35
+ inkscape:pageshadow="2"
36
+ inkscape:window-width="1920"
37
+ inkscape:window-height="1180"
38
+ id="namedview3250"
39
+ showgrid="false"
40
+ inkscape:zoom="1"
41
+ inkscape:cx="250"
42
+ inkscape:cy="126.17999"
43
+ inkscape:window-x="-3"
44
+ inkscape:window-y="-3"
45
+ inkscape:window-maximized="1"
46
+ inkscape:current-layer="g3256" /><g
47
+ id="g3256"
48
+ inkscape:groupmode="layer"
49
+ inkscape:label="logo-cs3"
50
+ transform="matrix(1.25,0,0,-1.25,0,500.00001)"><path
51
+ inkscape:connector-curvature="0"
52
+ id="path3268"
53
+ style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
54
+ d="m 173.36094,93.52233 c -73.473446,0 -133.118753,59.62718 -133.118753,133.11473 0,25.93002 7.569723,49.93237 20.414886,70.40567 -2.110981,-6.35309 -3.20273,-13.15537 -3.20273,-20.21547 0,-36.39027 29.440945,-65.91783 65.833227,-65.91783 36.354,0 65.86746,29.52756 65.86746,65.91783 0,36.32782 -29.51346,65.84934 -65.86746,65.84934 -7.06011,0 -13.86641,-1.1542 -20.12483,-3.20475 20.37863,12.76862 44.39709,20.27792 70.1982,20.27792 73.47345,0 133.11875,-59.62517 133.11875,-133.11271 0,-73.48755 -59.6453,-133.11473 -133.11875,-133.11473 M 60.403272,113.67737 22.774216,76.06443 C 61.313734,37.555127 114.55358,13.677667 173.36094,13.677667 c 117.58048,0 212.9614,95.376893 212.9614,212.959393 0,58.78923 -23.87343,112.06332 -62.37467,150.57061 l -37.70158,-37.61093 0.0725,-0.0625 c -28.93133,28.94543 -68.85265,46.78806 -112.95767,46.78806 -88.175789,0 -159.683283,-71.49943 -159.683283,-159.68529 0,-44.02848 17.830545,-83.9498 46.725615,-112.83279 l 0,-0.1269 z" /></g></svg>
vendor/iworks/rate/rate.php ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * iWorks_Rate - Dashboard Notification module.
4
+ *
5
+ * @version 1.0.0
6
+ * @author iworks (Marcin Pietrzak)
7
+ * @author Incsub (Philipp Stracker)
8
+ *
9
+ * Based on:
10
+ *
11
+ * WPMUDEV iworks - Free Dashboard Notification module.
12
+ * Used by wordpress.org hosted plugins.
13
+ *
14
+ */
15
+ if ( ! class_exists( 'iworks_rate' ) ) {
16
+ class iworks_rate {
17
+
18
+ /**
19
+ * $wpdb->options field name.
20
+ *
21
+ * @since 1.0.0
22
+ * @var string
23
+ */
24
+ protected $option_name = 'iworks_rate';
25
+
26
+ /**
27
+ * List of all registered plugins.
28
+ *
29
+ * @since 1.0.0
30
+ * @var array
31
+ */
32
+ protected $plugins = array();
33
+
34
+ /**
35
+ * Module options that are stored in database.
36
+ * Timestamps are stored here.
37
+ *
38
+ * Note that this option is stored in site-meta for multisite installs.
39
+ *
40
+ * @since 1.0.0
41
+ * @var array
42
+ */
43
+ protected $stored = array();
44
+
45
+ /**
46
+ * Initializes and returns the singleton instance.
47
+ *
48
+ * @since 1.0.0
49
+ */
50
+ static public function instance() {
51
+ static $Inst = null;
52
+
53
+ if ( null === $Inst ) {
54
+ $Inst = new iworks_rate();
55
+ }
56
+
57
+ return $Inst;
58
+ }
59
+
60
+ /**
61
+ * Set up the iworks_rate module. Private singleton constructor.
62
+ *
63
+ * @since 1.0.0
64
+ */
65
+ private function __construct() {
66
+ $this->read_stored_data();
67
+
68
+ $this->add_action( 'iworks-register-plugin', 5 );
69
+ $this->add_action( 'load-index.php' );
70
+
71
+ $this->add_action( 'wp_ajax_iworks_act' );
72
+ $this->add_action( 'wp_ajax_iworks_dismiss' );
73
+ }
74
+
75
+ /**
76
+ * Load persistent module-data from the WP Database.
77
+ *
78
+ * @since 1.0.0
79
+ */
80
+ protected function read_stored_data() {
81
+ $data = get_site_option( $this->option_name, false, false );
82
+
83
+ if ( ! is_array( $data ) ) {
84
+ $data = array();
85
+ }
86
+
87
+ // A list of all plugins with timestamp of first registration.
88
+ if ( ! isset( $data['plugins'] ) || ! is_array( $data['plugins'] ) ) {
89
+ $data['plugins'] = array();
90
+ }
91
+
92
+ // A list with pending messages and earliest timestamp for display.
93
+ if ( ! isset( $data['queue'] ) || ! is_array( $data['queue'] ) ) {
94
+ $data['queue'] = array();
95
+ }
96
+
97
+ // A list with all messages that were handles already.
98
+ if ( ! isset( $data['done'] ) || ! is_array( $data['done'] ) ) {
99
+ $data['done'] = array();
100
+ }
101
+
102
+ $this->stored = $data;
103
+ }
104
+
105
+ /**
106
+ * Save persistent module-data to the WP database.
107
+ *
108
+ * @since 1.0.0
109
+ */
110
+ protected function store_data() {
111
+ update_site_option( $this->option_name, $this->stored );
112
+ }
113
+
114
+ /**
115
+ * Action handler for 'iworks-register-plugin'
116
+ * Register an active plugin.
117
+ *
118
+ * @since 1.0.0
119
+ * @param string $plugin_id WordPress plugin-ID (see: plugin_basename).
120
+ * @param string $title Plugin name for display.
121
+ * @param string $url_wp URL to the plugin on wp.org (domain not needed)
122
+ * @param string $cta_email Title of the Email CTA button.
123
+ * @param string $drip_plugin Optional. Plugin-param for the getdrip rule.
124
+ */
125
+ public function iworks_register_plugin( $plugin_id, $title, $url_wp, $cta_email = '', $drip_plugin = '' ) {
126
+ // Ignore incorrectly registered plugins to avoid errors later.
127
+ if ( empty( $plugin_id ) ) { return; }
128
+ if ( empty( $title ) ) { return; }
129
+ if ( empty( $url_wp ) ) { return; }
130
+
131
+ if ( false === strpos( $url_wp, '://' ) ) {
132
+ $url_wp = 'https://wordpress.org/' . trim( $url_wp, '/' );
133
+ }
134
+
135
+ $this->plugins[ $plugin_id ] = (object) array(
136
+ 'id' => $plugin_id,
137
+ 'title' => $title,
138
+ 'url_wp' => $url_wp,
139
+ 'cta_email' => $cta_email,
140
+ 'drip_plugin' => $drip_plugin,
141
+ );
142
+
143
+ /*
144
+ * When the plugin is registered the first time we store some infos
145
+ * in the persistent module-data that help us later to find out
146
+ * if/which message should be displayed.
147
+ */
148
+ if ( empty( $this->stored['plugins'][ $plugin_id ] ) ) {
149
+ // First register the plugin permanently.
150
+ $this->stored['plugins'][ $plugin_id ] = time();
151
+
152
+ // Second schedule the messages to display.
153
+ $hash = md5( $plugin_id . '-email' );
154
+ $this->stored['queue'][ $hash ] = array(
155
+ 'plugin' => $plugin_id,
156
+ 'type' => 'email',
157
+ 'show_at' => time(), // Earliest time to display note.
158
+ );
159
+
160
+ $hash = md5( $plugin_id . '-rate' );
161
+ $this->stored['queue'][ $hash ] = array(
162
+ 'plugin' => $plugin_id,
163
+ 'type' => 'rate',
164
+ 'show_at' => time() + 7 * DAY_IN_SECONDS,
165
+ );
166
+
167
+ // Finally save the details.
168
+ $this->store_data();
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Ajax handler called when the user chooses the CTA button.
174
+ *
175
+ * @since 1.0.0
176
+ */
177
+ public function wp_ajax_iworks_act() {
178
+ $plugin = $_POST['plugin_id'];
179
+ $type = $_POST['type'];
180
+
181
+ $this->mark_as_done( $plugin, $type, 'ok' );
182
+
183
+ echo 1;
184
+ exit;
185
+ }
186
+
187
+ /**
188
+ * Ajax handler called when the user chooses the dismiss button.
189
+ *
190
+ * @since 1.0.0
191
+ */
192
+ public function wp_ajax_iworks_dismiss() {
193
+ $plugin = $_POST['plugin_id'];
194
+ $type = $_POST['type'];
195
+
196
+ $this->mark_as_done( $plugin, $type, 'ignore' );
197
+
198
+ echo 1;
199
+ exit;
200
+ }
201
+
202
+ /**
203
+ * Action handler for 'load-index.php'
204
+ * Set-up the Dashboard notification.
205
+ *
206
+ * @since 1.0.0
207
+ */
208
+ public function load_index_php() {
209
+ if ( is_super_admin() ) {
210
+ $this->add_action( 'all_admin_notices' );
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Action handler for 'admin_notices'
216
+ * Display the Dashboard notification.
217
+ *
218
+ * @since 1.0.0
219
+ */
220
+ public function all_admin_notices() {
221
+ $info = $this->choose_message();
222
+ if ( ! $info ) { return; }
223
+
224
+ $this->render_message( $info );
225
+ }
226
+
227
+ /**
228
+ * Check to see if there is a pending message to display and returns
229
+ * the message details if there is.
230
+ *
231
+ * Note that this function is only called on the main Dashboard screen
232
+ * and only when logged in as super-admin.
233
+ *
234
+ * @since 1.0.0
235
+ * @return object|false
236
+ * string $type [rate|email] Which message type?
237
+ * string $plugin WordPress plugin ID?
238
+ */
239
+ protected function choose_message() {
240
+ $obj = false;
241
+ $chosen = false;
242
+ $earliest = false;
243
+
244
+ $now = time();
245
+
246
+ // The "current" time can be changed via $_GET to test the module.
247
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! empty( $_GET['time'] ) ) {
248
+ $custom_time = $_GET['time'];
249
+ if ( ' ' == $custom_time[0] ) { $custom_time[0] = '+'; }
250
+ if ( $custom_time ) { $now = strtotime( $custom_time ); }
251
+ if ( ! $now ) { $now = time(); }
252
+ }
253
+
254
+ $tomorrow = $now + DAY_IN_SECONDS;
255
+
256
+ foreach ( $this->stored['queue'] as $hash => $item ) {
257
+ $show_at = intval( $item['show_at'] );
258
+ $is_sticky = ! empty( $item['sticky'] );
259
+
260
+ if ( ! isset( $this->plugins[ $item['plugin'] ] ) ) {
261
+ // Deactivated plugin before the message was displayed.
262
+ continue;
263
+ }
264
+ $plugin = $this->plugins[ $item['plugin'] ];
265
+
266
+ $can_display = true;
267
+ if ( wp_is_mobile() ) {
268
+ // Do not display rating message on mobile devices.
269
+ if ( 'rate' == $item['type'] ) {
270
+ $can_display = false;
271
+ }
272
+ }
273
+ if ( 'email' == $item['type'] ) {
274
+ if ( ! $plugin->drip_plugin || ! $plugin->cta_email ) {
275
+ // Do not display email message with missing email params.
276
+ $can_display = false;
277
+ }
278
+ }
279
+ if ( $now < $show_at ) {
280
+ // Do not display messages that are not due yet.
281
+ $can_display = false;
282
+ }
283
+
284
+ if ( ! $can_display ) { continue; }
285
+
286
+ if ( $is_sticky ) {
287
+ // If sticky item is present then choose it!
288
+ $chosen = $hash;
289
+ break;
290
+ } elseif ( ! $earliest || $earliest < $show_at ) {
291
+ $earliest = $show_at;
292
+ $chosen = $hash;
293
+ // Don't use `break` because a sticky item might follow...
294
+ // Find the item with the earliest schedule.
295
+ }
296
+ }
297
+
298
+ if ( $chosen ) {
299
+ // Make the chosen item sticky.
300
+ $this->stored['queue'][ $chosen ]['sticky'] = true;
301
+
302
+ // Re-schedule other messages that are due today.
303
+ foreach ( $this->stored['queue'] as $hash => $item ) {
304
+ $show_at = intval( $item['show_at'] );
305
+
306
+ if ( empty( $item['sticky'] ) && $tomorrow > $show_at ) {
307
+ $this->stored['queue'][ $hash ]['show_at'] = $tomorrow;
308
+ }
309
+ }
310
+
311
+ // Save the changes.
312
+ $this->store_data();
313
+
314
+ $obj = (object) $this->stored['queue'][ $chosen ];
315
+ }
316
+
317
+ return $obj;
318
+ }
319
+
320
+ /**
321
+ * Moves a message from the queue to the done list.
322
+ *
323
+ * @since 1.0.0
324
+ * @param string $plugin Plugin ID.
325
+ * @param string $type [rate|email] Message type.
326
+ * @param string $state [ok|ignore] Button clicked.
327
+ */
328
+ protected function mark_as_done( $plugin, $type, $state ) {
329
+ $done_item = false;
330
+
331
+ foreach ( $this->stored['queue'] as $hash => $item ) {
332
+ unset( $this->stored['queue'][ $hash ]['sticky'] );
333
+
334
+ if ( $item['plugin'] == $plugin && $item['type'] == $type ) {
335
+ $done_item = $item;
336
+ unset( $this->stored['queue'][ $hash ] );
337
+ }
338
+ }
339
+
340
+ if ( $done_item ) {
341
+ $done_item['state'] = $state;
342
+ $done_item['hash'] = $hash;
343
+ $done_item['handled_at'] = time();
344
+ unset( $done_item['sticky'] );
345
+
346
+ $this->stored['done'][] = $done_item;
347
+ $this->store_data();
348
+ }
349
+ }
350
+
351
+ /**
352
+ * Renders the actual Notification message.
353
+ *
354
+ * @since 1.0.0
355
+ */
356
+ protected function render_message( $info ) {
357
+ $plugin = $this->plugins[ $info->plugin ];
358
+ $css_url = plugin_dir_url( __FILE__ ) . '/admin.css';
359
+ $js_url = plugin_dir_url( __FILE__ ) . '/admin.js';
360
+
361
+ do_action( 'iworks_rate_css' );
362
+ ?>
363
+ <link rel="stylesheet" type="text/css" href="<?php echo esc_url( $css_url ); ?>" />
364
+ <div class="notice iworks-notice iworks-notice-<?php echo esc_attr( $info->type ); ?> iworks-notice-<?php echo esc_attr( dirname( $info->plugin ) ); ?>" style="display:none">
365
+ <input type="hidden" name="type" value="<?php echo esc_attr( $info->type ); ?>" />
366
+ <input type="hidden" name="plugin_id" value="<?php echo esc_attr( $info->plugin ); ?>" />
367
+ <input type="hidden" name="url_wp" value="<?php echo esc_attr( $plugin->url_wp ); ?>" />
368
+ <input type="hidden" name="drip_plugin" value="<?php echo esc_attr( $plugin->drip_plugin ); ?>" />
369
+ <?php
370
+ $this->render_rate_message( $plugin );
371
+ ?>
372
+ </div>
373
+ <script src="<?php echo esc_url( $js_url ); ?>"></script>
374
+ <?php
375
+ }
376
+
377
+ /**
378
+ * Output the contents of the rate-this-plugin message.
379
+ * No return value. The code is directly output.
380
+ *
381
+ * @since 1.0.0
382
+ */
383
+ protected function render_rate_message( $plugin ) {
384
+ $user = wp_get_current_user();
385
+ $user_name = $user->display_name;
386
+
387
+ $msg = __( "Hey %s, you've been using %s for a while now, and we hope you're happy with it.", 'sierotki' ) . '<br />'. __( "We've spent countless hours developing this free plugin for you, and we would really appreciate it if you dropped us a quick rating!", 'sierotki' );
388
+ $msg = apply_filters( 'iworks-rating-message-' . $plugin->id, $msg );
389
+
390
+ ?>
391
+ <div class="iworks-notice-logo"><span></span></div>
392
+ <div class="iworks-notice-message">
393
+ <?php
394
+ printf(
395
+ $msg,
396
+ '<strong>' . $user_name . '</strong>',
397
+ '<strong>' . $plugin->title . '</strong>'
398
+ );
399
+ ?>
400
+ </div>
401
+ <div class="iworks-notice-cta">
402
+ <button class="iworks-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', 'sierotki' ); ?>">
403
+ <?php
404
+ printf(
405
+ __( 'Rate %s', 'sierotki' ),
406
+ esc_html( $plugin->title )
407
+ ); ?>
408
+ </button>
409
+ <button class="iworks-notice-dismiss" data-msg="<?php _e( 'Saving', 'sierotki' ); ?>">
410
+ <?php _e( 'No thanks', 'sierotki' ); ?>
411
+ </button>
412
+ </div>
413
+ <?php
414
+ }
415
+
416
+ /**
417
+ * Registers a new action handler. The callback function has the same
418
+ * name as the action hook.
419
+ *
420
+ * @since 1.0.0
421
+ */
422
+ protected function add_action( $hook, $params = 1 ) {
423
+ $method_name = strtolower( $hook );
424
+ $method_name = preg_replace( '/[^a-z0-9]/', '_', $method_name );
425
+ $handler = array( $this, $method_name );
426
+ add_action( $hook, $handler, 5, $params );
427
+ }
428
+ }
429
+
430
+ // Initialize the module.
431
+ iworks_rate::instance();
432
+ }