SSH SFTP Updater Support - Version 0.7.4

Version Description

  • 2018/Aug/25 =

  • TWEAK: Update phpseclib to latest version (1.0.10)

  • TWEAK: Replace deprecated constructor for WP_Filesystem_SSH2 class

  • TWEAK: Adds a "Other useful plugins" link on the plugin listing page and 'thank you' notice

Download this release

Release Info

Developer DavidAnderson
Plugin Icon wp plugin SSH SFTP Updater Support
Version 0.7.4
Comparing to
See all releases

Code changes from version 0.7.3 to 0.7.4

class-wp-filesystem-ssh2.php CHANGED
@@ -29,7 +29,7 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
29
  var $errors = array();
30
  var $options = array();
31
 
32
- function WP_Filesystem_SSH2($opt='') {
33
  $this->method = 'ssh2';
34
  $this->errors = new WP_Error();
35
 
@@ -347,4 +347,4 @@ class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
347
  }
348
  return $ret;
349
  }
350
- }
29
  var $errors = array();
30
  var $options = array();
31
 
32
+ public function __construct($opt='') {
33
  $this->method = 'ssh2';
34
  $this->errors = new WP_Error();
35
 
347
  }
348
  return $ret;
349
  }
350
+ }
phpseclib/File/ASN1.php CHANGED
@@ -666,7 +666,7 @@ class File_ASN1
666
  $childClass = $tempClass = FILE_ASN1_CLASS_UNIVERSAL;
667
  $constant = null;
668
  if (isset($temp['constant'])) {
669
- $tempClass = isset($temp['class']) ? $temp['class'] : FILE_ASN1_CLASS_CONTEXT_SPECIFIC;
670
  }
671
  if (isset($child['class'])) {
672
  $childClass = $child['class'];
@@ -729,7 +729,7 @@ class File_ASN1
729
  $temp = $decoded['content'][$i];
730
  $tempClass = FILE_ASN1_CLASS_UNIVERSAL;
731
  if (isset($temp['constant'])) {
732
- $tempClass = isset($temp['class']) ? $temp['class'] : FILE_ASN1_CLASS_CONTEXT_SPECIFIC;
733
  }
734
 
735
  foreach ($mapping['children'] as $key => $child) {
666
  $childClass = $tempClass = FILE_ASN1_CLASS_UNIVERSAL;
667
  $constant = null;
668
  if (isset($temp['constant'])) {
669
+ $tempClass = $temp['type'];
670
  }
671
  if (isset($child['class'])) {
672
  $childClass = $child['class'];
729
  $temp = $decoded['content'][$i];
730
  $tempClass = FILE_ASN1_CLASS_UNIVERSAL;
731
  if (isset($temp['constant'])) {
732
+ $tempClass = $temp['type'];
733
  }
734
 
735
  foreach ($mapping['children'] as $key => $child) {
phpseclib/File/X509.php CHANGED
@@ -320,6 +320,22 @@ class File_X509
320
  */
321
  var $challenge;
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  /**
324
  * Default Constructor.
325
  *
@@ -2144,6 +2160,117 @@ class File_X509
2144
  return true;
2145
  }
2146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2147
  /**
2148
  * Validate a signature
2149
  *
@@ -2160,11 +2287,30 @@ class File_X509
2160
  * @return mixed
2161
  */
2162
  function validateSignature($caonly = true)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2163
  {
2164
  if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
2165
  return null;
2166
  }
2167
 
 
 
 
 
2168
  /* TODO:
2169
  "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
2170
  -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
@@ -2210,10 +2356,10 @@ class File_X509
2210
  }
2211
  }
2212
  if (count($this->CAs) == $i && $caonly) {
2213
- return false;
2214
  }
2215
  } elseif (!isset($signingCert) || $caonly) {
2216
- return false;
2217
  }
2218
  return $this->_validateSignature(
2219
  $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
@@ -2323,6 +2469,41 @@ class File_X509
2323
  return true;
2324
  }
2325
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2326
  /**
2327
  * Reformat public keys
2328
  *
@@ -3517,7 +3698,7 @@ class File_X509
3517
  'tbsCertificate' =>
3518
  array(
3519
  'version' => 'v3',
3520
- 'serialNumber' => $serialNumber, // $this->setserialNumber()
3521
  'signature' => array('algorithm' => $signatureAlgorithm),
3522
  'issuer' => false, // this is going to be overwritten later
3523
  'validity' => array(
320
  */
321
  var $challenge;
322
 
323
+ /**
324
+ * Recursion Limit
325
+ *
326
+ * @var int
327
+ * @access private
328
+ */
329
+ var $recur_limit = 5;
330
+
331
+ /**
332
+ * URL fetch flag
333
+ *
334
+ * @var bool
335
+ * @access private
336
+ */
337
+ var $disable_url_fetch = false;
338
+
339
  /**
340
  * Default Constructor.
341
  *
2160
  return true;
2161
  }
2162
 
2163
+ /**
2164
+ * Fetches a URL
2165
+ *
2166
+ * @param string $url
2167
+ * @access private
2168
+ * @return bool|string
2169
+ */
2170
+ function _fetchURL($url)
2171
+ {
2172
+ if ($this->disable_url_fetch) {
2173
+ return false;
2174
+ }
2175
+
2176
+ $parts = parse_url($url);
2177
+ $data = '';
2178
+ switch ($parts['scheme']) {
2179
+ case 'http':
2180
+ $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80);
2181
+ if (!$fsock) {
2182
+ return false;
2183
+ }
2184
+ fputs($fsock, "GET $parts[path] HTTP/1.0\r\n");
2185
+ fputs($fsock, "Host: $parts[host]\r\n\r\n");
2186
+ $line = fgets($fsock, 1024);
2187
+ if (strlen($line) < 3) {
2188
+ return false;
2189
+ }
2190
+ preg_match('#HTTP/1.\d (\d{3})#', $line, $temp);
2191
+ if ($temp[1] != '200') {
2192
+ return false;
2193
+ }
2194
+
2195
+ // skip the rest of the headers in the http response
2196
+ while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") {
2197
+ }
2198
+
2199
+ while (!feof($fsock)) {
2200
+ $data.= fread($fsock, 1024);
2201
+ }
2202
+
2203
+ break;
2204
+ //case 'ftp':
2205
+ //case 'ldap':
2206
+ //default:
2207
+ }
2208
+
2209
+ return $data;
2210
+ }
2211
+
2212
+ /**
2213
+ * Validates an intermediate cert as identified via authority info access extension
2214
+ *
2215
+ * See https://tools.ietf.org/html/rfc4325 for more info
2216
+ *
2217
+ * @param bool $caonly
2218
+ * @param int $count
2219
+ * @access private
2220
+ * @return bool
2221
+ */
2222
+ function _testForIntermediate($caonly, $count)
2223
+ {
2224
+ $opts = $this->getExtension('id-pe-authorityInfoAccess');
2225
+ if (!is_array($opts)) {
2226
+ return false;
2227
+ }
2228
+ foreach ($opts as $opt) {
2229
+ if ($opt['accessMethod'] == 'id-ad-caIssuers') {
2230
+ // accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP,
2231
+ // etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325
2232
+ // discusses
2233
+ if (isset($opt['accessLocation']['uniformResourceIdentifier'])) {
2234
+ $url = $opt['accessLocation']['uniformResourceIdentifier'];
2235
+ break;
2236
+ }
2237
+ }
2238
+ }
2239
+
2240
+ if (!isset($url)) {
2241
+ return false;
2242
+ }
2243
+
2244
+ $cert = $this->_fetchURL($url);
2245
+ if (!is_string($cert)) {
2246
+ return false;
2247
+ }
2248
+
2249
+ $parent = new static();
2250
+ $parent->CAs = $this->CAs;
2251
+ /*
2252
+ "Conforming applications that support HTTP or FTP for accessing
2253
+ certificates MUST be able to accept .cer files and SHOULD be able
2254
+ to accept .p7c files." -- https://tools.ietf.org/html/rfc4325
2255
+
2256
+ A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797"
2257
+
2258
+ These are currently unsupported
2259
+ */
2260
+ if (!is_array($parent->loadX509($cert))) {
2261
+ return false;
2262
+ }
2263
+
2264
+ if (!$parent->_validateSignatureCountable($caonly, ++$count)) {
2265
+ return false;
2266
+ }
2267
+
2268
+ $this->CAs[] = $parent->currentCert;
2269
+ //$this->loadCA($cert);
2270
+
2271
+ return true;
2272
+ }
2273
+
2274
  /**
2275
  * Validate a signature
2276
  *
2287
  * @return mixed
2288
  */
2289
  function validateSignature($caonly = true)
2290
+ {
2291
+ return $this->_validateSignatureCountable($caonly, 0);
2292
+ }
2293
+
2294
+ /**
2295
+ * Validate a signature
2296
+ *
2297
+ * Performs said validation whilst keeping track of how many times validation method is called
2298
+ *
2299
+ * @param bool $caonly
2300
+ * @param int $count
2301
+ * @access private
2302
+ * @return mixed
2303
+ */
2304
+ function _validateSignatureCountable($caonly, $count)
2305
  {
2306
  if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
2307
  return null;
2308
  }
2309
 
2310
+ if ($count == $this->recur_limit) {
2311
+ return false;
2312
+ }
2313
+
2314
  /* TODO:
2315
  "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
2316
  -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
2356
  }
2357
  }
2358
  if (count($this->CAs) == $i && $caonly) {
2359
+ return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
2360
  }
2361
  } elseif (!isset($signingCert) || $caonly) {
2362
+ return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
2363
  }
2364
  return $this->_validateSignature(
2365
  $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
2469
  return true;
2470
  }
2471
 
2472
+ /**
2473
+ * Sets the recursion limit
2474
+ *
2475
+ * When validating a signature it may be necessary to download intermediate certs from URI's.
2476
+ * An intermediate cert that linked to itself would result in an infinite loop so to prevent
2477
+ * that we set a recursion limit. A negative number means that there is no recursion limit.
2478
+ *
2479
+ * @param int $count
2480
+ * @access public
2481
+ */
2482
+ function setRecurLimit($count)
2483
+ {
2484
+ $this->recur_limit = $count;
2485
+ }
2486
+
2487
+ /**
2488
+ * Prevents URIs from being automatically retrieved
2489
+ *
2490
+ * @access public
2491
+ */
2492
+ function disableURLFetch()
2493
+ {
2494
+ $this->disable_url_fetch = true;
2495
+ }
2496
+
2497
+ /**
2498
+ * Allows URIs to be automatically retrieved
2499
+ *
2500
+ * @access public
2501
+ */
2502
+ function enableURLFetch()
2503
+ {
2504
+ $this->disable_url_fetch = false;
2505
+ }
2506
+
2507
  /**
2508
  * Reformat public keys
2509
  *
3698
  'tbsCertificate' =>
3699
  array(
3700
  'version' => 'v3',
3701
+ 'serialNumber' => $serialNumber, // $this->setSerialNumber()
3702
  'signature' => array('algorithm' => $signatureAlgorithm),
3703
  'issuer' => false, // this is going to be overwritten later
3704
  'validity' => array(
phpseclib/Math/BigInteger.php CHANGED
@@ -550,7 +550,7 @@ class Math_BigInteger
550
  $temp = $comparison < 0 ? $this->add(new Math_BigInteger(1)) : $this->copy();
551
  $bytes = $temp->toBytes();
552
 
553
- if (empty($bytes)) { // eg. if the number we're trying to convert is -1
554
  $bytes = chr(0);
555
  }
556
 
550
  $temp = $comparison < 0 ? $this->add(new Math_BigInteger(1)) : $this->copy();
551
  $bytes = $temp->toBytes();
552
 
553
+ if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1
554
  $bytes = chr(0);
555
  }
556
 
readme.txt CHANGED
@@ -1,68 +1,83 @@
1
- === SSH SFTP Updater Support ===
2
- Contributors: TerraFrost, DavidAnderson
3
- Donate link: http://sourceforge.net/donate/index.php?group_id=198487
4
- Tags: ssh, sftp
5
- Requires at least: 3.1
6
- Tested up to: 4.9
7
- Stable tag: 0.7.3
8
-
9
- "SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
10
-
11
- == Description ==
12
-
13
- Keeping your Wordpress install up-to-date and installing plugins in a hassle-free manner is not so easy if your server uses SFTP. "SSH SFTP Updater Support" for Wordpress uses phpseclib to remedy this deficiency.
14
-
15
- == Installation ==
16
-
17
- 1. Upload the files to the `/wp-content/plugins/ssh-sftp-updater-support` directory
18
- 2. Activate the plugin through the 'Plugins' menu in WordPress
19
-
20
- == Changelog ==
21
-
22
- = 0.7.3 =
23
-
24
- * TWEAK: Update phpseclib to latest version (1.0.10)
25
- * TWEAK: Ship complete phpseclib library so that other plugins using it after we have loaded it don't have problems
26
- * TWEAK: Some minor internal re-factoring
27
- * TWEAK: Adds a dismissable (and won't reappear for 12 months) notice about other plugins users may be interested in.
28
-
29
- = 0.7.2 =
30
- * update phpseclib to latest version
31
-
32
- = 0.7.1 =
33
- * remove deprecated function
34
-
35
- = 0.7.0 =
36
- * disable modal dialog and use full screen real page when prompting for information
37
-
38
- = 0.6.1 =
39
- * fix a few compatibility issues with 4.2
40
-
41
- = 0.6 =
42
- * update phpseclib to latest version
43
- * make plugin work with 4.2's new modal dialog
44
-
45
- = 0.5 =
46
- * update phpseclib to latest version
47
-
48
- = 0.4 =
49
- * fix an E_NOTICE (thanks, runblip!)
50
- * make it so keys that are copy / pasted in are saved with HTML5's localStorage (thanks, kkzk!)
51
- * update phpseclib to latest Git
52
-
53
- = 0.3 =
54
- * update phpseclib to latest SVN
55
- * read file when FTP_PRIKEY is defined (thanks, lkraav!)
56
-
57
- = 0.2 =
58
- * recursive deletes weren't working correctly (directories never got deleted - just files)
59
- * use SFTP for recursive chmod instead of SSH / exec
60
- * fix plugin for people using custom WP_CONTENT_DIR values (thanks, dd32!)
61
- * plugin prevented non-SFTP install methods from being used
62
- * make it so private keys can be uploaded in addition to being copy / pasted
63
-
64
- = 0.1 =
65
- * Initial Release
66
-
67
- == Upgrade Notice ==
68
- * 1.14.4: Update phpseclib to latest version (1.0.10)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === SSH SFTP Updater Support ===
2
+ Contributors: DavidAnderson, TerraFrost, pmbaldha
3
+ Donate link: http://sourceforge.net/donate/index.php?group_id=198487
4
+ Tags: ssh, sftp
5
+ Requires at least: 3.1
6
+ Tested up to: 4.9
7
+ Stable tag: 0.7.4
8
+
9
+ "SSH SFTP Updater Support" is the easiest way to keep your Wordpress installation up-to-date with SFTP.
10
+
11
+ == Description ==
12
+
13
+ Keeping your Wordpress install up-to-date and installing plugins in a hassle-free manner is not so easy if your server uses SFTP. "SSH SFTP Updater Support" for Wordpress uses phpseclib to remedy this deficiency.
14
+
15
+ This plugin is offered and maintained as a free service to the WP community. You might also be interested in enhancing your WordPress site with our other top plugins, below.
16
+
17
+ * **[UpdraftPlus](https://updraftplus.com/?ref=212&source=sshsmtp)** simplifies backups and restoration. It is the #1 most-used backup/restore plugin, with over a million currently-active installs.
18
+ * **[UpdraftCentral](https://updraftplus.com/updraftcentral/?ref=212&source=sshsmtp)** - a highly efficient way to manage, optimize, update and backup multiple websites from one place.
19
+ * **[WP-Optimize](https://getwpo.com/)** helps you to optimize and clean your WordPress database so that it runs at maximum efficiency.
20
+ * **[Keyy](https://getkeyy.com/)**: Simple and secure logins with a wave of your phone.
21
+ * **[MetaSlider](https://www.metaslider.com)**: Easily create beautifully-designed sliders with the #1-most installed WP slider plugin.
22
+ * **More quality plugins**: **[Premium WooCommerce extensions](https://www.simbahosting.co.uk/s3/shop/)** | **[Other useful plugins](https://profiles.wordpress.org/davidanderson#content-plugins)**
23
+
24
+ == Installation ==
25
+
26
+ 1. Upload the files to the `/wp-content/plugins/ssh-sftp-updater-support` directory
27
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
28
+
29
+ == Changelog ==
30
+
31
+ = 0.7.4 - 2018/Aug/25 =
32
+
33
+ * TWEAK: Update phpseclib to latest version (1.0.10)
34
+ * TWEAK: Replace deprecated constructor for WP_Filesystem_SSH2 class
35
+ * TWEAK: Adds a "Other useful plugins" link on the plugin listing page and 'thank you' notice
36
+
37
+ = 0.7.3 =
38
+
39
+ * TWEAK: Update phpseclib to latest version (1.0.10)
40
+ * TWEAK: Ship complete phpseclib library so that other plugins using it after we have loaded it don't have problems
41
+ * TWEAK: Some minor internal re-factoring
42
+ * TWEAK: Adds a dismissable (and won't reappear for 12 months) notice about other plugins users may be interested in.
43
+
44
+ = 0.7.2 =
45
+ * update phpseclib to latest version
46
+
47
+ = 0.7.1 =
48
+ * remove deprecated function
49
+
50
+ = 0.7.0 =
51
+ * disable modal dialog and use full screen real page when prompting for information
52
+
53
+ = 0.6.1 =
54
+ * fix a few compatibility issues with 4.2
55
+
56
+ = 0.6 =
57
+ * update phpseclib to latest version
58
+ * make plugin work with 4.2's new modal dialog
59
+
60
+ = 0.5 =
61
+ * update phpseclib to latest version
62
+
63
+ = 0.4 =
64
+ * fix an E_NOTICE (thanks, runblip!)
65
+ * make it so keys that are copy / pasted in are saved with HTML5's localStorage (thanks, kkzk!)
66
+ * update phpseclib to latest Git
67
+
68
+ = 0.3 =
69
+ * update phpseclib to latest SVN
70
+ * read file when FTP_PRIKEY is defined (thanks, lkraav!)
71
+
72
+ = 0.2 =
73
+ * recursive deletes weren't working correctly (directories never got deleted - just files)
74
+ * use SFTP for recursive chmod instead of SSH / exec
75
+ * fix plugin for people using custom WP_CONTENT_DIR values (thanks, dd32!)
76
+ * plugin prevented non-SFTP install methods from being used
77
+ * make it so private keys can be uploaded in addition to being copy / pasted
78
+
79
+ = 0.1 =
80
+ * Initial Release
81
+
82
+ == Upgrade Notice ==
83
+ * 0.7.4: Update phpseclib to latest version (1.0.11), and prevent deprecation notice
sftp.php CHANGED
@@ -3,15 +3,16 @@
3
  Plugin Name: SSH SFTP Updater Support
4
  Plugin URI: https://wordpress.org/plugins/ssh-sftp-updater-support/
5
  Description: Update your WordPress blog / plugins via SFTP without libssh2
6
- Version: 0.7.3
7
- Author: TerraFrost
8
- Author URI: http://phpseclib.sourceforge.net/
9
  */
10
 
11
  if (!defined('ABSPATH')) die('No direct access allowed');
12
 
13
  define('SSH_SFTP_UPDATER_SUPPORT_MAIN_PATH', plugin_dir_path(__FILE__));
14
- define('SSH_SFTP_UPDATER_SUPPORT_VERSION', '0.7.3');
 
15
  define('SSH_SFTP_UPDATER_SUPPORT_URL', plugin_dir_url(__FILE__));
16
  // see http://adambrown.info/p/wp_hooks/hook/<filter name>
17
  add_filter('filesystem_method', 'phpseclib_filesystem_method', 10, 2); // since 2.6 - WordPress will ignore the ssh option if the php ssh extension is not loaded
@@ -276,6 +277,7 @@ class SSH_SFTP_Updater_Support {
276
  add_action('plugins_loaded', array($this, 'plugins_loaded'), 1);
277
  add_action('admin_init', array($this, 'admin_init'));
278
  add_action('wp_ajax_ssh_sftp_updater_support_ajax', array($this, 'ssh_sftp_updater_support_ajax_handler'));
 
279
  }
280
 
281
  public static function instance() {
@@ -519,6 +521,20 @@ class SSH_SFTP_Updater_Support {
519
  if ($return_instead_of_echo) return $result;
520
  echo $result;
521
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522
  }
523
 
524
  function SSH_SFTP_Updater_Support() {
3
  Plugin Name: SSH SFTP Updater Support
4
  Plugin URI: https://wordpress.org/plugins/ssh-sftp-updater-support/
5
  Description: Update your WordPress blog / plugins via SFTP without libssh2
6
+ Version: 0.7.4
7
+ Author: TerraFrost, David Anderson + Team Updraft
8
+ Author URI: https://updraftplus.com/
9
  */
10
 
11
  if (!defined('ABSPATH')) die('No direct access allowed');
12
 
13
  define('SSH_SFTP_UPDATER_SUPPORT_MAIN_PATH', plugin_dir_path(__FILE__));
14
+ define('SSH_SFTP_UPDATER_SUPPORT_BASENAME', plugin_basename(__FILE__));
15
+ define('SSH_SFTP_UPDATER_SUPPORT_VERSION', '0.7.4');
16
  define('SSH_SFTP_UPDATER_SUPPORT_URL', plugin_dir_url(__FILE__));
17
  // see http://adambrown.info/p/wp_hooks/hook/<filter name>
18
  add_filter('filesystem_method', 'phpseclib_filesystem_method', 10, 2); // since 2.6 - WordPress will ignore the ssh option if the php ssh extension is not loaded
277
  add_action('plugins_loaded', array($this, 'plugins_loaded'), 1);
278
  add_action('admin_init', array($this, 'admin_init'));
279
  add_action('wp_ajax_ssh_sftp_updater_support_ajax', array($this, 'ssh_sftp_updater_support_ajax_handler'));
280
+ add_filter('plugin_row_meta', array($this, 'plugin_row_meta'), 10, 2);
281
  }
282
 
283
  public static function instance() {
521
  if ($return_instead_of_echo) return $result;
522
  echo $result;
523
  }
524
+
525
+ /**
526
+ * Add a "Other useful plugins" link in the links in the line for the plugin in the 'Plugin' page
527
+ *
528
+ * @param array $plugin_meta An array of the plugin's metadata
529
+ * @param string $plugin_file Path to the plugin file, relative to the plugins directory
530
+ * @return array $links An array of plugin action links
531
+ */
532
+ public function plugin_row_meta($plugin_meta_links, $plugin_file) {
533
+ if (SSH_SFTP_UPDATER_SUPPORT_BASENAME == $plugin_file) {
534
+ $plugin_meta_links[] = '<a href="https://profiles.wordpress.org/davidanderson#content-plugins">'.__('Other useful plugins', 'ssh-sftp-updater-support').'</a>';
535
+ }
536
+ return $plugin_meta_links;
537
+ }
538
  }
539
 
540
  function SSH_SFTP_Updater_Support() {
templates/notices/thanks-for-using-main-dash.php CHANGED
@@ -7,30 +7,31 @@
7
  <h3><?php _e("Thank you for installing 'SSH SFTP Updater Support' !", 'ssh-sftp-updater-support'); ?></h3>
8
  <div id="ssh-sftp-updater-support-dashnotice-wrapper">
9
  <p>
10
- <?php echo htmlspecialchars(__("This plugin is offered and maintained as a free service to the WP community. You might also be interested in enhancing your WordPress site with our other top plugins, below. If not, then sorry to trouble you; please use the 'Dismiss' link above and right.", 'ssh-sftp-updater-support')); ?>
11
  </p>
12
  <p>
13
- <?php printf(__('%s simplifies backups and restoration. It is the #1 most-used backup/restore plugin, with over a million currently-active installs.', 'ssh-sftp-updater-support'), '<strong>'.$ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://updraftplus.com/', 'UpdraftPlus', '', '', true).'</strong>'); ?>
14
  </p>
15
 
16
  <p>
17
- <?php printf(__('%s - a highly efficient way to manage, optimize, update and backup multiple websites from one place.', 'ssh-sftp-updater-support'), '<strong>'.$ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://updraftplus.com/updraftcentral/', 'UpdraftCentral', '', '', true).'</strong>'); ?>
18
  </p>
19
 
20
  <p>
21
- <?php printf(__('%s helps you to optimize and clean your WordPress database so that it runs at maximum efficiency.', 'ssh-sftp-updater-support'), '<strong>'.$ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://getwpo.com/', __('WP-Optimize', 'ssh-sftp-updater-support'), '', '', true).'</strong>'); ?>
22
  </p>
23
 
24
  <p>
25
- <strong><?php $ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://getkeyy.com/', __('Keyy:', 'ssh-sftp-updater-support')); ?></strong> <?php echo htmlspecialchars(__('Simple and secure logins with a wave of your phone.', 'ssh-sftp-updater-support')); ?>
26
  </p>
27
 
28
  <p>
29
- <strong><?php $ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://www.metaslider.com', 'MetaSlider');?>: </strong> <?php echo __('Easily create beautifully-designed sliders with the #1-most installed WP slider plugin.', 'ssh-sftp-updater-support'); ?>
30
  </p>
31
 
32
  <p>
33
- <strong><?php $ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://www.simbahosting.co.uk/s3/shop/', __('Premium WooCommerce extensions', 'ssh-sftp-updater-support')); ?></strong>
 
34
  </p>
35
 
36
  </div>
7
  <h3><?php _e("Thank you for installing 'SSH SFTP Updater Support' !", 'ssh-sftp-updater-support'); ?></h3>
8
  <div id="ssh-sftp-updater-support-dashnotice-wrapper">
9
  <p>
10
+ <?php echo __("This plugin is offered and maintained as a free service to the WP community. You might also be interested in enhancing your WordPress site with our other top plugins, below. If not, then sorry to trouble you; please use the 'Dismiss' link above and right.", 'ssh-sftp-updater-support'); ?>
11
  </p>
12
  <p>
13
+ <?php printf(__('%s simplifies backups and restoration. It is the #1 most-used backup/restore plugin, with over a million currently-active installs.', 'ssh-sftp-updater-support'), '<strong>'.$ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://updraftplus.com/', 'UpdraftPlus').': </strong>'); ?>
14
  </p>
15
 
16
  <p>
17
+ <?php printf(__('%s a highly efficient way to manage, optimize, update and backup multiple websites from one place.', 'ssh-sftp-updater-support'), '<strong>'.$ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://updraftplus.com/updraftcentral/', 'UpdraftCentral').': </strong>'); ?>
18
  </p>
19
 
20
  <p>
21
+ <?php printf(__('%s helps you to optimize and clean your WordPress database so that it runs at maximum efficiency.', 'ssh-sftp-updater-support'), '<strong>'.$ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://getwpo.com/', 'WP-Optimize').': </strong>'); ?>
22
  </p>
23
 
24
  <p>
25
+ <?php printf(__('%s Simple and secure logins with a wave of your phone.', 'ssh-sftp-updater-support'), '<strong>'.$ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://getkeyy.com/', 'Keyy').': </strong>'); ?>
26
  </p>
27
 
28
  <p>
29
+ <?php printf(__('%s Easily create beautifully-designed sliders with the #1-most installed WP slider plugin.', 'ssh-sftp-updater-support'), '<strong>'.$ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://www.metaslider.com', 'MetaSlider').': </strong>'); ?>
30
  </p>
31
 
32
  <p>
33
+ <?php '<strong>'.__('More quality plugins', 'ssh-sftp-updater-support').': </strong>';?>
34
+ <strong><?php $ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://www.simbahosting.co.uk/s3/shop/', __('Premium WooCommerce extensions', 'ssh-sftp-updater-support')); ?></strong> | <strong><?php $ssh_sftp_updater_support->ssh_sftp_updater_support_url('https://profiles.wordpress.org/davidanderson#content-plugins', __('Other useful plugins', 'ssh-sftp-updater-support')); ?></a></strong>
35
  </p>
36
 
37
  </div>