Version Description
- Custom URI editor in "Quick Edit"
- "Quick/Bulk Edit" hotfix
- New permastrutcure tag %category_custom_uri%
Download this release
Release Info
Developer | mbis |
Plugin | Permalink Manager Lite |
Version | 2.0.3 |
Comparing to | |
See all releases |
Code changes from version 2.0.4 to 2.0.3
- README.txt +2 -8
- includes/core/permalink-manager-admin-functions.php +7 -1
- includes/core/permalink-manager-core-functions.php +4 -5
- includes/core/permalink-manager-pro-functions.php +0 -220
- includes/core/permalink-manager-uri-functions-post.php +7 -1
- includes/core/permalink-manager-uri-functions-tax.php +0 -527
- includes/ext/plugin-update-checker/Puc/v4/Factory.php +0 -271
- includes/ext/plugin-update-checker/Puc/v4p1/Autoloader.php +0 -49
- includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/Extension.php +0 -117
- includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/Panel.php +0 -165
- includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/PluginExtension.php +0 -33
- includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/PluginPanel.php +0 -38
- includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/ThemePanel.php +0 -21
- includes/ext/plugin-update-checker/Puc/v4p1/Metadata.php +0 -132
- includes/ext/plugin-update-checker/Puc/v4p1/OAuthSignature.php +0 -88
- includes/ext/plugin-update-checker/Puc/v4p1/Plugin/Info.php +0 -127
- includes/ext/plugin-update-checker/Puc/v4p1/Plugin/Update.php +0 -91
- includes/ext/plugin-update-checker/Puc/v4p1/Plugin/UpdateChecker.php +0 -546
- includes/ext/plugin-update-checker/Puc/v4p1/Scheduler.php +0 -177
- includes/ext/plugin-update-checker/Puc/v4p1/StateStore.php +0 -207
- includes/ext/plugin-update-checker/Puc/v4p1/Theme/Update.php +0 -84
- includes/ext/plugin-update-checker/Puc/v4p1/Theme/UpdateChecker.php +0 -167
- includes/ext/plugin-update-checker/Puc/v4p1/Update.php +0 -34
- includes/ext/plugin-update-checker/Puc/v4p1/UpdateChecker.php +0 -825
- includes/ext/plugin-update-checker/Puc/v4p1/UpgraderStatus.php +0 -199
- includes/ext/plugin-update-checker/Puc/v4p1/Utils.php +0 -77
- includes/ext/plugin-update-checker/Puc/v4p1/Vcs/Api.php +0 -243
- includes/ext/plugin-update-checker/Puc/v4p1/Vcs/BaseChecker.php +0 -22
- includes/ext/plugin-update-checker/Puc/v4p1/Vcs/BitBucketApi.php +0 -251
- includes/ext/plugin-update-checker/Puc/v4p1/Vcs/GitHubApi.php +0 -289
- includes/ext/plugin-update-checker/Puc/v4p1/Vcs/PluginUpdateChecker.php +0 -198
- includes/ext/plugin-update-checker/Puc/v4p1/Vcs/Reference.php +0 -49
- includes/ext/plugin-update-checker/Puc/v4p1/Vcs/ThemeUpdateChecker.php +0 -101
- includes/ext/plugin-update-checker/plugin-update-checker.php +0 -22
- includes/ext/stopwords-json/README.md +0 -77
- includes/ext/stopwords-json/dist/af.json +0 -1
- includes/ext/stopwords-json/dist/ar.json +0 -1
- includes/ext/stopwords-json/dist/bg.json +0 -1
- includes/ext/stopwords-json/dist/bn.json +0 -1
- includes/ext/stopwords-json/dist/br.json +0 -1
- includes/ext/stopwords-json/dist/ca.json +0 -1
- includes/ext/stopwords-json/dist/cs.json +0 -1
- includes/ext/stopwords-json/dist/da.json +0 -1
- includes/ext/stopwords-json/dist/de.json +0 -1
- includes/ext/stopwords-json/dist/el.json +0 -1
- includes/ext/stopwords-json/dist/en.json +0 -1
- includes/ext/stopwords-json/dist/eo.json +0 -1
- includes/ext/stopwords-json/dist/es.json +0 -1
- includes/ext/stopwords-json/dist/et.json +0 -1
- includes/ext/stopwords-json/dist/eu.json +0 -1
- includes/ext/stopwords-json/dist/fa.json +0 -1
- includes/ext/stopwords-json/dist/fi.json +0 -1
- includes/ext/stopwords-json/dist/fr.json +0 -1
- includes/ext/stopwords-json/dist/ga.json +0 -1
- includes/ext/stopwords-json/dist/gl.json +0 -1
- includes/ext/stopwords-json/dist/ha.json +0 -1
- includes/ext/stopwords-json/dist/he.json +0 -1
- includes/ext/stopwords-json/dist/hi.json +0 -1
- includes/ext/stopwords-json/dist/hr.json +0 -1
- includes/ext/stopwords-json/dist/hu.json +0 -1
- includes/ext/stopwords-json/dist/hy.json +0 -1
- includes/ext/stopwords-json/dist/id.json +0 -1
- includes/ext/stopwords-json/dist/it.json +0 -1
- includes/ext/stopwords-json/dist/ja.json +0 -1
- includes/ext/stopwords-json/dist/ko.json +0 -1
- includes/ext/stopwords-json/dist/la.json +0 -1
- includes/ext/stopwords-json/dist/lv.json +0 -1
- includes/ext/stopwords-json/dist/mr.json +0 -1
- includes/ext/stopwords-json/dist/nl.json +0 -1
- includes/ext/stopwords-json/dist/no.json +0 -1
- includes/ext/stopwords-json/dist/pl.json +0 -1
- includes/ext/stopwords-json/dist/pt.json +0 -1
- includes/ext/stopwords-json/dist/ro.json +0 -1
- includes/ext/stopwords-json/dist/ru.json +0 -1
- includes/ext/stopwords-json/dist/sk.json +0 -1
- includes/ext/stopwords-json/dist/sl.json +0 -1
- includes/ext/stopwords-json/dist/so.json +0 -1
- includes/ext/stopwords-json/dist/st.json +0 -1
- includes/ext/stopwords-json/dist/sv.json +0 -1
- includes/ext/stopwords-json/dist/sw.json +0 -1
- includes/ext/stopwords-json/dist/th.json +0 -1
- includes/ext/stopwords-json/dist/tr.json +0 -1
- includes/ext/stopwords-json/dist/yo.json +0 -1
- includes/ext/stopwords-json/dist/zh.json +0 -1
- includes/ext/stopwords-json/dist/zu.json +0 -1
- includes/views/permalink-manager-pro-addons.php +0 -285
- includes/views/permalink-manager-settings.php +1 -6
- includes/views/permalink-manager-uri-editor-tax.php +0 -188
- permalink-manager.php +4 -5
README.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
=== Permalink Manager ===
|
2 |
Contributors: mbis
|
3 |
Donate link: https://www.paypal.me/Bismit
|
4 |
License: GPLv3
|
@@ -6,7 +6,7 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
|
6 |
Tags: urls, permalinks, slugs, custom url, custom permalinks, uris, url, slug, permalink
|
7 |
Requires at least: 4.0
|
8 |
Tested up to: 4.8
|
9 |
-
Stable tag: 2.0.
|
10 |
|
11 |
Most advanced yet easy-to-use permalink plugin that helps to maintain & bulk change your URLs & slugs.
|
12 |
|
@@ -97,12 +97,6 @@ A. Currently there is no 100% guarantee that Permalink Manager will work correct
|
|
97 |
|
98 |
== Changelog ==
|
99 |
|
100 |
-
= 2.0.4 =
|
101 |
-
* New settings field - "Deep detect"
|
102 |
-
|
103 |
-
= 2.0.3.1 =
|
104 |
-
* Fix for Custom Fields tag in permastructures
|
105 |
-
|
106 |
= 2.0.3 =
|
107 |
* Custom URI editor in "Quick Edit"
|
108 |
* "Quick/Bulk Edit" hotfix
|
1 |
+
=== Permalink Manager Lite ===
|
2 |
Contributors: mbis
|
3 |
Donate link: https://www.paypal.me/Bismit
|
4 |
License: GPLv3
|
6 |
Tags: urls, permalinks, slugs, custom url, custom permalinks, uris, url, slug, permalink
|
7 |
Requires at least: 4.0
|
8 |
Tested up to: 4.8
|
9 |
+
Stable tag: 2.0.3
|
10 |
|
11 |
Most advanced yet easy-to-use permalink plugin that helps to maintain & bulk change your URLs & slugs.
|
12 |
|
97 |
|
98 |
== Changelog ==
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
= 2.0.3 =
|
101 |
* Custom URI editor in "Quick Edit"
|
102 |
* "Quick/Bulk Edit" hotfix
|
includes/core/permalink-manager-admin-functions.php
CHANGED
@@ -547,6 +547,9 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
|
|
547 |
|
548 |
$html .= "</fieldset>";
|
549 |
|
|
|
|
|
|
|
550 |
return $html;
|
551 |
}
|
552 |
|
@@ -623,6 +626,9 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
|
|
623 |
$html .= "</div>";
|
624 |
$html .= "</div>";
|
625 |
|
|
|
|
|
|
|
626 |
return $html;
|
627 |
}
|
628 |
|
@@ -655,7 +661,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
|
|
655 |
/**
|
656 |
* Hide "Custom URI" column
|
657 |
*/
|
658 |
-
function quick_edit_hide_column($hidden, $screen) {
|
659 |
$hidden[] = 'permalink-manager-col';
|
660 |
return $hidden;
|
661 |
}
|
547 |
|
548 |
$html .= "</fieldset>";
|
549 |
|
550 |
+
// Append nonce field
|
551 |
+
$html .= wp_nonce_field( 'permalink-manager-edit-uri-box', 'permalink-manager-nonce', true, false );
|
552 |
+
|
553 |
return $html;
|
554 |
}
|
555 |
|
626 |
$html .= "</div>";
|
627 |
$html .= "</div>";
|
628 |
|
629 |
+
// 9. Append nonce field
|
630 |
+
$html .= wp_nonce_field( 'permalink-manager-edit-uri-box', 'permalink-manager-nonce', true, false );
|
631 |
+
|
632 |
return $html;
|
633 |
}
|
634 |
|
661 |
/**
|
662 |
* Hide "Custom URI" column
|
663 |
*/
|
664 |
+
function quick_edit_hide_column($hidden, $screen) {
|
665 |
$hidden[] = 'permalink-manager-col';
|
666 |
return $hidden;
|
667 |
}
|
includes/core/permalink-manager-core-functions.php
CHANGED
@@ -20,7 +20,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
|
|
20 |
|
21 |
// Redirects
|
22 |
add_filter( 'redirect_canonical', array($this, 'fix_canonical_redirect'), 9, 2);
|
23 |
-
add_action( 'template_redirect', array($this, 'redirect_to_new_uri'),
|
24 |
add_action( 'parse_request', array($this, 'disable_canonical_redirect'), 0, 1);
|
25 |
|
26 |
// Case insensitive permalinks
|
@@ -100,9 +100,8 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
|
|
100 |
$item_id = (empty($item_id)) ? array_search("{$uri}.html", $permalink_manager_uris) : $item_id;
|
101 |
|
102 |
// Check again in case someone used post/tax IDs instead of slugs
|
103 |
-
$deep_detect_enabled = apply_filters('permalink-manager-deep-uri-detect',
|
104 |
if($deep_detect_enabled && isset($old_query['page'])) {
|
105 |
-
|
106 |
$new_item_id = array_search("{$uri}/{$endpoint_value}", $permalink_manager_uris);
|
107 |
if($new_item_id) {
|
108 |
$item_id = $new_item_id;
|
@@ -256,8 +255,8 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
|
|
256 |
function redirect_to_new_uri() {
|
257 |
global $wp_query, $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_options, $wp;
|
258 |
|
259 |
-
// Do not redirect on author pages
|
260 |
-
if(is_author()
|
261 |
|
262 |
// Sometimes $wp_query indicates the wrong object if requested directly
|
263 |
$queried_object = get_queried_object();
|
20 |
|
21 |
// Redirects
|
22 |
add_filter( 'redirect_canonical', array($this, 'fix_canonical_redirect'), 9, 2);
|
23 |
+
add_action( 'template_redirect', array($this, 'redirect_to_new_uri'), 999);
|
24 |
add_action( 'parse_request', array($this, 'disable_canonical_redirect'), 0, 1);
|
25 |
|
26 |
// Case insensitive permalinks
|
100 |
$item_id = (empty($item_id)) ? array_search("{$uri}.html", $permalink_manager_uris) : $item_id;
|
101 |
|
102 |
// Check again in case someone used post/tax IDs instead of slugs
|
103 |
+
$deep_detect_enabled = apply_filters('permalink-manager-deep-uri-detect', false);
|
104 |
if($deep_detect_enabled && isset($old_query['page'])) {
|
|
|
105 |
$new_item_id = array_search("{$uri}/{$endpoint_value}", $permalink_manager_uris);
|
106 |
if($new_item_id) {
|
107 |
$item_id = $new_item_id;
|
255 |
function redirect_to_new_uri() {
|
256 |
global $wp_query, $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_options, $wp;
|
257 |
|
258 |
+
// Do not redirect on author pages
|
259 |
+
if(is_author()) { return false; }
|
260 |
|
261 |
// Sometimes $wp_query indicates the wrong object if requested directly
|
262 |
$queried_object = get_queried_object();
|
includes/core/permalink-manager-pro-functions.php
DELETED
@@ -1,220 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Additional hooks for "Permalink Manager Pro"
|
5 |
-
*/
|
6 |
-
class Permalink_Manager_Pro_Functions extends Permalink_Manager_Class {
|
7 |
-
|
8 |
-
public function __construct() {
|
9 |
-
define( 'PERMALINK_MANAGER_PRO', true );
|
10 |
-
|
11 |
-
// Stop words
|
12 |
-
add_filter( 'permalink_manager_filter_default_post_slug', array($this, 'remove_stop_words'), 9, 3 );
|
13 |
-
add_filter( 'permalink_manager_filter_default_term_slug', array($this, 'remove_stop_words'), 9, 3 );
|
14 |
-
|
15 |
-
// Custom fields in permalinks
|
16 |
-
add_filter( 'permalink_manager_filter_default_post_uri', array($this, 'replace_custom_field_tags'), 9, 5 );
|
17 |
-
|
18 |
-
// Permalink Manager Pro Alerts
|
19 |
-
add_filter( 'permalink-manager-alerts', array($this, 'pro_alerts'), 9, 3 );
|
20 |
-
|
21 |
-
// Save redirects
|
22 |
-
add_action( 'permalink-manager-updated-post-uri', array($this, 'save_redirects'), 9, 5 );
|
23 |
-
add_action( 'permalink-manager-updated-term-uri', array($this, 'save_redirects'), 9, 5 );
|
24 |
-
|
25 |
-
// Check for updates
|
26 |
-
add_action( 'init', array($this, 'check_for_updates'), 9 );
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Update check
|
31 |
-
*/
|
32 |
-
public function check_for_updates() {
|
33 |
-
global $permalink_manager_options;
|
34 |
-
|
35 |
-
// Get the licence key
|
36 |
-
$license_key = (!empty($permalink_manager_options['licence']['licence_key'])) ? $permalink_manager_options['licence']['licence_key'] : "";
|
37 |
-
|
38 |
-
// Get expiration date
|
39 |
-
// add_filter('puc_request_info_result-permalink-manager-pro', array($this, 'update_pro_info'), 99, 2);
|
40 |
-
|
41 |
-
// Load Plugin Update Checker by YahnisElsts
|
42 |
-
require_once PERMALINK_MANAGER_DIR . '/includes/ext/plugin-update-checker/plugin-update-checker.php';
|
43 |
-
|
44 |
-
$UpdateChecker = Puc_v4_Factory::buildUpdateChecker(
|
45 |
-
"https://updates.permalinkmanager.pro/?action=get_metadata&slug=permalink-manager-pro&license_key={$license_key}",
|
46 |
-
PERMALINK_MANAGER_FILE,
|
47 |
-
"permalink-manager-pro"
|
48 |
-
);
|
49 |
-
|
50 |
-
$file = PERMALINK_MANAGER_BASENAME;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Stop words
|
55 |
-
*/
|
56 |
-
static function load_stop_words_languages() {
|
57 |
-
return array (
|
58 |
-
'ar' => __('Arabic', 'permalink-manager'),
|
59 |
-
'zh' => __('Chinese', 'permalink-manager'),
|
60 |
-
'da' => __('Danish', 'permalink-manager'),
|
61 |
-
'nl' => __('Dutch', 'permalink-manager'),
|
62 |
-
'en' => __('English', 'permalink-manager'),
|
63 |
-
'fi' => __('Finnish', 'permalink-manager'),
|
64 |
-
'fr' => __('French', 'permalink-manager'),
|
65 |
-
'de' => __('German', 'permalink-manager'),
|
66 |
-
'he' => __('Hebrew', 'permalink-manager'),
|
67 |
-
'hi' => __('Hindi', 'permalink-manager'),
|
68 |
-
'it' => __('Italian', 'permalink-manager'),
|
69 |
-
'ja' => __('Japanese', 'permalink-manager'),
|
70 |
-
'ko' => __('Korean', 'permalink-manager'),
|
71 |
-
'no' => __('Norwegian', 'permalink-manager'),
|
72 |
-
'fa' => __('Persian', 'permalink-manager'),
|
73 |
-
'pl' => __('Polish', 'permalink-manager'),
|
74 |
-
'pt' => __('Portuguese', 'permalink-manager'),
|
75 |
-
'ru' => __('Russian', 'permalink-manager'),
|
76 |
-
'es' => __('Spanish', 'permalink-manager'),
|
77 |
-
'sv' => __('Swedish', 'permalink-manager'),
|
78 |
-
'tr' => __('Turkish', 'permalink-manager')
|
79 |
-
);
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Load stop words
|
84 |
-
*/
|
85 |
-
static function load_stop_words($iso = '') {
|
86 |
-
$json_dir = PERMALINK_MANAGER_DIR . "/includes/ext/stopwords-json/dist/{$iso}.json";
|
87 |
-
$json_a = array();
|
88 |
-
|
89 |
-
if(file_exists($json_dir)) {
|
90 |
-
$string = file_get_contents($json_dir);
|
91 |
-
$json_a = json_decode($string, true);
|
92 |
-
}
|
93 |
-
|
94 |
-
return $json_a;
|
95 |
-
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* Remove stop words from default URIs
|
99 |
-
*/
|
100 |
-
public function remove_stop_words($slug, $object, $name) {
|
101 |
-
global $permalink_manager_options;
|
102 |
-
|
103 |
-
if(!empty($permalink_manager_options['stop-words']['stop-words-enable']) && !empty($permalink_manager_options['stop-words']['stop-words-list'])) {
|
104 |
-
$stop_words = explode(",", strtolower(stripslashes($permalink_manager_options['stop-words']['stop-words-list'])));
|
105 |
-
|
106 |
-
foreach($stop_words as $stop_word) {
|
107 |
-
$stop_word = trim($stop_word);
|
108 |
-
$slug = preg_replace("/([\/-]|^)({$stop_word})([\/-]|$)/", '$1$3', $slug);
|
109 |
-
}
|
110 |
-
|
111 |
-
// Clear the slug
|
112 |
-
$slug = preg_replace("/(-+)/", "-", trim($slug, "-"));
|
113 |
-
$slug = preg_replace("/(-\/-)|(\/-)|(-\/)/", "/", $slug);
|
114 |
-
}
|
115 |
-
|
116 |
-
return $slug;
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Hide "Buy Permalink Manager Pro" alert
|
121 |
-
*/
|
122 |
-
function pro_alerts($alerts = array()) {
|
123 |
-
global $permalink_manager_options;
|
124 |
-
|
125 |
-
if(empty($permalink_manager_options['licence']['licence_key'])) {
|
126 |
-
$alerts['licence_key'] = array('txt' => sprintf(__("Please paste the licence key <a href=\"%s\">here</a> to access all Permalink Manager Pro updates!", "permalink-manager"), admin_url('tools.php?page=permalink-manager§ion=settings')), 'type' => 'notice-error', 'show' => 1);
|
127 |
-
}
|
128 |
-
|
129 |
-
return $alerts;
|
130 |
-
}
|
131 |
-
|
132 |
-
/**
|
133 |
-
* Replace custom field tags in default post URIs
|
134 |
-
*/
|
135 |
-
function replace_custom_field_tags($default_uri, $native_slug, $post, $post_name, $native_uri) {
|
136 |
-
preg_match_all("/%__(.[^\%]+)%/", $default_uri, $custom_fields);
|
137 |
-
|
138 |
-
if(!empty($custom_fields[1])) {
|
139 |
-
foreach($custom_fields[1] as $i => $custom_field) {
|
140 |
-
$custom_field_value = apply_filters('permalink_manager_custom_field_value', get_post_meta($post->ID, $custom_field, true), $custom_field, $post);
|
141 |
-
|
142 |
-
// Make sure that custom field is a string
|
143 |
-
if(!empty($custom_field_value) && is_string($custom_field_value)) {
|
144 |
-
$default_uri = str_replace($custom_fields[0][$i], sanitize_title($custom_field_value), $default_uri);
|
145 |
-
}
|
146 |
-
}
|
147 |
-
}
|
148 |
-
|
149 |
-
return $default_uri;
|
150 |
-
}
|
151 |
-
|
152 |
-
public function update_pro_info($raw, $result) {
|
153 |
-
if(!empty($result['body'])) {
|
154 |
-
$plugin_info = json_decode($result['body']);
|
155 |
-
if(!empty($plugin_info['expiration_date'])) {
|
156 |
-
// $plugin_info['expiration_date'];
|
157 |
-
}
|
158 |
-
}
|
159 |
-
return $raw;
|
160 |
-
}
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Save Redirects
|
164 |
-
*/
|
165 |
-
public function save_redirects($element_id, $new_uri, $old_uri, $native_uri, $default_uri) {
|
166 |
-
global $permalink_manager_options, $permalink_manager_redirects;
|
167 |
-
|
168 |
-
// Terms IDs should be prepended with prefix
|
169 |
-
$element_id = (current_filter() == 'permalink-manager-updated-term-uri') ? "tax-{$element_id}" : $element_id;
|
170 |
-
|
171 |
-
// Make sure that $permalink_manager_redirects variable is an array
|
172 |
-
$permalink_manager_redirects = (is_array($permalink_manager_redirects)) ? $permalink_manager_redirects : array();
|
173 |
-
|
174 |
-
// AA. Post/term is saved or updated
|
175 |
-
if(isset($_POST['permalink-manager-redirects']) && is_array($_POST['permalink-manager-redirects'])) {
|
176 |
-
$permalink_manager_redirects[$element_id] = array_filter($_POST['permalink-manager-redirects']);
|
177 |
-
$redirects_updated = true;
|
178 |
-
}
|
179 |
-
// AB. All redirects are removed
|
180 |
-
else if(isset($_POST['permalink-manager-redirects'])) {
|
181 |
-
$permalink_manager_redirects[$element_id] = array();
|
182 |
-
$redirects_updated = true;
|
183 |
-
}
|
184 |
-
|
185 |
-
// No longer needed
|
186 |
-
unset($_POST['permalink-manager-redirects']);
|
187 |
-
|
188 |
-
// B. Custom URI is updated
|
189 |
-
if(!empty($permalink_manager_options['general']['setup_redirects']) && ($new_uri != $old_uri)) {
|
190 |
-
// Make sure that the array with redirects exists
|
191 |
-
$permalink_manager_redirects[$element_id] = (!empty($permalink_manager_redirects[$element_id])) ? $permalink_manager_redirects[$element_id] : array();
|
192 |
-
|
193 |
-
// Append the old custom URI
|
194 |
-
$permalink_manager_redirects[$element_id][] = $old_uri;
|
195 |
-
$redirects_updated = true;
|
196 |
-
}
|
197 |
-
|
198 |
-
if(!empty($redirects_updated) && is_array($permalink_manager_redirects[$element_id])) {
|
199 |
-
// Remove empty redirects
|
200 |
-
$permalink_manager_redirects[$element_id] = array_filter($permalink_manager_redirects[$element_id]);
|
201 |
-
|
202 |
-
if(!empty($permalink_manager_redirects[$element_id])) {
|
203 |
-
// Sanitize the array with redirects
|
204 |
-
$permalink_manager_redirects[$element_id] = array_map('Permalink_Manager_Helper_Functions::sanitize_title', $permalink_manager_redirects[$element_id]);
|
205 |
-
|
206 |
-
// Reset the keys
|
207 |
-
$permalink_manager_redirects[$element_id] = array_values($permalink_manager_redirects[$element_id]);
|
208 |
-
|
209 |
-
// Remove the duplicates
|
210 |
-
$permalink_manager_redirects[$element_id] = array_unique($permalink_manager_redirects[$element_id]);
|
211 |
-
}
|
212 |
-
|
213 |
-
// Save the redirects
|
214 |
-
update_option('permalink-manager-redirects', $permalink_manager_redirects);
|
215 |
-
}
|
216 |
-
}
|
217 |
-
|
218 |
-
}
|
219 |
-
|
220 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/core/permalink-manager-uri-functions-post.php
CHANGED
@@ -575,6 +575,9 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
|
|
575 |
function new_post_uri($post_id) {
|
576 |
global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
|
577 |
|
|
|
|
|
|
|
578 |
// Do not do anything if post is autosaved
|
579 |
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
|
580 |
|
@@ -582,7 +585,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
|
|
582 |
if(!empty($_REQUEST['bulk_edit'])) { return $post_id; }
|
583 |
|
584 |
// Hotfix
|
585 |
-
if(isset($_POST['custom_uri']) || isset($_POST['permalink-manager-quick-edit'])) { return; }
|
586 |
|
587 |
// Continue only if no custom URI is already assigned
|
588 |
if(!empty($permalink_manager_uris[$post_id])) { return $post_id; }
|
@@ -610,6 +613,9 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
|
|
610 |
function update_post_uri($post_id) {
|
611 |
global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
|
612 |
|
|
|
|
|
|
|
613 |
// Do not do anything if post is autosaved
|
614 |
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
|
615 |
|
575 |
function new_post_uri($post_id) {
|
576 |
global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
|
577 |
|
578 |
+
// Do not trigger if post is a revision
|
579 |
+
if(wp_is_post_revision($post_id)) { return $post_id; }
|
580 |
+
|
581 |
// Do not do anything if post is autosaved
|
582 |
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
|
583 |
|
585 |
if(!empty($_REQUEST['bulk_edit'])) { return $post_id; }
|
586 |
|
587 |
// Hotfix
|
588 |
+
if(isset($_POST['custom_uri']) || isset($_POST['permalink-manager-quick-edit'])) { return $post_id; }
|
589 |
|
590 |
// Continue only if no custom URI is already assigned
|
591 |
if(!empty($permalink_manager_uris[$post_id])) { return $post_id; }
|
613 |
function update_post_uri($post_id) {
|
614 |
global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
|
615 |
|
616 |
+
// Verify nonce at first
|
617 |
+
if(!isset($_POST['permalink-manager-nonce']) || !wp_verify_nonce($_POST['permalink-manager-nonce'], 'permalink-manager-edit-uri-box')) { return $post_id; }
|
618 |
+
|
619 |
// Do not do anything if post is autosaved
|
620 |
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
|
621 |
|
includes/core/permalink-manager-uri-functions-tax.php
DELETED
@@ -1,527 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Additional functions used in classes and another subclasses
|
5 |
-
*/
|
6 |
-
class Permalink_Manager_URI_Functions_Tax extends Permalink_Manager_Class {
|
7 |
-
|
8 |
-
public function __construct() {
|
9 |
-
add_action( 'admin_init', array($this, 'init') );
|
10 |
-
|
11 |
-
add_filter( 'term_link', array($this, 'custom_tax_permalinks'), 999, 2 );
|
12 |
-
add_filter( 'category_link', array($this, 'custom_tax_permalinks'), 999, 2 );
|
13 |
-
add_filter( 'tag_link', array($this, 'custom_tax_permalinks'), 999, 2 );
|
14 |
-
|
15 |
-
/**
|
16 |
-
* URI Editor
|
17 |
-
*/
|
18 |
-
add_action( 'quick_edit_custom_box', array($this, 'quick_edit_column_form'), 999, 3);
|
19 |
-
}
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Allow to edit URIs from "Edit Term" admin pages (register hooks)
|
23 |
-
*/
|
24 |
-
public function init() {
|
25 |
-
$all_taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array();
|
26 |
-
|
27 |
-
// Add "URI Editor" to "Quick Edit" for all taxonomies
|
28 |
-
foreach($all_taxonomies as $tax => $label) {
|
29 |
-
add_action( "{$tax}_add_form_fields", array($this, 'edit_uri_box'), 10, 1 );
|
30 |
-
add_action( "{$tax}_edit_form_fields", array($this, 'edit_uri_box'), 10, 1 );
|
31 |
-
add_action( "edited_{$tax}", array($this, 'update_term_uri'), 10, 2 );
|
32 |
-
add_action( "create_{$tax}", array($this, 'update_term_uri'), 10, 2 );
|
33 |
-
|
34 |
-
add_filter( "manage_edit-{$tax}_columns", array($this, 'quick_edit_column') );
|
35 |
-
add_filter( "manage_{$tax}_custom_column" , array($this, 'quick_edit_column_content'), 10, 3 );
|
36 |
-
}
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Change permalinks for taxonomies
|
41 |
-
*/
|
42 |
-
function custom_tax_permalinks($permalink, $term) {
|
43 |
-
global $wp_rewrite, $permalink_manager_uris, $permalink_manager_options;
|
44 |
-
|
45 |
-
$term_id = (!empty($term->term_id)) ? $term->term_id : $term;
|
46 |
-
|
47 |
-
// Apend the language code as a non-editable prefix (can be used also for another prefixes)
|
48 |
-
$prefix = apply_filters('permalink-manager-term-permalink-prefix', '', $term);
|
49 |
-
|
50 |
-
if(isset($permalink_manager_uris["tax-{$term_id}"])) {
|
51 |
-
$permalink = get_option('home');
|
52 |
-
|
53 |
-
// Encode URI?
|
54 |
-
if(!empty($permalink_manager_options['general']['decode_uris'])) {
|
55 |
-
$permalink .= urldecode("/{$prefix}{$permalink_manager_uris["tax-{$term_id}"]}");
|
56 |
-
} else {
|
57 |
-
$permalink .= Permalink_Manager_Helper_Functions::encode_uri("/{$prefix}{$permalink_manager_uris["tax-{$term_id}"]}");
|
58 |
-
}
|
59 |
-
} else if(!empty($permalink_manager_options['general']['decode_uris'])) {
|
60 |
-
$permalink = urldecode($permalink);
|
61 |
-
}
|
62 |
-
|
63 |
-
return apply_filters('permalink_manager_filter_final_term_permalink', $permalink, $term);
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Check if the provided slug is unique and then update it with SQL query.
|
68 |
-
*/
|
69 |
-
static function update_slug_by_id($slug, $id) {
|
70 |
-
global $wpdb;
|
71 |
-
|
72 |
-
// Update slug and make it unique
|
73 |
-
$term = get_term(intval($id));
|
74 |
-
$slug = (empty($slug)) ? sanitize_title(get_the_title($term->name)) : $slug;
|
75 |
-
$new_slug = wp_unique_term_slug($slug, $term);
|
76 |
-
|
77 |
-
$wpdb->query("UPDATE $wpdb->terms SET slug = '$new_slug' WHERE term_id = '$id'");
|
78 |
-
|
79 |
-
return $new_slug;
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Get the active URI
|
84 |
-
*/
|
85 |
-
public static function get_term_uri($term_id, $native_uri = false) {
|
86 |
-
global $permalink_manager_uris;
|
87 |
-
|
88 |
-
// Check if input is term object
|
89 |
-
$term = (isset($term_id->term_id)) ? $term_id->term_id : get_term($term_id);
|
90 |
-
|
91 |
-
$final_uri = (!empty($permalink_manager_uris["tax-{$term_id}"])) ? $permalink_manager_uris["tax-{$term_id}"] : self::get_default_term_uri($term->term_id, $native_uri);
|
92 |
-
return $final_uri;
|
93 |
-
}
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Get the default (not overwritten by the user) or native URI (unfiltered)
|
97 |
-
*/
|
98 |
-
public static function get_default_term_uri($term, $native_uri = false) {
|
99 |
-
global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $wp_rewrite;
|
100 |
-
|
101 |
-
// Load all bases & term
|
102 |
-
$term = is_object($term) ? $term : get_term($term);
|
103 |
-
$term_id = $term->term_id;
|
104 |
-
$taxonomy_name = $term->taxonomy;
|
105 |
-
$taxonomy = get_taxonomy($taxonomy_name);
|
106 |
-
$term_slug = ($native_uri == false) ? apply_filters('permalink_manager_filter_default_term_slug', $term->slug, $term, $term->name) : $term->slug;
|
107 |
-
|
108 |
-
// Get the permastruct
|
109 |
-
$default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($taxonomy_name, true);
|
110 |
-
if($native_uri) {
|
111 |
-
$permastruct = $default_permastruct;
|
112 |
-
} else {
|
113 |
-
$permastruct = (isset($permalink_manager_permastructs['taxonomies'][$taxonomy_name])) ? $permalink_manager_permastructs['taxonomies'][$taxonomy_name] : $default_permastruct;
|
114 |
-
}
|
115 |
-
$default_base = (!empty($permastruct)) ? trim($permastruct, '/') : "";
|
116 |
-
|
117 |
-
// A. Check if taxonomy has custom rewrite rules
|
118 |
-
if(empty($default_base) && !isset($permalink_manager_permastructs['taxonomies'][$taxonomy_name])) {
|
119 |
-
if('category' == $taxonomy_name) {
|
120 |
-
$default_base = "?cat={$term->term_id}";
|
121 |
-
} elseif ($taxonomy->query_var) {
|
122 |
-
$default_base = "?{$taxonomy->query_var}={$term_slug}";
|
123 |
-
} else {
|
124 |
-
$default_base = "?taxonomy={$taxonomy_name}&term={$slug}";
|
125 |
-
}
|
126 |
-
}
|
127 |
-
// B. Use default rewrite rules
|
128 |
-
else {
|
129 |
-
// Add ancestors to hierarchical taxonomy
|
130 |
-
if($taxonomy->rewrite['hierarchical']) {
|
131 |
-
$hierarchical_slugs = array();
|
132 |
-
$ancestors = get_ancestors( $term->term_id, $taxonomy_name, 'taxonomy' );
|
133 |
-
foreach ( (array) $ancestors as $ancestor ) {
|
134 |
-
$ancestor_term = get_term($ancestor, $taxonomy_name);
|
135 |
-
$hierarchical_slugs[] = ($native_uri) ? $ancestor_term->slug : Permalink_Manager_Helper_Functions::force_custom_slugs($ancestor_term->slug, $ancestor_term);
|
136 |
-
}
|
137 |
-
$hierarchical_slugs = array_reverse($hierarchical_slugs);
|
138 |
-
$default_base = (!empty($default_base) && strpos($default_base, "%{$taxonomy_name}%") !== false) ? str_replace("%{$taxonomy_name}%", implode('/', $hierarchical_slugs), $default_base) : $default_base . "/" . implode('/', $hierarchical_slugs);
|
139 |
-
} else {
|
140 |
-
$default_base = str_replace("%{$taxonomy_name}%", $term_slug, $default_base);
|
141 |
-
}
|
142 |
-
|
143 |
-
// Append the term slug now
|
144 |
-
$term_slug = ($native_uri) ? $term_slug : Permalink_Manager_Helper_Functions::force_custom_slugs($term_slug, $term);
|
145 |
-
$default_base = (in_array("tax-{$taxonomy_name}", $permalink_manager_options['general']['disable_slug_appendix'])) ? $default_base : "{$default_base}/{$term_slug}";
|
146 |
-
}
|
147 |
-
$default_uri = $default_base;
|
148 |
-
|
149 |
-
// Clear the URI
|
150 |
-
$default_uri = preg_replace("/%(.+?)%/", "", $default_uri);
|
151 |
-
$default_uri = preg_replace('/\s+/', '', $default_uri);
|
152 |
-
$default_uri = str_replace('//', '/', $default_uri);
|
153 |
-
$default_uri = trim($default_uri, "/");
|
154 |
-
|
155 |
-
return apply_filters('permalink_manager_filter_default_term_uri', $default_uri, $term->slug, $term, $term_slug, $native_uri);
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Find & replace (bulk action)
|
160 |
-
*/
|
161 |
-
public static function find_and_replace() {
|
162 |
-
global $wpdb, $permalink_manager_uris;
|
163 |
-
|
164 |
-
// Check if post types & statuses are not empty
|
165 |
-
if(empty($_POST['post_types']) || empty($_POST['post_statuses'])) { return false; }
|
166 |
-
|
167 |
-
// Reset variables
|
168 |
-
$updated_slugs_count = 0;
|
169 |
-
$updated_array = array();
|
170 |
-
$alert_type = $alert_content = $errors = '';
|
171 |
-
|
172 |
-
// Process the variables from $_POST object
|
173 |
-
$old_string = esc_sql($_POST['old_string']);
|
174 |
-
$new_string = esc_sql($_POST['new_string']);
|
175 |
-
|
176 |
-
$taxonomy_names_array = ($_POST['taxonomies']) ? ($_POST['taxonomies']) : '';
|
177 |
-
$taxonomy_names = implode("', '", $taxonomy_names_array);
|
178 |
-
$mode = isset($_POST['mode']) ? $_POST['mode'] : 'custom_uris';
|
179 |
-
|
180 |
-
// Filter the terms by IDs
|
181 |
-
$where = '';
|
182 |
-
if(!empty($_POST['ids'])) {
|
183 |
-
// Remove whitespaces and prepare array with IDs and/or ranges
|
184 |
-
$ids = esc_sql(preg_replace('/\s*/m', '', $_POST['ids']));
|
185 |
-
preg_match_all("/([\d]+(?:-?[\d]+)?)/x", $ids, $groups);
|
186 |
-
|
187 |
-
// Prepare the extra ID filters
|
188 |
-
$where .= "AND (";
|
189 |
-
foreach($groups[0] as $group) {
|
190 |
-
$where .= ($group == reset($groups[0])) ? "" : " OR ";
|
191 |
-
// A. Single number
|
192 |
-
if(is_numeric($group)) {
|
193 |
-
$where .= "(t.term_id = {$group})";
|
194 |
-
}
|
195 |
-
// B. Range
|
196 |
-
else if(substr_count($group, '-')) {
|
197 |
-
$range_edges = explode("-", $group);
|
198 |
-
$where .= "(t.term_id BETWEEN {$range_edges[0]} AND {$range_edges[1]})";
|
199 |
-
}
|
200 |
-
}
|
201 |
-
$where .= ")";
|
202 |
-
}
|
203 |
-
|
204 |
-
// Get the rows before they are altered
|
205 |
-
$terms_to_update = $wpdb->get_results("SELECT t.slug, t.name, t.term_id, tt.taxonomy FROM {$wpdb->terms} as t INNER JOIN {$wpdb->term_taxonomy} as tt ON tt.term_id = t.term_id WHERE tt.taxonomy IN ('{$taxonomy_names}') {$where}", ARRAY_A);
|
206 |
-
|
207 |
-
// Now if the array is not empty use IDs from each subarray as a key
|
208 |
-
if($terms_to_update && empty($errors)) {
|
209 |
-
foreach ($terms_to_update as $row) {
|
210 |
-
// Prevent server timeout
|
211 |
-
set_time_limit(0);
|
212 |
-
|
213 |
-
// Prepare variables
|
214 |
-
$this_term = get_term($row['term_id']);
|
215 |
-
$term_permalink_id = "tax-{$row['term_id']}";
|
216 |
-
|
217 |
-
// Get default & native URL
|
218 |
-
$native_uri = self::get_default_term_uri($this_term, true);
|
219 |
-
$default_uri = self::get_default_term_uri($this_term);
|
220 |
-
$old_term_name = $row['slug'];
|
221 |
-
$old_uri = (isset($permalink_manager_uris[$term_permalink_id])) ? $permalink_manager_uris[$term_permalink_id] : $native_uri;
|
222 |
-
|
223 |
-
// Do replacement on slugs (non-REGEX)
|
224 |
-
if(preg_match("/^\/.+\/[a-z]*$/i", $old_string)) {
|
225 |
-
// Use $_POST['old_string'] directly here & fix double slashes problem
|
226 |
-
$pattern = "~" . stripslashes(trim(sanitize_text_field($_POST['old_string']), "/")) . "~";
|
227 |
-
|
228 |
-
$new_term_name = ($mode == 'slugs') ? preg_replace($pattern, $new_string, $old_term_name) : $old_term_name;
|
229 |
-
$new_uri = ($mode != 'slugs') ? preg_replace($pattern, $new_string, $old_uri) : $old_uri;
|
230 |
-
} else {
|
231 |
-
$new_term_name = ($mode == 'slugs') ? str_replace($old_string, $new_string, $old_term_name) : $old_term_name; // Term slug is changed only in first mode
|
232 |
-
$new_uri = ($mode != 'slugs') ? str_replace($old_string, $new_string, $old_uri) : $old_uri;
|
233 |
-
}
|
234 |
-
|
235 |
-
//print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
|
236 |
-
|
237 |
-
// Check if native slug should be changed
|
238 |
-
if(($mode == 'slugs') && ($old_term_name != $new_term_name)) {
|
239 |
-
self::update_slug_by_id($new_term_name, $row['term_id']);
|
240 |
-
}
|
241 |
-
|
242 |
-
if(($old_uri != $new_uri) || ($old_term_name != $new_term_name)) {
|
243 |
-
$permalink_manager_uris[$term_permalink_id] = $new_uri;
|
244 |
-
$updated_array[] = array('item_title' => $row['name'], 'ID' => $row['term_id'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_term_name, 'new_slug' => $new_term_name, 'tax' => $this_term->taxonomy);
|
245 |
-
$updated_slugs_count++;
|
246 |
-
}
|
247 |
-
|
248 |
-
do_action('permalink-manager-updated-term-uri', $row['term_id'], $new_uri, $old_uri, $native_uri, $default_uri);
|
249 |
-
}
|
250 |
-
|
251 |
-
// Filter array before saving
|
252 |
-
$permalink_manager_uris = array_filter($permalink_manager_uris);
|
253 |
-
update_option('permalink-manager-uris', $permalink_manager_uris);
|
254 |
-
|
255 |
-
$output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
|
256 |
-
wp_reset_postdata();
|
257 |
-
}
|
258 |
-
|
259 |
-
return (!empty($output)) ? $output : "";
|
260 |
-
}
|
261 |
-
|
262 |
-
/**
|
263 |
-
* Regenerate slugs & bases (bulk action)
|
264 |
-
*/
|
265 |
-
static function regenerate_all_permalinks() {
|
266 |
-
global $wpdb, $permalink_manager_uris;
|
267 |
-
|
268 |
-
// Check if post types & statuses are not empty
|
269 |
-
if(empty($_POST['taxonomies'])) { return false; }
|
270 |
-
|
271 |
-
// Process the variables from $_POST object
|
272 |
-
$updated_slugs_count = 0;
|
273 |
-
$updated_array = array();
|
274 |
-
$alert_type = $alert_content = $errors = '';
|
275 |
-
|
276 |
-
$taxonomy_names_array = ($_POST['taxonomies']) ? ($_POST['taxonomies']) : '';
|
277 |
-
$taxonomy_names = implode("', '", $taxonomy_names_array);
|
278 |
-
$mode = isset($_POST['mode']) ? $_POST['mode'] : 'custom_uris';
|
279 |
-
|
280 |
-
// Filter the terms by IDs
|
281 |
-
$where = '';
|
282 |
-
if(!empty($_POST['ids'])) {
|
283 |
-
// Remove whitespaces and prepare array with IDs and/or ranges
|
284 |
-
$ids = esc_sql(preg_replace('/\s*/m', '', $_POST['ids']));
|
285 |
-
preg_match_all("/([\d]+(?:-?[\d]+)?)/x", $ids, $groups);
|
286 |
-
|
287 |
-
// Prepare the extra ID filters
|
288 |
-
$where .= "AND (";
|
289 |
-
foreach($groups[0] as $group) {
|
290 |
-
$where .= ($group == reset($groups[0])) ? "" : " OR ";
|
291 |
-
// A. Single number
|
292 |
-
if(is_numeric($group)) {
|
293 |
-
$where .= "(t.term_id = {$group})";
|
294 |
-
}
|
295 |
-
// B. Range
|
296 |
-
else if(substr_count($group, '-')) {
|
297 |
-
$range_edges = explode("-", $group);
|
298 |
-
$where .= "(t.term_id BETWEEN {$range_edges[0]} AND {$range_edges[1]})";
|
299 |
-
}
|
300 |
-
}
|
301 |
-
$where .= ")";
|
302 |
-
}
|
303 |
-
|
304 |
-
// Get the rows before they are altered
|
305 |
-
$terms_to_update = $wpdb->get_results("SELECT t.slug, t.name, t.term_id, tt.taxonomy FROM {$wpdb->terms} as t INNER JOIN {$wpdb->term_taxonomy} as tt ON tt.term_id = t.term_id WHERE tt.taxonomy IN ('{$taxonomy_names}') {$where}", ARRAY_A);
|
306 |
-
|
307 |
-
// Now if the array is not empty use IDs from each subarray as a key
|
308 |
-
if($terms_to_update && empty($errors)) {
|
309 |
-
foreach ($terms_to_update as $row) {
|
310 |
-
// Prevent server timeout
|
311 |
-
set_time_limit(0);
|
312 |
-
|
313 |
-
// Prepare variables
|
314 |
-
$this_term = get_term($row['term_id']);
|
315 |
-
$term_permalink_id = "tax-{$row['term_id']}";
|
316 |
-
|
317 |
-
// Get default & native URL
|
318 |
-
$native_uri = self::get_default_term_uri($this_term, true);
|
319 |
-
$default_uri = self::get_default_term_uri($this_term);
|
320 |
-
$old_term_name = $row['slug'];
|
321 |
-
$old_uri = (isset($permalink_manager_uris[$term_permalink_id])) ? $permalink_manager_uris[$term_permalink_id] : $native_uri;
|
322 |
-
$correct_slug = sanitize_title($row['name']);
|
323 |
-
|
324 |
-
// Process URI & slug
|
325 |
-
$new_slug = wp_unique_term_slug($correct_slug, $this_term);
|
326 |
-
$new_term_name = ($mode == 'slugs') ? $new_slug : $old_term_name; // Post name is changed only in first mode
|
327 |
-
|
328 |
-
// Prepare the new URI
|
329 |
-
if($mode == 'slugs') {
|
330 |
-
$new_uri = $old_uri;
|
331 |
-
} else if($mode == 'native') {
|
332 |
-
$new_uri = $native_uri;
|
333 |
-
} else {
|
334 |
-
$new_uri = $default_uri;
|
335 |
-
}
|
336 |
-
|
337 |
-
//print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
|
338 |
-
|
339 |
-
// Check if native slug should be changed
|
340 |
-
if(($mode == 'slugs') && ($old_term_name != $new_term_name)) {
|
341 |
-
self::update_slug_by_id($new_term_name, $row['term_id']);
|
342 |
-
}
|
343 |
-
|
344 |
-
if(($old_uri != $new_uri) || ($old_term_name != $new_term_name)) {
|
345 |
-
$permalink_manager_uris[$term_permalink_id] = $new_uri;
|
346 |
-
$updated_array[] = array('item_title' => $row['name'], 'ID' => $row['term_id'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_term_name, 'new_slug' => $new_term_name, 'tax' => $this_term->taxonomy);
|
347 |
-
$updated_slugs_count++;
|
348 |
-
}
|
349 |
-
|
350 |
-
do_action('permalink-manager-updated-term-uri', $row['term_id'], $new_uri, $old_uri, $native_uri, $default_uri);
|
351 |
-
}
|
352 |
-
|
353 |
-
// Filter array before saving
|
354 |
-
$permalink_manager_uris = array_filter($permalink_manager_uris);
|
355 |
-
update_option('permalink-manager-uris', $permalink_manager_uris);
|
356 |
-
|
357 |
-
$output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
|
358 |
-
wp_reset_postdata();
|
359 |
-
}
|
360 |
-
|
361 |
-
return (!empty($output)) ? $output : "";
|
362 |
-
}
|
363 |
-
|
364 |
-
/**
|
365 |
-
* Update all slugs & bases (bulk action)
|
366 |
-
*/
|
367 |
-
static public function update_all_permalinks() {
|
368 |
-
global $permalink_manager_uris;
|
369 |
-
|
370 |
-
// Setup needed variables
|
371 |
-
$updated_slugs_count = 0;
|
372 |
-
$updated_array = array();
|
373 |
-
|
374 |
-
$old_uris = $permalink_manager_uris;
|
375 |
-
$new_uris = isset($_POST['uri']) ? $_POST['uri'] : array();
|
376 |
-
|
377 |
-
// Double check if the slugs and ids are stored in arrays
|
378 |
-
if (!is_array($new_uris)) $new_uris = explode(',', $new_uris);
|
379 |
-
|
380 |
-
if (!empty($new_uris)) {
|
381 |
-
foreach($new_uris as $id => $new_uri) {
|
382 |
-
// Remove prefix from field name to obtain term id
|
383 |
-
$term_id = filter_var(str_replace('tax-', '', $id), FILTER_SANITIZE_NUMBER_INT);
|
384 |
-
|
385 |
-
// Prepare variables
|
386 |
-
$this_term = get_term($term_id);
|
387 |
-
$updated = '';
|
388 |
-
|
389 |
-
// Get default & native URL
|
390 |
-
$native_uri = self::get_default_term_uri($this_term, true);
|
391 |
-
$default_uri = self::get_default_term_uri($this_term);
|
392 |
-
|
393 |
-
$old_uri = isset($old_uris[$id]) ? trim($old_uris[$id], "/") : $native_uri;
|
394 |
-
|
395 |
-
// Process new values - empty entries will be treated as default values
|
396 |
-
$new_uri = preg_replace('/\s+/', '', $new_uri);
|
397 |
-
$new_uri = (!empty($new_uri)) ? trim($new_uri, "/") : $default_uri;
|
398 |
-
$new_slug = (strpos($new_uri, '/') !== false) ? substr($new_uri, strrpos($new_uri, '/') + 1) : $new_uri;
|
399 |
-
|
400 |
-
if($new_uri != $old_uri) {
|
401 |
-
$old_uris[$id] = $new_uri;
|
402 |
-
$updated_array[] = array('item_title' => $this_term->name, 'ID' => $term_id, 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'tax' => $this_term->taxonomy);
|
403 |
-
$updated_slugs_count++;
|
404 |
-
}
|
405 |
-
|
406 |
-
do_action('permalink-manager-updated-term-uri', $term_id, $new_uri, $old_uri, $native_uri, $default_uri);
|
407 |
-
}
|
408 |
-
|
409 |
-
// Filter array before saving & append the global
|
410 |
-
$old_uris = $permalink_manager_uris = array_filter($old_uris);
|
411 |
-
update_option('permalink-manager-uris', $old_uris);
|
412 |
-
|
413 |
-
//print_r($permalink_manager_uris);
|
414 |
-
|
415 |
-
$output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
|
416 |
-
}
|
417 |
-
|
418 |
-
return ($output) ? $output : "";
|
419 |
-
}
|
420 |
-
|
421 |
-
/**
|
422 |
-
* Allow to edit URIs from "New Term" & "Edit Term" admin pages
|
423 |
-
*/
|
424 |
-
public function edit_uri_box($term = '') {
|
425 |
-
$label = __("Custom URI", "permalink-manager");
|
426 |
-
$description = __("Clear/leave the field empty to use the default permalink.", "permalink-manager");
|
427 |
-
|
428 |
-
// A. New term
|
429 |
-
if (empty($term->term_id)) {
|
430 |
-
$html = "<div class=\"form-field\">";
|
431 |
-
$html .= "<label for=\"term_meta[uri]\">{$label}</label>";
|
432 |
-
$html .= "<input type=\"text\" name=\"permalink-manager[term-uri]\" id=\"permalink-manager[term-uri]\" value=\"\">";
|
433 |
-
$html .= "<p class=\"description\">{$description}</p>";
|
434 |
-
$html .= "</div>";
|
435 |
-
}
|
436 |
-
// B. Edit term
|
437 |
-
else {
|
438 |
-
$uri = self::get_term_uri($term->term_id, true);
|
439 |
-
$default_uri = self::get_default_term_uri($term->term_id);
|
440 |
-
$native_uri = self::get_default_term_uri($term->term_id, true);
|
441 |
-
|
442 |
-
// Make sure that home URL ends with slash
|
443 |
-
$home_url = trim(get_option('home'), "/") . "/";
|
444 |
-
$prefix = apply_filters('permalink-manager-term-permalink-prefix', '', $term, true);
|
445 |
-
|
446 |
-
$html = "<tr id=\"permalink-manager\" class=\"form-field permalink-manager-edit-term permalink-manager\">";
|
447 |
-
$html .= "<th scope=\"row\" valign=\"top\"><label for=\"custom_uri\">{$label}</label></th>";
|
448 |
-
$html .= "<td><div>";
|
449 |
-
if(!empty($uri)) {
|
450 |
-
$html .= Permalink_Manager_Admin_Functions::display_uri_box($term, $default_uri, $uri, $native_uri, "{$home_url}{$prefix}");
|
451 |
-
}
|
452 |
-
$html .= "</div></td>";
|
453 |
-
$html .= "</tr>";
|
454 |
-
}
|
455 |
-
|
456 |
-
echo $html;
|
457 |
-
}
|
458 |
-
|
459 |
-
/**
|
460 |
-
* "Quick Edit" form
|
461 |
-
*/
|
462 |
-
function quick_edit_column($columns) {
|
463 |
-
return array_merge($columns, array('permalink-manager-col' => __( 'Current URI', 'permalink-manager')));
|
464 |
-
}
|
465 |
-
|
466 |
-
function quick_edit_column_content($content, $column_name, $term_id) {
|
467 |
-
if($column_name != "permalink-manager-col") { return $content; }
|
468 |
-
return self::get_term_uri($term_id);
|
469 |
-
}
|
470 |
-
|
471 |
-
function quick_edit_column_form($column_name, $post_type, $taxonomy = '') {
|
472 |
-
if($taxonomy && $column_name == 'permalink-manager-col') {
|
473 |
-
echo Permalink_Manager_Admin_Functions::quick_edit_column_form();
|
474 |
-
}
|
475 |
-
}
|
476 |
-
|
477 |
-
/**
|
478 |
-
* Update URI from "Edit Term" admin page
|
479 |
-
*/
|
480 |
-
function update_term_uri($term_id, $taxonomy) {
|
481 |
-
global $permalink_manager_uris;
|
482 |
-
|
483 |
-
// Check if user changed URI
|
484 |
-
if(!isset($_POST['custom_uri'])) {
|
485 |
-
return;
|
486 |
-
}
|
487 |
-
|
488 |
-
// Get the term object
|
489 |
-
$this_term = get_term($term_id);
|
490 |
-
$term_permalink_id = "tax-{$term_id}";
|
491 |
-
|
492 |
-
// Get default & native & user-submitted URIs
|
493 |
-
$native_uri = self::get_default_term_uri($this_term, true);
|
494 |
-
$default_uri = self::get_default_term_uri($this_term);
|
495 |
-
$old_uri = (isset($permalink_manager_uris[$term_permalink_id])) ? $permalink_manager_uris[$term_permalink_id] : "";
|
496 |
-
$new_uri = trim($_POST['custom_uri'], "/");
|
497 |
-
|
498 |
-
// A little hack (if user removes whole URI from input) ...
|
499 |
-
$new_uri = (!empty($new_uri)) ? Permalink_Manager_Helper_Functions::sanitize_title($new_uri) : $default_uri;
|
500 |
-
|
501 |
-
// Save only changed URIs
|
502 |
-
if($new_uri != $old_uri) {
|
503 |
-
$permalink_manager_uris[$term_permalink_id] = $new_uri;
|
504 |
-
}
|
505 |
-
|
506 |
-
do_action('permalink-manager-updated-term-uri', $term_id, $new_uri, $old_uri, $native_uri, $default_uri);
|
507 |
-
|
508 |
-
update_option('permalink-manager-uris', $permalink_manager_uris);
|
509 |
-
}
|
510 |
-
|
511 |
-
/**
|
512 |
-
* Remove URI from options array after post is moved to the trash
|
513 |
-
*/
|
514 |
-
function remove_term_uri($term_id) {
|
515 |
-
global $permalink_manager_uris;
|
516 |
-
|
517 |
-
// Check if the custom permalink is assigned to this post
|
518 |
-
if(isset($permalink_manager_uris[$term_id])) {
|
519 |
-
unset($permalink_manager_uris[$term_id]);
|
520 |
-
}
|
521 |
-
|
522 |
-
update_option('permalink-manager-uris', $permalink_manager_uris);
|
523 |
-
}
|
524 |
-
|
525 |
-
}
|
526 |
-
|
527 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4/Factory.php
DELETED
@@ -1,271 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Factory', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A factory that builds update checker instances.
|
6 |
-
*
|
7 |
-
* When multiple versions of the same class have been loaded (e.g. PluginUpdateChecker 4.0
|
8 |
-
* and 4.1), this factory will always use the latest available minor version. Register class
|
9 |
-
* versions by calling {@link PucFactory::addVersion()}.
|
10 |
-
*
|
11 |
-
* At the moment it can only build instances of the UpdateChecker class. Other classes are
|
12 |
-
* intended mainly for internal use and refer directly to specific implementations.
|
13 |
-
*/
|
14 |
-
class Puc_v4_Factory {
|
15 |
-
protected static $classVersions = array();
|
16 |
-
protected static $sorted = false;
|
17 |
-
|
18 |
-
protected static $myMajorVersion = '';
|
19 |
-
protected static $latestCompatibleVersion = '';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Create a new instance of the update checker.
|
23 |
-
*
|
24 |
-
* This method automatically detects if you're using it for a plugin or a theme and chooses
|
25 |
-
* the appropriate implementation for your update source (JSON file, GitHub, BitBucket, etc).
|
26 |
-
*
|
27 |
-
* @see Puc_v4p1_UpdateChecker::__construct
|
28 |
-
*
|
29 |
-
* @param string $metadataUrl The URL of the metadata file, a GitHub repository, or another supported update source.
|
30 |
-
* @param string $fullPath Full path to the main plugin file or to the theme directory.
|
31 |
-
* @param string $slug Custom slug. Defaults to the name of the main plugin file or the theme directory.
|
32 |
-
* @param int $checkPeriod How often to check for updates (in hours).
|
33 |
-
* @param string $optionName Where to store book-keeping info about update checks.
|
34 |
-
* @param string $muPluginFile The plugin filename relative to the mu-plugins directory.
|
35 |
-
* @return Puc_v4p1_Plugin_UpdateChecker|Puc_v4p1_Theme_UpdateChecker|Puc_v4p1_Vcs_BaseChecker
|
36 |
-
*/
|
37 |
-
public static function buildUpdateChecker($metadataUrl, $fullPath, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
|
38 |
-
$fullPath = wp_normalize_path($fullPath);
|
39 |
-
$id = null;
|
40 |
-
|
41 |
-
//Plugin or theme?
|
42 |
-
$themeDirectory = self::getThemeDirectoryName($fullPath);
|
43 |
-
if ( self::isPluginFile($fullPath) ) {
|
44 |
-
$type = 'Plugin';
|
45 |
-
$id = $fullPath;
|
46 |
-
} else if ( $themeDirectory !== null ) {
|
47 |
-
$type = 'Theme';
|
48 |
-
$id = $themeDirectory;
|
49 |
-
} else {
|
50 |
-
throw new RuntimeException(sprintf(
|
51 |
-
'The update checker cannot determine if "%s" is a plugin or a theme. ' .
|
52 |
-
'This is a bug. Please contact the PUC developer.',
|
53 |
-
htmlentities($fullPath)
|
54 |
-
));
|
55 |
-
}
|
56 |
-
|
57 |
-
//Which hosting service does the URL point to?
|
58 |
-
$service = self::getVcsService($metadataUrl);
|
59 |
-
|
60 |
-
$apiClass = null;
|
61 |
-
if ( empty($service) ) {
|
62 |
-
//The default is to get update information from a remote JSON file.
|
63 |
-
$checkerClass = $type . '_UpdateChecker';
|
64 |
-
} else {
|
65 |
-
//You can also use a VCS repository like GitHub.
|
66 |
-
$checkerClass = 'Vcs_' . $type . 'UpdateChecker';
|
67 |
-
$apiClass = $service . 'Api';
|
68 |
-
}
|
69 |
-
|
70 |
-
$checkerClass = self::getCompatibleClassVersion($checkerClass);
|
71 |
-
if ( $checkerClass === null ) {
|
72 |
-
trigger_error(
|
73 |
-
sprintf(
|
74 |
-
'PUC %s does not support updates for %ss %s',
|
75 |
-
htmlentities(self::$latestCompatibleVersion),
|
76 |
-
strtolower($type),
|
77 |
-
$service ? ('hosted on ' . htmlentities($service)) : 'using JSON metadata'
|
78 |
-
),
|
79 |
-
E_USER_ERROR
|
80 |
-
);
|
81 |
-
return null;
|
82 |
-
}
|
83 |
-
|
84 |
-
if ( !isset($apiClass) ) {
|
85 |
-
//Plain old update checker.
|
86 |
-
return new $checkerClass($metadataUrl, $id, $slug, $checkPeriod, $optionName, $muPluginFile);
|
87 |
-
} else {
|
88 |
-
//VCS checker + an API client.
|
89 |
-
$apiClass = self::getCompatibleClassVersion($apiClass);
|
90 |
-
if ( $apiClass === null ) {
|
91 |
-
trigger_error(sprintf(
|
92 |
-
'PUC %s does not support %s',
|
93 |
-
htmlentities(self::$latestCompatibleVersion),
|
94 |
-
htmlentities($service)
|
95 |
-
), E_USER_ERROR);
|
96 |
-
return null;
|
97 |
-
}
|
98 |
-
|
99 |
-
return new $checkerClass(
|
100 |
-
new $apiClass($metadataUrl),
|
101 |
-
$id,
|
102 |
-
$slug,
|
103 |
-
$checkPeriod,
|
104 |
-
$optionName,
|
105 |
-
$muPluginFile
|
106 |
-
);
|
107 |
-
}
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Check if the path points to a plugin file.
|
112 |
-
*
|
113 |
-
* @param string $absolutePath Normalized path.
|
114 |
-
* @return bool
|
115 |
-
*/
|
116 |
-
protected static function isPluginFile($absolutePath) {
|
117 |
-
//Is the file inside the "plugins" or "mu-plugins" directory?
|
118 |
-
$pluginDir = wp_normalize_path(WP_PLUGIN_DIR);
|
119 |
-
$muPluginDir = wp_normalize_path(WPMU_PLUGIN_DIR);
|
120 |
-
if ( (strpos($absolutePath, $pluginDir) === 0) || (strpos($absolutePath, $muPluginDir) === 0) ) {
|
121 |
-
return true;
|
122 |
-
}
|
123 |
-
|
124 |
-
//Is it a file at all? Caution: is_file() can fail if the parent dir. doesn't have the +x permission set.
|
125 |
-
if ( !is_file($absolutePath) ) {
|
126 |
-
return false;
|
127 |
-
}
|
128 |
-
|
129 |
-
//Does it have a valid plugin header?
|
130 |
-
//This is a last-ditch check for plugins symlinked from outside the WP root.
|
131 |
-
if ( function_exists('get_file_data') ) {
|
132 |
-
$headers = get_file_data($absolutePath, array('Name' => 'Plugin Name'), 'plugin');
|
133 |
-
return !empty($headers['Name']);
|
134 |
-
}
|
135 |
-
|
136 |
-
return false;
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Get the name of the theme's directory from a full path to a file inside that directory.
|
141 |
-
* E.g. "/abc/public_html/wp-content/themes/foo/whatever.php" => "foo".
|
142 |
-
*
|
143 |
-
* Note that subdirectories are currently not supported. For example,
|
144 |
-
* "/xyz/wp-content/themes/my-theme/includes/whatever.php" => NULL.
|
145 |
-
*
|
146 |
-
* @param string $absolutePath Normalized path.
|
147 |
-
* @return string|null Directory name, or NULL if the path doesn't point to a theme.
|
148 |
-
*/
|
149 |
-
protected static function getThemeDirectoryName($absolutePath) {
|
150 |
-
if ( is_file($absolutePath) ) {
|
151 |
-
$absolutePath = dirname($absolutePath);
|
152 |
-
}
|
153 |
-
|
154 |
-
if ( file_exists($absolutePath . '/style.css') ) {
|
155 |
-
return basename($absolutePath);
|
156 |
-
}
|
157 |
-
return null;
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* Get the name of the hosting service that the URL points to.
|
162 |
-
*
|
163 |
-
* @param string $metadataUrl
|
164 |
-
* @return string|null
|
165 |
-
*/
|
166 |
-
private static function getVcsService($metadataUrl) {
|
167 |
-
$service = null;
|
168 |
-
|
169 |
-
//Which hosting service does the URL point to?
|
170 |
-
$host = @parse_url($metadataUrl, PHP_URL_HOST);
|
171 |
-
$path = @parse_url($metadataUrl, PHP_URL_PATH);
|
172 |
-
//Check if the path looks like "/user-name/repository".
|
173 |
-
$usernameRepoRegex = '@^/?([^/]+?)/([^/#?&]+?)/?$@';
|
174 |
-
if ( preg_match($usernameRepoRegex, $path) ) {
|
175 |
-
$knownServices = array(
|
176 |
-
'github.com' => 'GitHub',
|
177 |
-
'bitbucket.org' => 'BitBucket',
|
178 |
-
'gitlab.com' => 'GitLab',
|
179 |
-
);
|
180 |
-
if ( isset($knownServices[$host]) ) {
|
181 |
-
$service = $knownServices[$host];
|
182 |
-
}
|
183 |
-
}
|
184 |
-
|
185 |
-
return $service;
|
186 |
-
}
|
187 |
-
|
188 |
-
/**
|
189 |
-
* Get the latest version of the specified class that has the same major version number
|
190 |
-
* as this factory class.
|
191 |
-
*
|
192 |
-
* @param string $class Partial class name.
|
193 |
-
* @return string|null Full class name.
|
194 |
-
*/
|
195 |
-
protected static function getCompatibleClassVersion($class) {
|
196 |
-
if ( isset(self::$classVersions[$class][self::$latestCompatibleVersion]) ) {
|
197 |
-
return self::$classVersions[$class][self::$latestCompatibleVersion];
|
198 |
-
}
|
199 |
-
return null;
|
200 |
-
}
|
201 |
-
|
202 |
-
/**
|
203 |
-
* Get the specific class name for the latest available version of a class.
|
204 |
-
*
|
205 |
-
* @param string $class
|
206 |
-
* @return null|string
|
207 |
-
*/
|
208 |
-
public static function getLatestClassVersion($class) {
|
209 |
-
if ( !self::$sorted ) {
|
210 |
-
self::sortVersions();
|
211 |
-
}
|
212 |
-
|
213 |
-
if ( isset(self::$classVersions[$class]) ) {
|
214 |
-
return reset(self::$classVersions[$class]);
|
215 |
-
} else {
|
216 |
-
return null;
|
217 |
-
}
|
218 |
-
}
|
219 |
-
|
220 |
-
/**
|
221 |
-
* Sort available class versions in descending order (i.e. newest first).
|
222 |
-
*/
|
223 |
-
protected static function sortVersions() {
|
224 |
-
foreach ( self::$classVersions as $class => $versions ) {
|
225 |
-
uksort($versions, array(__CLASS__, 'compareVersions'));
|
226 |
-
self::$classVersions[$class] = $versions;
|
227 |
-
}
|
228 |
-
self::$sorted = true;
|
229 |
-
}
|
230 |
-
|
231 |
-
protected static function compareVersions($a, $b) {
|
232 |
-
return -version_compare($a, $b);
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* Register a version of a class.
|
237 |
-
*
|
238 |
-
* @access private This method is only for internal use by the library.
|
239 |
-
*
|
240 |
-
* @param string $generalClass Class name without version numbers, e.g. 'PluginUpdateChecker'.
|
241 |
-
* @param string $versionedClass Actual class name, e.g. 'PluginUpdateChecker_1_2'.
|
242 |
-
* @param string $version Version number, e.g. '1.2'.
|
243 |
-
*/
|
244 |
-
public static function addVersion($generalClass, $versionedClass, $version) {
|
245 |
-
if ( empty(self::$myMajorVersion) ) {
|
246 |
-
$nameParts = explode('_', __CLASS__, 3);
|
247 |
-
self::$myMajorVersion = substr(ltrim($nameParts[1], 'v'), 0, 1);
|
248 |
-
}
|
249 |
-
|
250 |
-
//Store the greatest version number that matches our major version.
|
251 |
-
$components = explode('.', $version);
|
252 |
-
if ( $components[0] === self::$myMajorVersion ) {
|
253 |
-
|
254 |
-
if (
|
255 |
-
empty(self::$latestCompatibleVersion)
|
256 |
-
|| version_compare($version, self::$latestCompatibleVersion, '>')
|
257 |
-
) {
|
258 |
-
self::$latestCompatibleVersion = $version;
|
259 |
-
}
|
260 |
-
|
261 |
-
}
|
262 |
-
|
263 |
-
if ( !isset(self::$classVersions[$generalClass]) ) {
|
264 |
-
self::$classVersions[$generalClass] = array();
|
265 |
-
}
|
266 |
-
self::$classVersions[$generalClass][$version] = $versionedClass;
|
267 |
-
self::$sorted = false;
|
268 |
-
}
|
269 |
-
}
|
270 |
-
|
271 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Autoloader.php
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_Autoloader', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_Autoloader {
|
6 |
-
private $prefix = '';
|
7 |
-
private $rootDir = '';
|
8 |
-
private $libraryDir = '';
|
9 |
-
|
10 |
-
private $staticMap;
|
11 |
-
|
12 |
-
public function __construct() {
|
13 |
-
$this->rootDir = dirname(__FILE__) . '/';
|
14 |
-
$nameParts = explode('_', __CLASS__, 3);
|
15 |
-
$this->prefix = $nameParts[0] . '_' . $nameParts[1] . '_';
|
16 |
-
|
17 |
-
$this->libraryDir = realpath($this->rootDir . '../..') . '/';
|
18 |
-
$this->staticMap = array(
|
19 |
-
'PucReadmeParser' => 'vendor/readme-parser.php',
|
20 |
-
'Parsedown' => 'vendor/ParsedownLegacy.php',
|
21 |
-
);
|
22 |
-
if ( version_compare(PHP_VERSION, '5.3.0', '>=') ) {
|
23 |
-
$this->staticMap['Parsedown'] = 'vendor/Parsedown.php';
|
24 |
-
}
|
25 |
-
|
26 |
-
spl_autoload_register(array($this, 'autoload'));
|
27 |
-
}
|
28 |
-
|
29 |
-
public function autoload($className) {
|
30 |
-
if ( isset($this->staticMap[$className]) && file_exists($this->libraryDir . $this->staticMap[$className]) ) {
|
31 |
-
/** @noinspection PhpIncludeInspection */
|
32 |
-
include ($this->libraryDir . $this->staticMap[$className]);
|
33 |
-
return;
|
34 |
-
}
|
35 |
-
|
36 |
-
if (strpos($className, $this->prefix) === 0) {
|
37 |
-
$path = substr($className, strlen($this->prefix));
|
38 |
-
$path = str_replace('_', '/', $path);
|
39 |
-
$path = $this->rootDir . $path . '.php';
|
40 |
-
|
41 |
-
if (file_exists($path)) {
|
42 |
-
/** @noinspection PhpIncludeInspection */
|
43 |
-
include $path;
|
44 |
-
}
|
45 |
-
}
|
46 |
-
}
|
47 |
-
}
|
48 |
-
|
49 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/Extension.php
DELETED
@@ -1,117 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_DebugBar_Extension', false) ):
|
3 |
-
|
4 |
-
class Puc_v4p1_DebugBar_Extension {
|
5 |
-
/** @var Puc_v4p1_UpdateChecker */
|
6 |
-
protected $updateChecker;
|
7 |
-
protected $panelClass = 'Puc_v4p1_DebugBar_Panel';
|
8 |
-
|
9 |
-
public function __construct($updateChecker, $panelClass = null) {
|
10 |
-
$this->updateChecker = $updateChecker;
|
11 |
-
if ( isset($panelClass) ) {
|
12 |
-
$this->panelClass = $panelClass;
|
13 |
-
}
|
14 |
-
|
15 |
-
add_filter('debug_bar_panels', array($this, 'addDebugBarPanel'));
|
16 |
-
add_action('debug_bar_enqueue_scripts', array($this, 'enqueuePanelDependencies'));
|
17 |
-
|
18 |
-
add_action('wp_ajax_puc_v4_debug_check_now', array($this, 'ajaxCheckNow'));
|
19 |
-
}
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Register the PUC Debug Bar panel.
|
23 |
-
*
|
24 |
-
* @param array $panels
|
25 |
-
* @return array
|
26 |
-
*/
|
27 |
-
public function addDebugBarPanel($panels) {
|
28 |
-
if ( $this->updateChecker->userCanInstallUpdates() ) {
|
29 |
-
$panels[] = new $this->panelClass($this->updateChecker);
|
30 |
-
}
|
31 |
-
return $panels;
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Enqueue our Debug Bar scripts and styles.
|
36 |
-
*/
|
37 |
-
public function enqueuePanelDependencies() {
|
38 |
-
wp_enqueue_style(
|
39 |
-
'puc-debug-bar-style-v4',
|
40 |
-
$this->getLibraryUrl("/css/puc-debug-bar.css"),
|
41 |
-
array('debug-bar'),
|
42 |
-
'20161217'
|
43 |
-
);
|
44 |
-
|
45 |
-
wp_enqueue_script(
|
46 |
-
'puc-debug-bar-js-v4',
|
47 |
-
$this->getLibraryUrl("/js/debug-bar.js"),
|
48 |
-
array('jquery'),
|
49 |
-
'20170516'
|
50 |
-
);
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Run an update check and output the result. Useful for making sure that
|
55 |
-
* the update checking process works as expected.
|
56 |
-
*/
|
57 |
-
public function ajaxCheckNow() {
|
58 |
-
if ( $_POST['uid'] !== $this->updateChecker->getUniqueName('uid') ) {
|
59 |
-
return;
|
60 |
-
}
|
61 |
-
$this->preAjaxReqest();
|
62 |
-
$update = $this->updateChecker->checkForUpdates();
|
63 |
-
if ( $update !== null ) {
|
64 |
-
echo "An update is available:";
|
65 |
-
echo '<pre>', htmlentities(print_r($update, true)), '</pre>';
|
66 |
-
} else {
|
67 |
-
echo 'No updates found.';
|
68 |
-
}
|
69 |
-
exit;
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Check access permissions and enable error display (for debugging).
|
74 |
-
*/
|
75 |
-
protected function preAjaxReqest() {
|
76 |
-
if ( !$this->updateChecker->userCanInstallUpdates() ) {
|
77 |
-
die('Access denied');
|
78 |
-
}
|
79 |
-
check_ajax_referer('puc-ajax');
|
80 |
-
|
81 |
-
error_reporting(E_ALL);
|
82 |
-
@ini_set('display_errors','On');
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* @param string $filePath
|
87 |
-
* @return string
|
88 |
-
*/
|
89 |
-
private function getLibraryUrl($filePath) {
|
90 |
-
$absolutePath = realpath(dirname(__FILE__) . '/../../../' . ltrim($filePath, '/'));
|
91 |
-
|
92 |
-
//Where is the library located inside the WordPress directory structure?
|
93 |
-
$absolutePath = wp_normalize_path($absolutePath);
|
94 |
-
|
95 |
-
$pluginDir = wp_normalize_path(WP_PLUGIN_DIR);
|
96 |
-
$muPluginDir = wp_normalize_path(WPMU_PLUGIN_DIR);
|
97 |
-
$themeDir = wp_normalize_path(get_theme_root());
|
98 |
-
|
99 |
-
if ( (strpos($absolutePath, $pluginDir) === 0) || (strpos($absolutePath, $muPluginDir) === 0) ) {
|
100 |
-
//It's part of a plugin.
|
101 |
-
return plugins_url(basename($absolutePath), $absolutePath);
|
102 |
-
} else if ( strpos($absolutePath, $themeDir) === 0 ) {
|
103 |
-
//It's part of a theme.
|
104 |
-
$relativePath = substr($absolutePath, strlen($themeDir) + 1);
|
105 |
-
$template = substr($relativePath, 0, strpos($relativePath, '/'));
|
106 |
-
$baseUrl = get_theme_root_uri($template);
|
107 |
-
|
108 |
-
if ( !empty($baseUrl) && $relativePath ) {
|
109 |
-
return $baseUrl . '/' . $relativePath;
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
return '';
|
114 |
-
}
|
115 |
-
}
|
116 |
-
|
117 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/Panel.php
DELETED
@@ -1,165 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_DebugBar_Panel', false) && class_exists('Debug_Bar_Panel', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_DebugBar_Panel extends Debug_Bar_Panel {
|
6 |
-
/** @var Puc_v4p1_UpdateChecker */
|
7 |
-
protected $updateChecker;
|
8 |
-
|
9 |
-
private $responseBox = '<div class="puc-ajax-response" style="display: none;"></div>';
|
10 |
-
|
11 |
-
public function __construct($updateChecker) {
|
12 |
-
$this->updateChecker = $updateChecker;
|
13 |
-
$title = sprintf(
|
14 |
-
'<span class="puc-debug-menu-link-%s">PUC (%s)</span>',
|
15 |
-
esc_attr($this->updateChecker->getUniqueName('uid')),
|
16 |
-
$this->updateChecker->slug
|
17 |
-
);
|
18 |
-
parent::__construct($title);
|
19 |
-
}
|
20 |
-
|
21 |
-
public function render() {
|
22 |
-
printf(
|
23 |
-
'<div class="puc-debug-bar-panel-v4" id="%1$s" data-slug="%2$s" data-uid="%3$s" data-nonce="%4$s">',
|
24 |
-
esc_attr($this->updateChecker->getUniqueName('debug-bar-panel')),
|
25 |
-
esc_attr($this->updateChecker->slug),
|
26 |
-
esc_attr($this->updateChecker->getUniqueName('uid')),
|
27 |
-
esc_attr(wp_create_nonce('puc-ajax'))
|
28 |
-
);
|
29 |
-
|
30 |
-
$this->displayConfiguration();
|
31 |
-
$this->displayStatus();
|
32 |
-
$this->displayCurrentUpdate();
|
33 |
-
|
34 |
-
echo '</div>';
|
35 |
-
}
|
36 |
-
|
37 |
-
private function displayConfiguration() {
|
38 |
-
echo '<h3>Configuration</h3>';
|
39 |
-
echo '<table class="puc-debug-data">';
|
40 |
-
$this->displayConfigHeader();
|
41 |
-
$this->row('Slug', htmlentities($this->updateChecker->slug));
|
42 |
-
$this->row('DB option', htmlentities($this->updateChecker->optionName));
|
43 |
-
|
44 |
-
$requestInfoButton = $this->getMetadataButton();
|
45 |
-
$this->row('Metadata URL', htmlentities($this->updateChecker->metadataUrl) . ' ' . $requestInfoButton . $this->responseBox);
|
46 |
-
|
47 |
-
$scheduler = $this->updateChecker->scheduler;
|
48 |
-
if ( $scheduler->checkPeriod > 0 ) {
|
49 |
-
$this->row('Automatic checks', 'Every ' . $scheduler->checkPeriod . ' hours');
|
50 |
-
} else {
|
51 |
-
$this->row('Automatic checks', 'Disabled');
|
52 |
-
}
|
53 |
-
|
54 |
-
if ( isset($scheduler->throttleRedundantChecks) ) {
|
55 |
-
if ( $scheduler->throttleRedundantChecks && ($scheduler->checkPeriod > 0) ) {
|
56 |
-
$this->row(
|
57 |
-
'Throttling',
|
58 |
-
sprintf(
|
59 |
-
'Enabled. If an update is already available, check for updates every %1$d hours instead of every %2$d hours.',
|
60 |
-
$scheduler->throttledCheckPeriod,
|
61 |
-
$scheduler->checkPeriod
|
62 |
-
)
|
63 |
-
);
|
64 |
-
} else {
|
65 |
-
$this->row('Throttling', 'Disabled');
|
66 |
-
}
|
67 |
-
}
|
68 |
-
|
69 |
-
$this->updateChecker->onDisplayConfiguration($this);
|
70 |
-
|
71 |
-
echo '</table>';
|
72 |
-
}
|
73 |
-
|
74 |
-
protected function displayConfigHeader() {
|
75 |
-
//Do nothing. This should be implemented in subclasses.
|
76 |
-
}
|
77 |
-
|
78 |
-
protected function getMetadataButton() {
|
79 |
-
return '';
|
80 |
-
}
|
81 |
-
|
82 |
-
private function displayStatus() {
|
83 |
-
echo '<h3>Status</h3>';
|
84 |
-
echo '<table class="puc-debug-data">';
|
85 |
-
$state = $this->updateChecker->getUpdateState();
|
86 |
-
$checkNowButton = '';
|
87 |
-
if ( function_exists('get_submit_button') ) {
|
88 |
-
$checkNowButton = get_submit_button(
|
89 |
-
'Check Now',
|
90 |
-
'secondary',
|
91 |
-
'puc-check-now-button',
|
92 |
-
false,
|
93 |
-
array('id' => $this->updateChecker->getUniqueName('check-now-button'))
|
94 |
-
);
|
95 |
-
}
|
96 |
-
|
97 |
-
if ( $state->getLastCheck() > 0 ) {
|
98 |
-
$this->row('Last check', $this->formatTimeWithDelta($state->getLastCheck()) . ' ' . $checkNowButton . $this->responseBox);
|
99 |
-
} else {
|
100 |
-
$this->row('Last check', 'Never');
|
101 |
-
}
|
102 |
-
|
103 |
-
$nextCheck = wp_next_scheduled($this->updateChecker->scheduler->getCronHookName());
|
104 |
-
$this->row('Next automatic check', $this->formatTimeWithDelta($nextCheck));
|
105 |
-
|
106 |
-
if ( $state->getCheckedVersion() !== '' ) {
|
107 |
-
$this->row('Checked version', htmlentities($state->getCheckedVersion()));
|
108 |
-
$this->row('Cached update', $state->getUpdate());
|
109 |
-
}
|
110 |
-
$this->row('Update checker class', htmlentities(get_class($this->updateChecker)));
|
111 |
-
echo '</table>';
|
112 |
-
}
|
113 |
-
|
114 |
-
private function displayCurrentUpdate() {
|
115 |
-
$update = $this->updateChecker->getUpdate();
|
116 |
-
if ( $update !== null ) {
|
117 |
-
echo '<h3>An Update Is Available</h3>';
|
118 |
-
echo '<table class="puc-debug-data">';
|
119 |
-
$fields = $this->getUpdateFields();
|
120 |
-
foreach($fields as $field) {
|
121 |
-
if ( property_exists($update, $field) ) {
|
122 |
-
$this->row(ucwords(str_replace('_', ' ', $field)), htmlentities($update->$field));
|
123 |
-
}
|
124 |
-
}
|
125 |
-
echo '</table>';
|
126 |
-
} else {
|
127 |
-
echo '<h3>No updates currently available</h3>';
|
128 |
-
}
|
129 |
-
}
|
130 |
-
|
131 |
-
protected function getUpdateFields() {
|
132 |
-
return array('version', 'download_url', 'slug',);
|
133 |
-
}
|
134 |
-
|
135 |
-
private function formatTimeWithDelta($unixTime) {
|
136 |
-
if ( empty($unixTime) ) {
|
137 |
-
return 'Never';
|
138 |
-
}
|
139 |
-
|
140 |
-
$delta = time() - $unixTime;
|
141 |
-
$result = human_time_diff(time(), $unixTime);
|
142 |
-
if ( $delta < 0 ) {
|
143 |
-
$result = 'after ' . $result;
|
144 |
-
} else {
|
145 |
-
$result = $result . ' ago';
|
146 |
-
}
|
147 |
-
$result .= ' (' . $this->formatTimestamp($unixTime) . ')';
|
148 |
-
return $result;
|
149 |
-
}
|
150 |
-
|
151 |
-
private function formatTimestamp($unixTime) {
|
152 |
-
return gmdate('Y-m-d H:i:s', $unixTime + (get_option('gmt_offset') * 3600));
|
153 |
-
}
|
154 |
-
|
155 |
-
public function row($name, $value) {
|
156 |
-
if ( is_object($value) || is_array($value) ) {
|
157 |
-
$value = '<pre>' . htmlentities(print_r($value, true)) . '</pre>';
|
158 |
-
} else if ($value === null) {
|
159 |
-
$value = '<code>null</code>';
|
160 |
-
}
|
161 |
-
printf('<tr><th scope="row">%1$s</th> <td>%2$s</td></tr>', $name, $value);
|
162 |
-
}
|
163 |
-
}
|
164 |
-
|
165 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/PluginExtension.php
DELETED
@@ -1,33 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_DebugBar_PluginExtension', false) ):
|
3 |
-
|
4 |
-
class Puc_v4p1_DebugBar_PluginExtension extends Puc_v4p1_DebugBar_Extension {
|
5 |
-
/** @var Puc_v4p1_Plugin_UpdateChecker */
|
6 |
-
protected $updateChecker;
|
7 |
-
|
8 |
-
public function __construct($updateChecker) {
|
9 |
-
parent::__construct($updateChecker, 'Puc_v4p1_DebugBar_PluginPanel');
|
10 |
-
|
11 |
-
add_action('wp_ajax_puc_v4_debug_request_info', array($this, 'ajaxRequestInfo'));
|
12 |
-
}
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Request plugin info and output it.
|
16 |
-
*/
|
17 |
-
public function ajaxRequestInfo() {
|
18 |
-
if ( $_POST['uid'] !== $this->updateChecker->getUniqueName('uid') ) {
|
19 |
-
return;
|
20 |
-
}
|
21 |
-
$this->preAjaxReqest();
|
22 |
-
$info = $this->updateChecker->requestInfo();
|
23 |
-
if ( $info !== null ) {
|
24 |
-
echo 'Successfully retrieved plugin info from the metadata URL:';
|
25 |
-
echo '<pre>', htmlentities(print_r($info, true)), '</pre>';
|
26 |
-
} else {
|
27 |
-
echo 'Failed to retrieve plugin info from the metadata URL.';
|
28 |
-
}
|
29 |
-
exit;
|
30 |
-
}
|
31 |
-
}
|
32 |
-
|
33 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/PluginPanel.php
DELETED
@@ -1,38 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_DebugBar_PluginPanel', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_DebugBar_PluginPanel extends Puc_v4p1_DebugBar_Panel {
|
6 |
-
/**
|
7 |
-
* @var Puc_v4p1_Plugin_UpdateChecker
|
8 |
-
*/
|
9 |
-
protected $updateChecker;
|
10 |
-
|
11 |
-
protected function displayConfigHeader() {
|
12 |
-
$this->row('Plugin file', htmlentities($this->updateChecker->pluginFile));
|
13 |
-
parent::displayConfigHeader();
|
14 |
-
}
|
15 |
-
|
16 |
-
protected function getMetadataButton() {
|
17 |
-
$requestInfoButton = '';
|
18 |
-
if ( function_exists('get_submit_button') ) {
|
19 |
-
$requestInfoButton = get_submit_button(
|
20 |
-
'Request Info',
|
21 |
-
'secondary',
|
22 |
-
'puc-request-info-button',
|
23 |
-
false,
|
24 |
-
array('id' => $this->updateChecker->getUniqueName('request-info-button'))
|
25 |
-
);
|
26 |
-
}
|
27 |
-
return $requestInfoButton;
|
28 |
-
}
|
29 |
-
|
30 |
-
protected function getUpdateFields() {
|
31 |
-
return array_merge(
|
32 |
-
parent::getUpdateFields(),
|
33 |
-
array('homepage', 'upgrade_notice', 'tested',)
|
34 |
-
);
|
35 |
-
}
|
36 |
-
}
|
37 |
-
|
38 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/DebugBar/ThemePanel.php
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_DebugBar_ThemePanel', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_DebugBar_ThemePanel extends Puc_v4p1_DebugBar_Panel {
|
6 |
-
/**
|
7 |
-
* @var Puc_v4p1_Theme_UpdateChecker
|
8 |
-
*/
|
9 |
-
protected $updateChecker;
|
10 |
-
|
11 |
-
protected function displayConfigHeader() {
|
12 |
-
$this->row('Theme directory', htmlentities($this->updateChecker->directoryName));
|
13 |
-
parent::displayConfigHeader();
|
14 |
-
}
|
15 |
-
|
16 |
-
protected function getUpdateFields() {
|
17 |
-
return array_merge(parent::getUpdateFields(), array('details_url'));
|
18 |
-
}
|
19 |
-
}
|
20 |
-
|
21 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Metadata.php
DELETED
@@ -1,132 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Metadata', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A base container for holding information about updates and plugin metadata.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @copyright 2016
|
9 |
-
* @access public
|
10 |
-
*/
|
11 |
-
abstract class Puc_v4p1_Metadata {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Create an instance of this class from a JSON document.
|
15 |
-
*
|
16 |
-
* @abstract
|
17 |
-
* @param string $json
|
18 |
-
* @return self
|
19 |
-
*/
|
20 |
-
public static function fromJson(/** @noinspection PhpUnusedParameterInspection */ $json) {
|
21 |
-
throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @param string $json
|
26 |
-
* @param self $target
|
27 |
-
* @return bool
|
28 |
-
*/
|
29 |
-
protected static function createFromJson($json, $target) {
|
30 |
-
/** @var StdClass $apiResponse */
|
31 |
-
$apiResponse = json_decode($json);
|
32 |
-
if ( empty($apiResponse) || !is_object($apiResponse) ){
|
33 |
-
trigger_error(
|
34 |
-
"Failed to parse update metadata. Try validating your .json file with http://jsonlint.com/",
|
35 |
-
E_USER_NOTICE
|
36 |
-
);
|
37 |
-
return false;
|
38 |
-
}
|
39 |
-
|
40 |
-
$valid = $target->validateMetadata($apiResponse);
|
41 |
-
if ( is_wp_error($valid) ){
|
42 |
-
trigger_error($valid->get_error_message(), E_USER_NOTICE);
|
43 |
-
return false;
|
44 |
-
}
|
45 |
-
|
46 |
-
foreach(get_object_vars($apiResponse) as $key => $value){
|
47 |
-
$target->$key = $value;
|
48 |
-
}
|
49 |
-
|
50 |
-
return true;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* No validation by default! Subclasses should check that the required fields are present.
|
55 |
-
*
|
56 |
-
* @param StdClass $apiResponse
|
57 |
-
* @return bool|WP_Error
|
58 |
-
*/
|
59 |
-
protected function validateMetadata(/** @noinspection PhpUnusedParameterInspection */ $apiResponse) {
|
60 |
-
return true;
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Create a new instance by copying the necessary fields from another object.
|
65 |
-
*
|
66 |
-
* @abstract
|
67 |
-
* @param StdClass|self $object The source object.
|
68 |
-
* @return self The new copy.
|
69 |
-
*/
|
70 |
-
public static function fromObject(/** @noinspection PhpUnusedParameterInspection */ $object) {
|
71 |
-
throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Create an instance of StdClass that can later be converted back to an
|
76 |
-
* update or info container. Useful for serialization and caching, as it
|
77 |
-
* avoids the "incomplete object" problem if the cached value is loaded
|
78 |
-
* before this class.
|
79 |
-
*
|
80 |
-
* @return StdClass
|
81 |
-
*/
|
82 |
-
public function toStdClass() {
|
83 |
-
$object = new stdClass();
|
84 |
-
$this->copyFields($this, $object);
|
85 |
-
return $object;
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Transform the metadata into the format used by WordPress core.
|
90 |
-
*
|
91 |
-
* @return object
|
92 |
-
*/
|
93 |
-
abstract public function toWpFormat();
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Copy known fields from one object to another.
|
97 |
-
*
|
98 |
-
* @param StdClass|self $from
|
99 |
-
* @param StdClass|self $to
|
100 |
-
*/
|
101 |
-
protected function copyFields($from, $to) {
|
102 |
-
$fields = $this->getFieldNames();
|
103 |
-
|
104 |
-
if ( property_exists($from, 'slug') && !empty($from->slug) ) {
|
105 |
-
//Let plugins add extra fields without having to create subclasses.
|
106 |
-
$fields = apply_filters($this->getPrefixedFilter('retain_fields') . '-' . $from->slug, $fields);
|
107 |
-
}
|
108 |
-
|
109 |
-
foreach ($fields as $field) {
|
110 |
-
if ( property_exists($from, $field) ) {
|
111 |
-
$to->$field = $from->$field;
|
112 |
-
}
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* @return string[]
|
118 |
-
*/
|
119 |
-
protected function getFieldNames() {
|
120 |
-
return array();
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* @param string $tag
|
125 |
-
* @return string
|
126 |
-
*/
|
127 |
-
protected function getPrefixedFilter($tag) {
|
128 |
-
return 'puc_' . $tag;
|
129 |
-
}
|
130 |
-
}
|
131 |
-
|
132 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/OAuthSignature.php
DELETED
@@ -1,88 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_OAuthSignature', false) ):
|
4 |
-
|
5 |
-
/**
|
6 |
-
* A basic signature generator for zero-legged OAuth 1.0.
|
7 |
-
*/
|
8 |
-
class Puc_v4p1_OAuthSignature {
|
9 |
-
private $consumerKey = '';
|
10 |
-
private $consumerSecret = '';
|
11 |
-
|
12 |
-
public function __construct($consumerKey, $consumerSecret) {
|
13 |
-
$this->consumerKey = $consumerKey;
|
14 |
-
$this->consumerSecret = $consumerSecret;
|
15 |
-
}
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Sign a URL using OAuth 1.0.
|
19 |
-
*
|
20 |
-
* @param string $url The URL to be signed. It may contain query parameters.
|
21 |
-
* @param string $method HTTP method such as "GET", "POST" and so on.
|
22 |
-
* @return string The signed URL.
|
23 |
-
*/
|
24 |
-
public function sign($url, $method = 'GET') {
|
25 |
-
$parameters = array();
|
26 |
-
|
27 |
-
//Parse query parameters.
|
28 |
-
$query = @parse_url($url, PHP_URL_QUERY);
|
29 |
-
if ( !empty($query) ) {
|
30 |
-
parse_str($query, $parsedParams);
|
31 |
-
if ( is_array($parameters) ) {
|
32 |
-
$parameters = $parsedParams;
|
33 |
-
}
|
34 |
-
//Remove the query string from the URL. We'll replace it later.
|
35 |
-
$url = substr($url, 0, strpos($url, '?'));
|
36 |
-
}
|
37 |
-
|
38 |
-
$parameters = array_merge(
|
39 |
-
$parameters,
|
40 |
-
array(
|
41 |
-
'oauth_consumer_key' => $this->consumerKey,
|
42 |
-
'oauth_nonce' => $this->nonce(),
|
43 |
-
'oauth_signature_method' => 'HMAC-SHA1',
|
44 |
-
'oauth_timestamp' => time(),
|
45 |
-
'oauth_version' => '1.0',
|
46 |
-
)
|
47 |
-
);
|
48 |
-
unset($parameters['oauth_signature']);
|
49 |
-
|
50 |
-
//Parameters must be sorted alphabetically before signing.
|
51 |
-
ksort($parameters);
|
52 |
-
|
53 |
-
//The most complicated part of the request - generating the signature.
|
54 |
-
//The string to sign contains the HTTP method, the URL path, and all of
|
55 |
-
//our query parameters. Everything is URL encoded. Then we concatenate
|
56 |
-
//them with ampersands into a single string to hash.
|
57 |
-
$encodedVerb = urlencode($method);
|
58 |
-
$encodedUrl = urlencode($url);
|
59 |
-
$encodedParams = urlencode(http_build_query($parameters, '', '&'));
|
60 |
-
|
61 |
-
$stringToSign = $encodedVerb . '&' . $encodedUrl . '&' . $encodedParams;
|
62 |
-
|
63 |
-
//Since we only have one OAuth token (the consumer secret) we only have
|
64 |
-
//to use it as our HMAC key. However, we still have to append an & to it
|
65 |
-
//as if we were using it with additional tokens.
|
66 |
-
$secret = urlencode($this->consumerSecret) . '&';
|
67 |
-
|
68 |
-
//The signature is a hash of the consumer key and the base string. Note
|
69 |
-
//that we have to get the raw output from hash_hmac and base64 encode
|
70 |
-
//the binary data result.
|
71 |
-
$parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $stringToSign, $secret, true));
|
72 |
-
|
73 |
-
return ($url . '?' . http_build_query($parameters));
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Generate a random nonce.
|
78 |
-
*
|
79 |
-
* @return string
|
80 |
-
*/
|
81 |
-
private function nonce() {
|
82 |
-
$mt = microtime();
|
83 |
-
$rand = mt_rand();
|
84 |
-
return md5($mt . '_' . $rand);
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Plugin/Info.php
DELETED
@@ -1,127 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Plugin_Info', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A container class for holding and transforming various plugin metadata.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @copyright 2016
|
9 |
-
* @access public
|
10 |
-
*/
|
11 |
-
class Puc_v4p1_Plugin_Info extends Puc_v4p1_Metadata {
|
12 |
-
//Most fields map directly to the contents of the plugin's info.json file.
|
13 |
-
//See the relevant docs for a description of their meaning.
|
14 |
-
public $name;
|
15 |
-
public $slug;
|
16 |
-
public $version;
|
17 |
-
public $homepage;
|
18 |
-
public $sections = array();
|
19 |
-
public $banners;
|
20 |
-
public $translations = array();
|
21 |
-
public $download_url;
|
22 |
-
|
23 |
-
public $author;
|
24 |
-
public $author_homepage;
|
25 |
-
|
26 |
-
public $requires;
|
27 |
-
public $tested;
|
28 |
-
public $upgrade_notice;
|
29 |
-
|
30 |
-
public $rating;
|
31 |
-
public $num_ratings;
|
32 |
-
public $downloaded;
|
33 |
-
public $active_installs;
|
34 |
-
public $last_updated;
|
35 |
-
|
36 |
-
public $id = 0; //The native WP.org API returns numeric plugin IDs, but they're not used for anything.
|
37 |
-
|
38 |
-
public $filename; //Plugin filename relative to the plugins directory.
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Create a new instance of Plugin Info from JSON-encoded plugin info
|
42 |
-
* returned by an external update API.
|
43 |
-
*
|
44 |
-
* @param string $json Valid JSON string representing plugin info.
|
45 |
-
* @return self|null New instance of Plugin Info, or NULL on error.
|
46 |
-
*/
|
47 |
-
public static function fromJson($json){
|
48 |
-
$instance = new self();
|
49 |
-
|
50 |
-
if ( !parent::createFromJson($json, $instance) ) {
|
51 |
-
return null;
|
52 |
-
}
|
53 |
-
|
54 |
-
//json_decode decodes assoc. arrays as objects. We want it as an array.
|
55 |
-
$instance->sections = (array)$instance->sections;
|
56 |
-
|
57 |
-
return $instance;
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Very, very basic validation.
|
62 |
-
*
|
63 |
-
* @param StdClass $apiResponse
|
64 |
-
* @return bool|WP_Error
|
65 |
-
*/
|
66 |
-
protected function validateMetadata($apiResponse) {
|
67 |
-
if (
|
68 |
-
!isset($apiResponse->name, $apiResponse->version)
|
69 |
-
|| empty($apiResponse->name)
|
70 |
-
|| empty($apiResponse->version)
|
71 |
-
) {
|
72 |
-
return new WP_Error(
|
73 |
-
'puc-invalid-metadata',
|
74 |
-
"The plugin metadata file does not contain the required 'name' and/or 'version' keys."
|
75 |
-
);
|
76 |
-
}
|
77 |
-
return true;
|
78 |
-
}
|
79 |
-
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Transform plugin info into the format used by the native WordPress.org API
|
83 |
-
*
|
84 |
-
* @return object
|
85 |
-
*/
|
86 |
-
public function toWpFormat(){
|
87 |
-
$info = new stdClass;
|
88 |
-
|
89 |
-
//The custom update API is built so that many fields have the same name and format
|
90 |
-
//as those returned by the native WordPress.org API. These can be assigned directly.
|
91 |
-
$sameFormat = array(
|
92 |
-
'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice',
|
93 |
-
'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated',
|
94 |
-
);
|
95 |
-
foreach($sameFormat as $field){
|
96 |
-
if ( isset($this->$field) ) {
|
97 |
-
$info->$field = $this->$field;
|
98 |
-
} else {
|
99 |
-
$info->$field = null;
|
100 |
-
}
|
101 |
-
}
|
102 |
-
|
103 |
-
//Other fields need to be renamed and/or transformed.
|
104 |
-
$info->download_link = $this->download_url;
|
105 |
-
$info->author = $this->getFormattedAuthor();
|
106 |
-
$info->sections = array_merge(array('description' => ''), $this->sections);
|
107 |
-
|
108 |
-
if ( !empty($this->banners) ) {
|
109 |
-
//WP expects an array with two keys: "high" and "low". Both are optional.
|
110 |
-
//Docs: https://wordpress.org/plugins/about/faq/#banners
|
111 |
-
$info->banners = is_object($this->banners) ? get_object_vars($this->banners) : $this->banners;
|
112 |
-
$info->banners = array_intersect_key($info->banners, array('high' => true, 'low' => true));
|
113 |
-
}
|
114 |
-
|
115 |
-
return $info;
|
116 |
-
}
|
117 |
-
|
118 |
-
protected function getFormattedAuthor() {
|
119 |
-
if ( !empty($this->author_homepage) ){
|
120 |
-
/** @noinspection HtmlUnknownTarget */
|
121 |
-
return sprintf('<a href="%s">%s</a>', $this->author_homepage, $this->author);
|
122 |
-
}
|
123 |
-
return $this->author;
|
124 |
-
}
|
125 |
-
}
|
126 |
-
|
127 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Plugin/Update.php
DELETED
@@ -1,91 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Plugin_Update', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A simple container class for holding information about an available update.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @copyright 2016
|
9 |
-
* @access public
|
10 |
-
*/
|
11 |
-
class Puc_v4p1_Plugin_Update extends Puc_v4p1_Update {
|
12 |
-
public $id = 0;
|
13 |
-
public $homepage;
|
14 |
-
public $upgrade_notice;
|
15 |
-
public $tested;
|
16 |
-
public $filename; //Plugin filename relative to the plugins directory.
|
17 |
-
|
18 |
-
protected static $extraFields = array(
|
19 |
-
'id', 'homepage', 'tested', 'upgrade_notice', 'filename',
|
20 |
-
);
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Create a new instance of PluginUpdate from its JSON-encoded representation.
|
24 |
-
*
|
25 |
-
* @param string $json
|
26 |
-
* @return Puc_v4p1_Plugin_Update|null
|
27 |
-
*/
|
28 |
-
public static function fromJson($json){
|
29 |
-
//Since update-related information is simply a subset of the full plugin info,
|
30 |
-
//we can parse the update JSON as if it was a plugin info string, then copy over
|
31 |
-
//the parts that we care about.
|
32 |
-
$pluginInfo = Puc_v4p1_Plugin_Info::fromJson($json);
|
33 |
-
if ( $pluginInfo != null ) {
|
34 |
-
return self::fromPluginInfo($pluginInfo);
|
35 |
-
} else {
|
36 |
-
return null;
|
37 |
-
}
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Create a new instance of PluginUpdate based on an instance of PluginInfo.
|
42 |
-
* Basically, this just copies a subset of fields from one object to another.
|
43 |
-
*
|
44 |
-
* @param Puc_v4p1_Plugin_Info $info
|
45 |
-
* @return Puc_v4p1_Plugin_Update
|
46 |
-
*/
|
47 |
-
public static function fromPluginInfo($info){
|
48 |
-
return self::fromObject($info);
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Create a new instance by copying the necessary fields from another object.
|
53 |
-
*
|
54 |
-
* @param StdClass|Puc_v4p1_Plugin_Info|Puc_v4p1_Plugin_Update $object The source object.
|
55 |
-
* @return Puc_v4p1_Plugin_Update The new copy.
|
56 |
-
*/
|
57 |
-
public static function fromObject($object) {
|
58 |
-
$update = new self();
|
59 |
-
$update->copyFields($object, $update);
|
60 |
-
return $update;
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* @return string[]
|
65 |
-
*/
|
66 |
-
protected function getFieldNames() {
|
67 |
-
return array_merge(parent::getFieldNames(), self::$extraFields);
|
68 |
-
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Transform the update into the format used by WordPress native plugin API.
|
72 |
-
*
|
73 |
-
* @return object
|
74 |
-
*/
|
75 |
-
public function toWpFormat(){
|
76 |
-
$update = parent::toWpFormat();
|
77 |
-
|
78 |
-
$update->id = $this->id;
|
79 |
-
$update->url = $this->homepage;
|
80 |
-
$update->tested = $this->tested;
|
81 |
-
$update->plugin = $this->filename;
|
82 |
-
|
83 |
-
if ( !empty($this->upgrade_notice) ){
|
84 |
-
$update->upgrade_notice = $this->upgrade_notice;
|
85 |
-
}
|
86 |
-
|
87 |
-
return $update;
|
88 |
-
}
|
89 |
-
}
|
90 |
-
|
91 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Plugin/UpdateChecker.php
DELETED
@@ -1,546 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Plugin_UpdateChecker', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A custom plugin update checker.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @copyright 2016
|
9 |
-
* @access public
|
10 |
-
*/
|
11 |
-
class Puc_v4p1_Plugin_UpdateChecker extends Puc_v4p1_UpdateChecker {
|
12 |
-
protected $updateTransient = 'update_plugins';
|
13 |
-
protected $translationType = 'plugin';
|
14 |
-
|
15 |
-
public $pluginAbsolutePath = ''; //Full path of the main plugin file.
|
16 |
-
public $pluginFile = ''; //Plugin filename relative to the plugins directory. Many WP APIs use this to identify plugins.
|
17 |
-
public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
|
18 |
-
|
19 |
-
private $cachedInstalledVersion = null;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Class constructor.
|
23 |
-
*
|
24 |
-
* @param string $metadataUrl The URL of the plugin's metadata file.
|
25 |
-
* @param string $pluginFile Fully qualified path to the main plugin file.
|
26 |
-
* @param string $slug The plugin's 'slug'. If not specified, the filename part of $pluginFile sans '.php' will be used as the slug.
|
27 |
-
* @param integer $checkPeriod How often to check for updates (in hours). Defaults to checking every 12 hours. Set to 0 to disable automatic update checks.
|
28 |
-
* @param string $optionName Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'.
|
29 |
-
* @param string $muPluginFile Optional. The plugin filename relative to the mu-plugins directory.
|
30 |
-
*/
|
31 |
-
public function __construct($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = ''){
|
32 |
-
$this->pluginAbsolutePath = $pluginFile;
|
33 |
-
$this->pluginFile = plugin_basename($this->pluginAbsolutePath);
|
34 |
-
$this->muPluginFile = $muPluginFile;
|
35 |
-
|
36 |
-
//If no slug is specified, use the name of the main plugin file as the slug.
|
37 |
-
//For example, 'my-cool-plugin/cool-plugin.php' becomes 'cool-plugin'.
|
38 |
-
if ( empty($slug) ){
|
39 |
-
$slug = basename($this->pluginFile, '.php');
|
40 |
-
}
|
41 |
-
|
42 |
-
//Plugin slugs must be unique.
|
43 |
-
$slugCheckFilter = 'puc_is_slug_in_use-' . $this->slug;
|
44 |
-
$slugUsedBy = apply_filters($slugCheckFilter, false);
|
45 |
-
if ( $slugUsedBy ) {
|
46 |
-
$this->triggerError(sprintf(
|
47 |
-
'Plugin slug "%s" is already in use by %s. Slugs must be unique.',
|
48 |
-
htmlentities($this->slug),
|
49 |
-
htmlentities($slugUsedBy)
|
50 |
-
), E_USER_ERROR);
|
51 |
-
}
|
52 |
-
add_filter($slugCheckFilter, array($this, 'getAbsolutePath'));
|
53 |
-
|
54 |
-
//Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume
|
55 |
-
//it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir).
|
56 |
-
if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) {
|
57 |
-
$this->muPluginFile = $this->pluginFile;
|
58 |
-
}
|
59 |
-
|
60 |
-
parent::__construct($metadataUrl, dirname($this->pluginFile), $slug, $checkPeriod, $optionName);
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Create an instance of the scheduler.
|
65 |
-
*
|
66 |
-
* @param int $checkPeriod
|
67 |
-
* @return Puc_v4p1_Scheduler
|
68 |
-
*/
|
69 |
-
protected function createScheduler($checkPeriod) {
|
70 |
-
$scheduler = new Puc_v4p1_Scheduler($this, $checkPeriod, array('load-plugins.php'));
|
71 |
-
register_deactivation_hook($this->pluginFile, array($scheduler, 'removeUpdaterCron'));
|
72 |
-
return $scheduler;
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Install the hooks required to run periodic update checks and inject update info
|
77 |
-
* into WP data structures.
|
78 |
-
*
|
79 |
-
* @return void
|
80 |
-
*/
|
81 |
-
protected function installHooks(){
|
82 |
-
//Override requests for plugin information
|
83 |
-
add_filter('plugins_api', array($this, 'injectInfo'), 20, 3);
|
84 |
-
|
85 |
-
add_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10, 2);
|
86 |
-
add_action('admin_init', array($this, 'handleManualCheck'));
|
87 |
-
add_action('all_admin_notices', array($this, 'displayManualCheckResult'));
|
88 |
-
|
89 |
-
//Clear the version number cache when something - anything - is upgraded or WP clears the update cache.
|
90 |
-
add_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
|
91 |
-
add_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
|
92 |
-
|
93 |
-
parent::installHooks();
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Retrieve plugin info from the configured API endpoint.
|
98 |
-
*
|
99 |
-
* @uses wp_remote_get()
|
100 |
-
*
|
101 |
-
* @param array $queryArgs Additional query arguments to append to the request. Optional.
|
102 |
-
* @return Puc_v4p1_Plugin_Info
|
103 |
-
*/
|
104 |
-
public function requestInfo($queryArgs = array()) {
|
105 |
-
list($pluginInfo, $result) = $this->requestMetadata('Puc_v4p1_Plugin_Info', 'request_info', $queryArgs);
|
106 |
-
|
107 |
-
if ( $pluginInfo !== null ) {
|
108 |
-
/** @var Puc_v4p1_Plugin_Info $pluginInfo */
|
109 |
-
$pluginInfo->filename = $this->pluginFile;
|
110 |
-
$pluginInfo->slug = $this->slug;
|
111 |
-
}
|
112 |
-
|
113 |
-
$pluginInfo = apply_filters($this->getUniqueName('request_info_result'), $pluginInfo, $result);
|
114 |
-
return $pluginInfo;
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Retrieve the latest update (if any) from the configured API endpoint.
|
119 |
-
*
|
120 |
-
* @uses PluginUpdateChecker::requestInfo()
|
121 |
-
*
|
122 |
-
* @return Puc_v4p1_Update|null An instance of Plugin_Update, or NULL when no updates are available.
|
123 |
-
*/
|
124 |
-
public function requestUpdate() {
|
125 |
-
//For the sake of simplicity, this function just calls requestInfo()
|
126 |
-
//and transforms the result accordingly.
|
127 |
-
$pluginInfo = $this->requestInfo(array('checking_for_updates' => '1'));
|
128 |
-
if ( $pluginInfo == null ){
|
129 |
-
return null;
|
130 |
-
}
|
131 |
-
$update = Puc_v4p1_Plugin_Update::fromPluginInfo($pluginInfo);
|
132 |
-
|
133 |
-
$update = $this->filterUpdateResult($update);
|
134 |
-
|
135 |
-
return $update;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Get the currently installed version of the plugin.
|
140 |
-
*
|
141 |
-
* @return string Version number.
|
142 |
-
*/
|
143 |
-
public function getInstalledVersion(){
|
144 |
-
if ( isset($this->cachedInstalledVersion) ) {
|
145 |
-
return $this->cachedInstalledVersion;
|
146 |
-
}
|
147 |
-
|
148 |
-
$pluginHeader = $this->getPluginHeader();
|
149 |
-
if ( isset($pluginHeader['Version']) ) {
|
150 |
-
$this->cachedInstalledVersion = $pluginHeader['Version'];
|
151 |
-
return $pluginHeader['Version'];
|
152 |
-
} else {
|
153 |
-
//This can happen if the filename points to something that is not a plugin.
|
154 |
-
$this->triggerError(
|
155 |
-
sprintf(
|
156 |
-
"Can't to read the Version header for '%s'. The filename is incorrect or is not a plugin.",
|
157 |
-
$this->pluginFile
|
158 |
-
),
|
159 |
-
E_USER_WARNING
|
160 |
-
);
|
161 |
-
return null;
|
162 |
-
}
|
163 |
-
}
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Get plugin's metadata from its file header.
|
167 |
-
*
|
168 |
-
* @return array
|
169 |
-
*/
|
170 |
-
protected function getPluginHeader() {
|
171 |
-
if ( !is_file($this->pluginAbsolutePath) ) {
|
172 |
-
//This can happen if the plugin filename is wrong.
|
173 |
-
$this->triggerError(
|
174 |
-
sprintf(
|
175 |
-
"Can't to read the plugin header for '%s'. The file does not exist.",
|
176 |
-
$this->pluginFile
|
177 |
-
),
|
178 |
-
E_USER_WARNING
|
179 |
-
);
|
180 |
-
return array();
|
181 |
-
}
|
182 |
-
|
183 |
-
if ( !function_exists('get_plugin_data') ){
|
184 |
-
/** @noinspection PhpIncludeInspection */
|
185 |
-
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
186 |
-
}
|
187 |
-
return get_plugin_data($this->pluginAbsolutePath, false, false);
|
188 |
-
}
|
189 |
-
|
190 |
-
/**
|
191 |
-
* @return array
|
192 |
-
*/
|
193 |
-
protected function getHeaderNames() {
|
194 |
-
return array(
|
195 |
-
'Name' => 'Plugin Name',
|
196 |
-
'PluginURI' => 'Plugin URI',
|
197 |
-
'Version' => 'Version',
|
198 |
-
'Description' => 'Description',
|
199 |
-
'Author' => 'Author',
|
200 |
-
'AuthorURI' => 'Author URI',
|
201 |
-
'TextDomain' => 'Text Domain',
|
202 |
-
'DomainPath' => 'Domain Path',
|
203 |
-
'Network' => 'Network',
|
204 |
-
|
205 |
-
//The newest WordPress version that this plugin requires or has been tested with.
|
206 |
-
//We support several different formats for compatibility with other libraries.
|
207 |
-
'Tested WP' => 'Tested WP',
|
208 |
-
'Requires WP' => 'Requires WP',
|
209 |
-
'Tested up to' => 'Tested up to',
|
210 |
-
'Requires at least' => 'Requires at least',
|
211 |
-
);
|
212 |
-
}
|
213 |
-
|
214 |
-
|
215 |
-
/**
|
216 |
-
* Intercept plugins_api() calls that request information about our plugin and
|
217 |
-
* use the configured API endpoint to satisfy them.
|
218 |
-
*
|
219 |
-
* @see plugins_api()
|
220 |
-
*
|
221 |
-
* @param mixed $result
|
222 |
-
* @param string $action
|
223 |
-
* @param array|object $args
|
224 |
-
* @return mixed
|
225 |
-
*/
|
226 |
-
public function injectInfo($result, $action = null, $args = null){
|
227 |
-
$relevant = ($action == 'plugin_information') && isset($args->slug) && (
|
228 |
-
($args->slug == $this->slug) || ($args->slug == dirname($this->pluginFile))
|
229 |
-
);
|
230 |
-
if ( !$relevant ) {
|
231 |
-
return $result;
|
232 |
-
}
|
233 |
-
|
234 |
-
$pluginInfo = $this->requestInfo();
|
235 |
-
$pluginInfo = apply_filters($this->getUniqueName('pre_inject_info'), $pluginInfo);
|
236 |
-
if ( $pluginInfo ) {
|
237 |
-
return $pluginInfo->toWpFormat();
|
238 |
-
}
|
239 |
-
|
240 |
-
return $result;
|
241 |
-
}
|
242 |
-
|
243 |
-
protected function shouldShowUpdates() {
|
244 |
-
//No update notifications for mu-plugins unless explicitly enabled. The MU plugin file
|
245 |
-
//is usually different from the main plugin file so the update wouldn't show up properly anyway.
|
246 |
-
return !$this->isUnknownMuPlugin();
|
247 |
-
}
|
248 |
-
|
249 |
-
/**
|
250 |
-
* @param stdClass|null $updates
|
251 |
-
* @param stdClass $updateToAdd
|
252 |
-
* @return stdClass
|
253 |
-
*/
|
254 |
-
protected function addUpdateToList($updates, $updateToAdd) {
|
255 |
-
if ( $this->isMuPlugin() ) {
|
256 |
-
//WP does not support automatic update installation for mu-plugins, but we can
|
257 |
-
//still display a notice.
|
258 |
-
$updateToAdd->package = null;
|
259 |
-
}
|
260 |
-
return parent::addUpdateToList($updates, $updateToAdd);
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* @param stdClass|null $updates
|
265 |
-
* @return stdClass|null
|
266 |
-
*/
|
267 |
-
protected function removeUpdateFromList($updates) {
|
268 |
-
$updates = parent::removeUpdateFromList($updates);
|
269 |
-
if ( !empty($this->muPluginFile) && isset($updates, $updates->response) ) {
|
270 |
-
unset($updates->response[$this->muPluginFile]);
|
271 |
-
}
|
272 |
-
return $updates;
|
273 |
-
}
|
274 |
-
|
275 |
-
/**
|
276 |
-
* For plugins, the update array is indexed by the plugin filename relative to the "plugins"
|
277 |
-
* directory. Example: "plugin-name/plugin.php".
|
278 |
-
*
|
279 |
-
* @return string
|
280 |
-
*/
|
281 |
-
protected function getUpdateListKey() {
|
282 |
-
if ( $this->isMuPlugin() ) {
|
283 |
-
return $this->muPluginFile;
|
284 |
-
}
|
285 |
-
return $this->pluginFile;
|
286 |
-
}
|
287 |
-
|
288 |
-
/**
|
289 |
-
* Alias for isBeingUpgraded().
|
290 |
-
*
|
291 |
-
* @deprecated
|
292 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
293 |
-
* @return bool
|
294 |
-
*/
|
295 |
-
public function isPluginBeingUpgraded($upgrader = null) {
|
296 |
-
return $this->isBeingUpgraded($upgrader);
|
297 |
-
}
|
298 |
-
|
299 |
-
/**
|
300 |
-
* Is there an update being installed for this plugin, right now?
|
301 |
-
*
|
302 |
-
* @param WP_Upgrader|null $upgrader
|
303 |
-
* @return bool
|
304 |
-
*/
|
305 |
-
public function isBeingUpgraded($upgrader = null) {
|
306 |
-
return $this->upgraderStatus->isPluginBeingUpgraded($this->pluginFile, $upgrader);
|
307 |
-
}
|
308 |
-
|
309 |
-
/**
|
310 |
-
* Get the details of the currently available update, if any.
|
311 |
-
*
|
312 |
-
* If no updates are available, or if the last known update version is below or equal
|
313 |
-
* to the currently installed version, this method will return NULL.
|
314 |
-
*
|
315 |
-
* Uses cached update data. To retrieve update information straight from
|
316 |
-
* the metadata URL, call requestUpdate() instead.
|
317 |
-
*
|
318 |
-
* @return Puc_v4p1_Plugin_Update|null
|
319 |
-
*/
|
320 |
-
public function getUpdate() {
|
321 |
-
$update = parent::getUpdate();
|
322 |
-
if ( isset($update) ) {
|
323 |
-
/** @var Puc_v4p1_Plugin_Update $update */
|
324 |
-
$update->filename = $this->pluginFile;
|
325 |
-
}
|
326 |
-
return $update;
|
327 |
-
}
|
328 |
-
|
329 |
-
/**
|
330 |
-
* Add a "Check for updates" link to the plugin row in the "Plugins" page. By default,
|
331 |
-
* the new link will appear after the "Visit plugin site" link.
|
332 |
-
*
|
333 |
-
* You can change the link text by using the "puc_manual_check_link-$slug" filter.
|
334 |
-
* Returning an empty string from the filter will disable the link.
|
335 |
-
*
|
336 |
-
* @param array $pluginMeta Array of meta links.
|
337 |
-
* @param string $pluginFile
|
338 |
-
* @return array
|
339 |
-
*/
|
340 |
-
public function addCheckForUpdatesLink($pluginMeta, $pluginFile) {
|
341 |
-
$isRelevant = ($pluginFile == $this->pluginFile)
|
342 |
-
|| (!empty($this->muPluginFile) && $pluginFile == $this->muPluginFile);
|
343 |
-
|
344 |
-
if ( $isRelevant && $this->userCanInstallUpdates() ) {
|
345 |
-
$linkUrl = wp_nonce_url(
|
346 |
-
add_query_arg(
|
347 |
-
array(
|
348 |
-
'puc_check_for_updates' => 1,
|
349 |
-
'puc_slug' => $this->slug,
|
350 |
-
),
|
351 |
-
self_admin_url('plugins.php')
|
352 |
-
),
|
353 |
-
'puc_check_for_updates'
|
354 |
-
);
|
355 |
-
|
356 |
-
$linkText = apply_filters(
|
357 |
-
$this->getUniqueName('manual_check_link'),
|
358 |
-
__('Check for updates', 'plugin-update-checker')
|
359 |
-
);
|
360 |
-
if ( !empty($linkText) ) {
|
361 |
-
/** @noinspection HtmlUnknownTarget */
|
362 |
-
$pluginMeta[] = sprintf('<a href="%s">%s</a>', esc_attr($linkUrl), $linkText);
|
363 |
-
}
|
364 |
-
}
|
365 |
-
return $pluginMeta;
|
366 |
-
}
|
367 |
-
|
368 |
-
/**
|
369 |
-
* Check for updates when the user clicks the "Check for updates" link.
|
370 |
-
* @see self::addCheckForUpdatesLink()
|
371 |
-
*
|
372 |
-
* @return void
|
373 |
-
*/
|
374 |
-
public function handleManualCheck() {
|
375 |
-
$shouldCheck =
|
376 |
-
isset($_GET['puc_check_for_updates'], $_GET['puc_slug'])
|
377 |
-
&& $_GET['puc_slug'] == $this->slug
|
378 |
-
&& $this->userCanInstallUpdates()
|
379 |
-
&& check_admin_referer('puc_check_for_updates');
|
380 |
-
|
381 |
-
if ( $shouldCheck ) {
|
382 |
-
$update = $this->checkForUpdates();
|
383 |
-
$status = ($update === null) ? 'no_update' : 'update_available';
|
384 |
-
wp_redirect(add_query_arg(
|
385 |
-
array(
|
386 |
-
'puc_update_check_result' => $status,
|
387 |
-
'puc_slug' => $this->slug,
|
388 |
-
),
|
389 |
-
self_admin_url('plugins.php')
|
390 |
-
));
|
391 |
-
}
|
392 |
-
}
|
393 |
-
|
394 |
-
/**
|
395 |
-
* Display the results of a manual update check.
|
396 |
-
* @see self::handleManualCheck()
|
397 |
-
*
|
398 |
-
* You can change the result message by using the "puc_manual_check_message-$slug" filter.
|
399 |
-
*/
|
400 |
-
public function displayManualCheckResult() {
|
401 |
-
if ( isset($_GET['puc_update_check_result'], $_GET['puc_slug']) && ($_GET['puc_slug'] == $this->slug) ) {
|
402 |
-
$status = strval($_GET['puc_update_check_result']);
|
403 |
-
$title = $this->getPluginTitle();
|
404 |
-
if ( $status == 'no_update' ) {
|
405 |
-
$message = sprintf(_x('The %s plugin is up to date.', 'the plugin title', 'plugin-update-checker'), $title);
|
406 |
-
} else if ( $status == 'update_available' ) {
|
407 |
-
$message = sprintf(_x('A new version of the %s plugin is available.', 'the plugin title', 'plugin-update-checker'), $title);
|
408 |
-
} else {
|
409 |
-
$message = sprintf(__('Unknown update checker status "%s"', 'plugin-update-checker'), htmlentities($status));
|
410 |
-
}
|
411 |
-
printf(
|
412 |
-
'<div class="updated notice is-dismissible"><p>%s</p></div>',
|
413 |
-
apply_filters($this->getUniqueName('manual_check_message'), $message, $status)
|
414 |
-
);
|
415 |
-
}
|
416 |
-
}
|
417 |
-
|
418 |
-
/**
|
419 |
-
* Get the translated plugin title.
|
420 |
-
*
|
421 |
-
* @return string
|
422 |
-
*/
|
423 |
-
protected function getPluginTitle() {
|
424 |
-
$title = '';
|
425 |
-
$header = $this->getPluginHeader();
|
426 |
-
if ( $header && !empty($header['Name']) && isset($header['TextDomain']) ) {
|
427 |
-
$title = translate($header['Name'], $header['TextDomain']);
|
428 |
-
}
|
429 |
-
return $title;
|
430 |
-
}
|
431 |
-
|
432 |
-
/**
|
433 |
-
* Check if the current user has the required permissions to install updates.
|
434 |
-
*
|
435 |
-
* @return bool
|
436 |
-
*/
|
437 |
-
public function userCanInstallUpdates() {
|
438 |
-
return current_user_can('update_plugins');
|
439 |
-
}
|
440 |
-
|
441 |
-
/**
|
442 |
-
* Check if the plugin file is inside the mu-plugins directory.
|
443 |
-
*
|
444 |
-
* @return bool
|
445 |
-
*/
|
446 |
-
protected function isMuPlugin() {
|
447 |
-
static $cachedResult = null;
|
448 |
-
|
449 |
-
if ( $cachedResult === null ) {
|
450 |
-
//Convert both paths to the canonical form before comparison.
|
451 |
-
$muPluginDir = realpath(WPMU_PLUGIN_DIR);
|
452 |
-
$pluginPath = realpath($this->pluginAbsolutePath);
|
453 |
-
|
454 |
-
$cachedResult = (strpos($pluginPath, $muPluginDir) === 0);
|
455 |
-
}
|
456 |
-
|
457 |
-
return $cachedResult;
|
458 |
-
}
|
459 |
-
|
460 |
-
/**
|
461 |
-
* MU plugins are partially supported, but only when we know which file in mu-plugins
|
462 |
-
* corresponds to this plugin.
|
463 |
-
*
|
464 |
-
* @return bool
|
465 |
-
*/
|
466 |
-
protected function isUnknownMuPlugin() {
|
467 |
-
return empty($this->muPluginFile) && $this->isMuPlugin();
|
468 |
-
}
|
469 |
-
|
470 |
-
/**
|
471 |
-
* Clear the cached plugin version. This method can be set up as a filter (hook) and will
|
472 |
-
* return the filter argument unmodified.
|
473 |
-
*
|
474 |
-
* @param mixed $filterArgument
|
475 |
-
* @return mixed
|
476 |
-
*/
|
477 |
-
public function clearCachedVersion($filterArgument = null) {
|
478 |
-
$this->cachedInstalledVersion = null;
|
479 |
-
return $filterArgument;
|
480 |
-
}
|
481 |
-
|
482 |
-
/**
|
483 |
-
* Get absolute path to the main plugin file.
|
484 |
-
*
|
485 |
-
* @return string
|
486 |
-
*/
|
487 |
-
public function getAbsolutePath() {
|
488 |
-
return $this->pluginAbsolutePath;
|
489 |
-
}
|
490 |
-
|
491 |
-
/**
|
492 |
-
* Register a callback for filtering query arguments.
|
493 |
-
*
|
494 |
-
* The callback function should take one argument - an associative array of query arguments.
|
495 |
-
* It should return a modified array of query arguments.
|
496 |
-
*
|
497 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
498 |
-
*
|
499 |
-
* @param callable $callback
|
500 |
-
* @return void
|
501 |
-
*/
|
502 |
-
public function addQueryArgFilter($callback){
|
503 |
-
$this->addFilter('request_info_query_args', $callback);
|
504 |
-
}
|
505 |
-
|
506 |
-
/**
|
507 |
-
* Register a callback for filtering arguments passed to wp_remote_get().
|
508 |
-
*
|
509 |
-
* The callback function should take one argument - an associative array of arguments -
|
510 |
-
* and return a modified array or arguments. See the WP documentation on wp_remote_get()
|
511 |
-
* for details on what arguments are available and how they work.
|
512 |
-
*
|
513 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
514 |
-
*
|
515 |
-
* @param callable $callback
|
516 |
-
* @return void
|
517 |
-
*/
|
518 |
-
public function addHttpRequestArgFilter($callback) {
|
519 |
-
$this->addFilter('request_info_options', $callback);
|
520 |
-
}
|
521 |
-
|
522 |
-
/**
|
523 |
-
* Register a callback for filtering the plugin info retrieved from the external API.
|
524 |
-
*
|
525 |
-
* The callback function should take two arguments. If the plugin info was retrieved
|
526 |
-
* successfully, the first argument passed will be an instance of PluginInfo. Otherwise,
|
527 |
-
* it will be NULL. The second argument will be the corresponding return value of
|
528 |
-
* wp_remote_get (see WP docs for details).
|
529 |
-
*
|
530 |
-
* The callback function should return a new or modified instance of PluginInfo or NULL.
|
531 |
-
*
|
532 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
533 |
-
*
|
534 |
-
* @param callable $callback
|
535 |
-
* @return void
|
536 |
-
*/
|
537 |
-
public function addResultFilter($callback) {
|
538 |
-
$this->addFilter('request_info_result', $callback, 10, 2);
|
539 |
-
}
|
540 |
-
|
541 |
-
protected function createDebugBarExtension() {
|
542 |
-
return new Puc_v4p1_DebugBar_PluginExtension($this);
|
543 |
-
}
|
544 |
-
}
|
545 |
-
|
546 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Scheduler.php
DELETED
@@ -1,177 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Scheduler', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* The scheduler decides when and how often to check for updates.
|
6 |
-
* It calls @see Puc_v4p1_UpdateChecker::checkForUpdates() to perform the actual checks.
|
7 |
-
*/
|
8 |
-
class Puc_v4p1_Scheduler {
|
9 |
-
public $checkPeriod = 12; //How often to check for updates (in hours).
|
10 |
-
public $throttleRedundantChecks = false; //Check less often if we already know that an update is available.
|
11 |
-
public $throttledCheckPeriod = 72;
|
12 |
-
|
13 |
-
protected $hourlyCheckHooks = array('load-update.php');
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var Puc_v4p1_UpdateChecker
|
17 |
-
*/
|
18 |
-
protected $updateChecker;
|
19 |
-
|
20 |
-
private $cronHook = null;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Scheduler constructor.
|
24 |
-
*
|
25 |
-
* @param Puc_v4p1_UpdateChecker $updateChecker
|
26 |
-
* @param int $checkPeriod How often to check for updates (in hours).
|
27 |
-
* @param array $hourlyHooks
|
28 |
-
*/
|
29 |
-
public function __construct($updateChecker, $checkPeriod, $hourlyHooks = array('load-plugins.php')) {
|
30 |
-
$this->updateChecker = $updateChecker;
|
31 |
-
$this->checkPeriod = $checkPeriod;
|
32 |
-
|
33 |
-
//Set up the periodic update checks
|
34 |
-
$this->cronHook = $this->updateChecker->getUniqueName('cron_check_updates');
|
35 |
-
if ( $this->checkPeriod > 0 ){
|
36 |
-
|
37 |
-
//Trigger the check via Cron.
|
38 |
-
//Try to use one of the default schedules if possible as it's less likely to conflict
|
39 |
-
//with other plugins and their custom schedules.
|
40 |
-
$defaultSchedules = array(
|
41 |
-
1 => 'hourly',
|
42 |
-
12 => 'twicedaily',
|
43 |
-
24 => 'daily',
|
44 |
-
);
|
45 |
-
if ( array_key_exists($this->checkPeriod, $defaultSchedules) ) {
|
46 |
-
$scheduleName = $defaultSchedules[$this->checkPeriod];
|
47 |
-
} else {
|
48 |
-
//Use a custom cron schedule.
|
49 |
-
$scheduleName = 'every' . $this->checkPeriod . 'hours';
|
50 |
-
add_filter('cron_schedules', array($this, '_addCustomSchedule'));
|
51 |
-
}
|
52 |
-
|
53 |
-
if ( !wp_next_scheduled($this->cronHook) && !defined('WP_INSTALLING') ) {
|
54 |
-
wp_schedule_event(time(), $scheduleName, $this->cronHook);
|
55 |
-
}
|
56 |
-
add_action($this->cronHook, array($this, 'maybeCheckForUpdates'));
|
57 |
-
|
58 |
-
//In case Cron is disabled or unreliable, we also manually trigger
|
59 |
-
//the periodic checks while the user is browsing the Dashboard.
|
60 |
-
add_action( 'admin_init', array($this, 'maybeCheckForUpdates') );
|
61 |
-
|
62 |
-
//Like WordPress itself, we check more often on certain pages.
|
63 |
-
/** @see wp_update_plugins */
|
64 |
-
add_action('load-update-core.php', array($this, 'maybeCheckForUpdates'));
|
65 |
-
//"load-update.php" and "load-plugins.php" or "load-themes.php".
|
66 |
-
$this->hourlyCheckHooks = array_merge($this->hourlyCheckHooks, $hourlyHooks);
|
67 |
-
foreach($this->hourlyCheckHooks as $hook) {
|
68 |
-
add_action($hook, array($this, 'maybeCheckForUpdates'));
|
69 |
-
}
|
70 |
-
//This hook fires after a bulk update is complete.
|
71 |
-
add_action('upgrader_process_complete', array($this, 'maybeCheckForUpdates'), 11, 0);
|
72 |
-
|
73 |
-
} else {
|
74 |
-
//Periodic checks are disabled.
|
75 |
-
wp_clear_scheduled_hook($this->cronHook);
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Check for updates if the configured check interval has already elapsed.
|
81 |
-
* Will use a shorter check interval on certain admin pages like "Dashboard -> Updates" or when doing cron.
|
82 |
-
*
|
83 |
-
* You can override the default behaviour by using the "puc_check_now-$slug" filter.
|
84 |
-
* The filter callback will be passed three parameters:
|
85 |
-
* - Current decision. TRUE = check updates now, FALSE = don't check now.
|
86 |
-
* - Last check time as a Unix timestamp.
|
87 |
-
* - Configured check period in hours.
|
88 |
-
* Return TRUE to check for updates immediately, or FALSE to cancel.
|
89 |
-
*
|
90 |
-
* This method is declared public because it's a hook callback. Calling it directly is not recommended.
|
91 |
-
*/
|
92 |
-
public function maybeCheckForUpdates(){
|
93 |
-
if ( empty($this->checkPeriod) ){
|
94 |
-
return;
|
95 |
-
}
|
96 |
-
|
97 |
-
$state = $this->updateChecker->getUpdateState();
|
98 |
-
$shouldCheck = ($state->timeSinceLastCheck() >= $this->getEffectiveCheckPeriod());
|
99 |
-
|
100 |
-
//Let plugin authors substitute their own algorithm.
|
101 |
-
$shouldCheck = apply_filters(
|
102 |
-
$this->updateChecker->getUniqueName('check_now'),
|
103 |
-
$shouldCheck,
|
104 |
-
$state->getLastCheck(),
|
105 |
-
$this->checkPeriod
|
106 |
-
);
|
107 |
-
|
108 |
-
if ( $shouldCheck ) {
|
109 |
-
$this->updateChecker->checkForUpdates();
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Calculate the actual check period based on the current status and environment.
|
115 |
-
*
|
116 |
-
* @return int Check period in seconds.
|
117 |
-
*/
|
118 |
-
protected function getEffectiveCheckPeriod() {
|
119 |
-
$currentFilter = current_filter();
|
120 |
-
if ( in_array($currentFilter, array('load-update-core.php', 'upgrader_process_complete')) ) {
|
121 |
-
//Check more often when the user visits "Dashboard -> Updates" or does a bulk update.
|
122 |
-
$period = 60;
|
123 |
-
} else if ( in_array($currentFilter, $this->hourlyCheckHooks) ) {
|
124 |
-
//Also check more often on /wp-admin/update.php and the "Plugins" or "Themes" page.
|
125 |
-
$period = 3600;
|
126 |
-
} else if ( $this->throttleRedundantChecks && ($this->updateChecker->getUpdate() !== null) ) {
|
127 |
-
//Check less frequently if it's already known that an update is available.
|
128 |
-
$period = $this->throttledCheckPeriod * 3600;
|
129 |
-
} else if ( defined('DOING_CRON') && constant('DOING_CRON') ) {
|
130 |
-
//WordPress cron schedules are not exact, so lets do an update check even
|
131 |
-
//if slightly less than $checkPeriod hours have elapsed since the last check.
|
132 |
-
$cronFuzziness = 20 * 60;
|
133 |
-
$period = $this->checkPeriod * 3600 - $cronFuzziness;
|
134 |
-
} else {
|
135 |
-
$period = $this->checkPeriod * 3600;
|
136 |
-
}
|
137 |
-
|
138 |
-
return $period;
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Add our custom schedule to the array of Cron schedules used by WP.
|
143 |
-
*
|
144 |
-
* @param array $schedules
|
145 |
-
* @return array
|
146 |
-
*/
|
147 |
-
public function _addCustomSchedule($schedules){
|
148 |
-
if ( $this->checkPeriod && ($this->checkPeriod > 0) ){
|
149 |
-
$scheduleName = 'every' . $this->checkPeriod . 'hours';
|
150 |
-
$schedules[$scheduleName] = array(
|
151 |
-
'interval' => $this->checkPeriod * 3600,
|
152 |
-
'display' => sprintf('Every %d hours', $this->checkPeriod),
|
153 |
-
);
|
154 |
-
}
|
155 |
-
return $schedules;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Remove the scheduled cron event that the library uses to check for updates.
|
160 |
-
*
|
161 |
-
* @return void
|
162 |
-
*/
|
163 |
-
public function removeUpdaterCron(){
|
164 |
-
wp_clear_scheduled_hook($this->cronHook);
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Get the name of the update checker's WP-cron hook. Mostly useful for debugging.
|
169 |
-
*
|
170 |
-
* @return string
|
171 |
-
*/
|
172 |
-
public function getCronHookName() {
|
173 |
-
return $this->cronHook;
|
174 |
-
}
|
175 |
-
}
|
176 |
-
|
177 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/StateStore.php
DELETED
@@ -1,207 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_StateStore', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_StateStore {
|
6 |
-
/**
|
7 |
-
* @var int Last update check timestamp.
|
8 |
-
*/
|
9 |
-
protected $lastCheck = 0;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @var string Version number.
|
13 |
-
*/
|
14 |
-
protected $checkedVersion = '';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @var Puc_v4p1_Update|null Cached update.
|
18 |
-
*/
|
19 |
-
protected $update = null;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @var string Site option name.
|
23 |
-
*/
|
24 |
-
private $optionName = '';
|
25 |
-
|
26 |
-
/**
|
27 |
-
* @var bool Whether we've already tried to load the state from the database.
|
28 |
-
*/
|
29 |
-
private $isLoaded = false;
|
30 |
-
|
31 |
-
public function __construct($optionName) {
|
32 |
-
$this->optionName = $optionName;
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Get time elapsed since the last update check.
|
37 |
-
*
|
38 |
-
* If there are no recorded update checks, this method returns a large arbitrary number
|
39 |
-
* (i.e. time since the Unix epoch).
|
40 |
-
*
|
41 |
-
* @return int Elapsed time in seconds.
|
42 |
-
*/
|
43 |
-
public function timeSinceLastCheck() {
|
44 |
-
$this->lazyLoad();
|
45 |
-
return time() - $this->lastCheck;
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* @return int
|
50 |
-
*/
|
51 |
-
public function getLastCheck() {
|
52 |
-
$this->lazyLoad();
|
53 |
-
return $this->lastCheck;
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Set the time of the last update check to the current timestamp.
|
58 |
-
*
|
59 |
-
* @return $this
|
60 |
-
*/
|
61 |
-
public function setLastCheckToNow() {
|
62 |
-
$this->lazyLoad();
|
63 |
-
$this->lastCheck = time();
|
64 |
-
return $this;
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* @return null|Puc_v4p1_Update
|
69 |
-
*/
|
70 |
-
public function getUpdate() {
|
71 |
-
$this->lazyLoad();
|
72 |
-
return $this->update;
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* @param Puc_v4p1_Update|null $update
|
77 |
-
* @return $this
|
78 |
-
*/
|
79 |
-
public function setUpdate(Puc_v4p1_Update $update = null) {
|
80 |
-
$this->lazyLoad();
|
81 |
-
$this->update = $update;
|
82 |
-
return $this;
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* @return string
|
87 |
-
*/
|
88 |
-
public function getCheckedVersion() {
|
89 |
-
$this->lazyLoad();
|
90 |
-
return $this->checkedVersion;
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* @param string $version
|
95 |
-
* @return $this
|
96 |
-
*/
|
97 |
-
public function setCheckedVersion($version) {
|
98 |
-
$this->lazyLoad();
|
99 |
-
$this->checkedVersion = strval($version);
|
100 |
-
return $this;
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Get translation updates.
|
105 |
-
*
|
106 |
-
* @return array
|
107 |
-
*/
|
108 |
-
public function getTranslations() {
|
109 |
-
$this->lazyLoad();
|
110 |
-
if ( isset($this->update, $this->update->translations) ) {
|
111 |
-
return $this->update->translations;
|
112 |
-
}
|
113 |
-
return array();
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Set translation updates.
|
118 |
-
*
|
119 |
-
* @param array $translationUpdates
|
120 |
-
*/
|
121 |
-
public function setTranslations($translationUpdates) {
|
122 |
-
$this->lazyLoad();
|
123 |
-
if ( isset($this->update) ) {
|
124 |
-
$this->update->translations = $translationUpdates;
|
125 |
-
$this->save();
|
126 |
-
}
|
127 |
-
}
|
128 |
-
|
129 |
-
public function save() {
|
130 |
-
$state = new stdClass();
|
131 |
-
|
132 |
-
$state->lastCheck = $this->lastCheck;
|
133 |
-
$state->checkedVersion = $this->checkedVersion;
|
134 |
-
|
135 |
-
if ( isset($this->update)) {
|
136 |
-
$state->update = $this->update->toStdClass();
|
137 |
-
|
138 |
-
$updateClass = get_class($this->update);
|
139 |
-
$state->updateClass = $updateClass;
|
140 |
-
$prefix = $this->getLibPrefix();
|
141 |
-
if ( Puc_v4p1_Utils::startsWith($updateClass, $prefix) ) {
|
142 |
-
$state->updateBaseClass = substr($updateClass, strlen($prefix));
|
143 |
-
}
|
144 |
-
}
|
145 |
-
|
146 |
-
update_site_option($this->optionName, $state);
|
147 |
-
$this->isLoaded = true;
|
148 |
-
}
|
149 |
-
|
150 |
-
/**
|
151 |
-
* @return $this
|
152 |
-
*/
|
153 |
-
public function lazyLoad() {
|
154 |
-
if ( !$this->isLoaded ) {
|
155 |
-
$this->load();
|
156 |
-
}
|
157 |
-
return $this;
|
158 |
-
}
|
159 |
-
|
160 |
-
protected function load() {
|
161 |
-
$this->isLoaded = true;
|
162 |
-
|
163 |
-
$state = get_site_option($this->optionName, null);
|
164 |
-
|
165 |
-
if ( !is_object($state) ) {
|
166 |
-
$this->lastCheck = 0;
|
167 |
-
$this->checkedVersion = '';
|
168 |
-
$this->update = null;
|
169 |
-
return;
|
170 |
-
}
|
171 |
-
|
172 |
-
$this->lastCheck = intval(Puc_v4p1_Utils::get($state, 'lastCheck', 0));
|
173 |
-
$this->checkedVersion = Puc_v4p1_Utils::get($state, 'checkedVersion', '');
|
174 |
-
$this->update = null;
|
175 |
-
|
176 |
-
if ( isset($state->update) ) {
|
177 |
-
//This mess is due to the fact that the want the update class from this version
|
178 |
-
//of the library, not the version that saved the update.
|
179 |
-
|
180 |
-
$updateClass = null;
|
181 |
-
if ( isset($state->updateBaseClass) ) {
|
182 |
-
$updateClass = $this->getLibPrefix() . $state->updateBaseClass;
|
183 |
-
} else if ( isset($state->updateClass) && class_exists($state->updateClass) ) {
|
184 |
-
$updateClass = $state->updateClass;
|
185 |
-
}
|
186 |
-
|
187 |
-
if ( $updateClass !== null ) {
|
188 |
-
$this->update = call_user_func(array($updateClass, 'fromObject'), $state->update);
|
189 |
-
}
|
190 |
-
}
|
191 |
-
}
|
192 |
-
|
193 |
-
public function delete() {
|
194 |
-
delete_site_option($this->optionName);
|
195 |
-
|
196 |
-
$this->lastCheck = 0;
|
197 |
-
$this->checkedVersion = '';
|
198 |
-
$this->update = null;
|
199 |
-
}
|
200 |
-
|
201 |
-
private function getLibPrefix() {
|
202 |
-
$parts = explode('_', __CLASS__, 3);
|
203 |
-
return $parts[0] . '_' . $parts[1] . '_';
|
204 |
-
}
|
205 |
-
}
|
206 |
-
|
207 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Theme/Update.php
DELETED
@@ -1,84 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_Theme_Update', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_Theme_Update extends Puc_v4p1_Update {
|
6 |
-
public $details_url = '';
|
7 |
-
|
8 |
-
protected static $extraFields = array('details_url');
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Transform the metadata into the format used by WordPress core.
|
12 |
-
* Note the inconsistency: WP stores plugin updates as objects and theme updates as arrays.
|
13 |
-
*
|
14 |
-
* @return array
|
15 |
-
*/
|
16 |
-
public function toWpFormat() {
|
17 |
-
$update = array(
|
18 |
-
'theme' => $this->slug,
|
19 |
-
'new_version' => $this->version,
|
20 |
-
'url' => $this->details_url,
|
21 |
-
);
|
22 |
-
|
23 |
-
if ( !empty($this->download_url) ) {
|
24 |
-
$update['package'] = $this->download_url;
|
25 |
-
}
|
26 |
-
|
27 |
-
return $update;
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Create a new instance of Theme_Update from its JSON-encoded representation.
|
32 |
-
*
|
33 |
-
* @param string $json Valid JSON string representing a theme information object.
|
34 |
-
* @return self New instance of ThemeUpdate, or NULL on error.
|
35 |
-
*/
|
36 |
-
public static function fromJson($json) {
|
37 |
-
$instance = new self();
|
38 |
-
if ( !parent::createFromJson($json, $instance) ) {
|
39 |
-
return null;
|
40 |
-
}
|
41 |
-
return $instance;
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Create a new instance by copying the necessary fields from another object.
|
46 |
-
*
|
47 |
-
* @param StdClass|Puc_v4p1_Theme_Update $object The source object.
|
48 |
-
* @return Puc_v4p1_Theme_Update The new copy.
|
49 |
-
*/
|
50 |
-
public static function fromObject($object) {
|
51 |
-
$update = new self();
|
52 |
-
$update->copyFields($object, $update);
|
53 |
-
return $update;
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Basic validation.
|
58 |
-
*
|
59 |
-
* @param StdClass $apiResponse
|
60 |
-
* @return bool|WP_Error
|
61 |
-
*/
|
62 |
-
protected function validateMetadata($apiResponse) {
|
63 |
-
$required = array('version', 'details_url');
|
64 |
-
foreach($required as $key) {
|
65 |
-
if ( !isset($apiResponse->$key) || empty($apiResponse->$key) ) {
|
66 |
-
return new WP_Error(
|
67 |
-
'tuc-invalid-metadata',
|
68 |
-
sprintf('The theme metadata is missing the required "%s" key.', $key)
|
69 |
-
);
|
70 |
-
}
|
71 |
-
}
|
72 |
-
return true;
|
73 |
-
}
|
74 |
-
|
75 |
-
protected function getFieldNames() {
|
76 |
-
return array_merge(parent::getFieldNames(), self::$extraFields);
|
77 |
-
}
|
78 |
-
|
79 |
-
protected function getPrefixedFilter($tag) {
|
80 |
-
return parent::getPrefixedFilter($tag) . '_theme';
|
81 |
-
}
|
82 |
-
}
|
83 |
-
|
84 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Theme/UpdateChecker.php
DELETED
@@ -1,167 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_Theme_UpdateChecker', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_Theme_UpdateChecker extends Puc_v4p1_UpdateChecker {
|
6 |
-
protected $filterSuffix = 'theme';
|
7 |
-
protected $updateTransient = 'update_themes';
|
8 |
-
protected $translationType = 'theme';
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var string Theme directory name.
|
12 |
-
*/
|
13 |
-
protected $stylesheet;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var WP_Theme Theme object.
|
17 |
-
*/
|
18 |
-
protected $theme;
|
19 |
-
|
20 |
-
public function __construct($metadataUrl, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') {
|
21 |
-
if ( $stylesheet === null ) {
|
22 |
-
$stylesheet = get_stylesheet();
|
23 |
-
}
|
24 |
-
$this->stylesheet = $stylesheet;
|
25 |
-
$this->theme = wp_get_theme($this->stylesheet);
|
26 |
-
|
27 |
-
parent::__construct(
|
28 |
-
$metadataUrl,
|
29 |
-
$stylesheet,
|
30 |
-
$customSlug ? $customSlug : $stylesheet,
|
31 |
-
$checkPeriod,
|
32 |
-
$optionName
|
33 |
-
);
|
34 |
-
}
|
35 |
-
|
36 |
-
/**
|
37 |
-
* For themes, the update array is indexed by theme directory name.
|
38 |
-
*
|
39 |
-
* @return string
|
40 |
-
*/
|
41 |
-
protected function getUpdateListKey() {
|
42 |
-
return $this->directoryName;
|
43 |
-
}
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Retrieve the latest update (if any) from the configured API endpoint.
|
47 |
-
*
|
48 |
-
* @return Puc_v4p1_Update|null An instance of Update, or NULL when no updates are available.
|
49 |
-
*/
|
50 |
-
public function requestUpdate() {
|
51 |
-
list($themeUpdate, $result) = $this->requestMetadata('Puc_v4p1_Theme_Update', 'request_update');
|
52 |
-
|
53 |
-
if ( $themeUpdate !== null ) {
|
54 |
-
/** @var Puc_v4p1_Theme_Update $themeUpdate */
|
55 |
-
$themeUpdate->slug = $this->slug;
|
56 |
-
}
|
57 |
-
|
58 |
-
$themeUpdate = $this->filterUpdateResult($themeUpdate, $result);
|
59 |
-
return $themeUpdate;
|
60 |
-
}
|
61 |
-
|
62 |
-
public function userCanInstallUpdates() {
|
63 |
-
return current_user_can('update_themes');
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Get the currently installed version of the plugin or theme.
|
68 |
-
*
|
69 |
-
* @return string Version number.
|
70 |
-
*/
|
71 |
-
public function getInstalledVersion() {
|
72 |
-
return $this->theme->get('Version');
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Create an instance of the scheduler.
|
77 |
-
*
|
78 |
-
* @param int $checkPeriod
|
79 |
-
* @return Puc_v4p1_Scheduler
|
80 |
-
*/
|
81 |
-
protected function createScheduler($checkPeriod) {
|
82 |
-
return new Puc_v4p1_Scheduler($this, $checkPeriod, array('load-themes.php'));
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Is there an update being installed right now for this theme?
|
87 |
-
*
|
88 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
89 |
-
* @return bool
|
90 |
-
*/
|
91 |
-
public function isBeingUpgraded($upgrader = null) {
|
92 |
-
return $this->upgraderStatus->isThemeBeingUpgraded($this->stylesheet, $upgrader);
|
93 |
-
}
|
94 |
-
|
95 |
-
protected function createDebugBarExtension() {
|
96 |
-
return new Puc_v4p1_DebugBar_Extension($this, 'Puc_v4p1_DebugBar_ThemePanel');
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Register a callback for filtering query arguments.
|
101 |
-
*
|
102 |
-
* The callback function should take one argument - an associative array of query arguments.
|
103 |
-
* It should return a modified array of query arguments.
|
104 |
-
*
|
105 |
-
* @param callable $callback
|
106 |
-
* @return void
|
107 |
-
*/
|
108 |
-
public function addQueryArgFilter($callback){
|
109 |
-
$this->addFilter('request_update_query_args', $callback);
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Register a callback for filtering arguments passed to wp_remote_get().
|
114 |
-
*
|
115 |
-
* The callback function should take one argument - an associative array of arguments -
|
116 |
-
* and return a modified array or arguments. See the WP documentation on wp_remote_get()
|
117 |
-
* for details on what arguments are available and how they work.
|
118 |
-
*
|
119 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
120 |
-
*
|
121 |
-
* @param callable $callback
|
122 |
-
* @return void
|
123 |
-
*/
|
124 |
-
public function addHttpRequestArgFilter($callback) {
|
125 |
-
$this->addFilter('request_update_options', $callback);
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Register a callback for filtering theme updates retrieved from the external API.
|
130 |
-
*
|
131 |
-
* The callback function should take two arguments. If the theme update was retrieved
|
132 |
-
* successfully, the first argument passed will be an instance of Theme_Update. Otherwise,
|
133 |
-
* it will be NULL. The second argument will be the corresponding return value of
|
134 |
-
* wp_remote_get (see WP docs for details).
|
135 |
-
*
|
136 |
-
* The callback function should return a new or modified instance of Theme_Update or NULL.
|
137 |
-
*
|
138 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
139 |
-
*
|
140 |
-
* @param callable $callback
|
141 |
-
* @return void
|
142 |
-
*/
|
143 |
-
public function addResultFilter($callback) {
|
144 |
-
$this->addFilter('request_update_result', $callback, 10, 2);
|
145 |
-
}
|
146 |
-
|
147 |
-
/**
|
148 |
-
* @return array
|
149 |
-
*/
|
150 |
-
protected function getHeaderNames() {
|
151 |
-
return array(
|
152 |
-
'Name' => 'Theme Name',
|
153 |
-
'ThemeURI' => 'Theme URI',
|
154 |
-
'Description' => 'Description',
|
155 |
-
'Author' => 'Author',
|
156 |
-
'AuthorURI' => 'Author URI',
|
157 |
-
'Version' => 'Version',
|
158 |
-
'Template' => 'Template',
|
159 |
-
'Status' => 'Status',
|
160 |
-
'Tags' => 'Tags',
|
161 |
-
'TextDomain' => 'Text Domain',
|
162 |
-
'DomainPath' => 'Domain Path',
|
163 |
-
);
|
164 |
-
}
|
165 |
-
}
|
166 |
-
|
167 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Update.php
DELETED
@@ -1,34 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Update', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A simple container class for holding information about an available update.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @access public
|
9 |
-
*/
|
10 |
-
abstract class Puc_v4p1_Update extends Puc_v4p1_Metadata {
|
11 |
-
public $slug;
|
12 |
-
public $version;
|
13 |
-
public $download_url;
|
14 |
-
public $translations = array();
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @return string[]
|
18 |
-
*/
|
19 |
-
protected function getFieldNames() {
|
20 |
-
return array('slug', 'version', 'download_url', 'translations');
|
21 |
-
}
|
22 |
-
|
23 |
-
public function toWpFormat() {
|
24 |
-
$update = new stdClass();
|
25 |
-
|
26 |
-
$update->slug = $this->slug;
|
27 |
-
$update->new_version = $this->version;
|
28 |
-
$update->package = $this->download_url;
|
29 |
-
|
30 |
-
return $update;
|
31 |
-
}
|
32 |
-
}
|
33 |
-
|
34 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/UpdateChecker.php
DELETED
@@ -1,825 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_UpdateChecker', false) ):
|
4 |
-
|
5 |
-
abstract class Puc_v4p1_UpdateChecker {
|
6 |
-
protected $filterSuffix = '';
|
7 |
-
protected $updateTransient = '';
|
8 |
-
protected $translationType = ''; //"plugin" or "theme".
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Set to TRUE to enable error reporting. Errors are raised using trigger_error()
|
12 |
-
* and should be logged to the standard PHP error log.
|
13 |
-
* @var bool
|
14 |
-
*/
|
15 |
-
public $debugMode = false;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string Where to store the update info.
|
19 |
-
*/
|
20 |
-
public $optionName = '';
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var string The URL of the metadata file.
|
24 |
-
*/
|
25 |
-
public $metadataUrl = '';
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var string Plugin or theme directory name.
|
29 |
-
*/
|
30 |
-
public $directoryName = '';
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var string The slug that will be used in update checker hooks and remote API requests.
|
34 |
-
* Usually matches the directory name unless the plugin/theme directory has been renamed.
|
35 |
-
*/
|
36 |
-
public $slug = '';
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @var Puc_v4p1_Scheduler
|
40 |
-
*/
|
41 |
-
public $scheduler;
|
42 |
-
|
43 |
-
/**
|
44 |
-
* @var Puc_v4p1_UpgraderStatus
|
45 |
-
*/
|
46 |
-
protected $upgraderStatus;
|
47 |
-
|
48 |
-
/**
|
49 |
-
* @var Puc_v4p1_StateStore
|
50 |
-
*/
|
51 |
-
protected $updateState;
|
52 |
-
|
53 |
-
public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
|
54 |
-
$this->debugMode = (bool)(constant('WP_DEBUG'));
|
55 |
-
$this->metadataUrl = $metadataUrl;
|
56 |
-
$this->directoryName = $directoryName;
|
57 |
-
$this->slug = !empty($slug) ? $slug : $this->directoryName;
|
58 |
-
|
59 |
-
$this->optionName = $optionName;
|
60 |
-
if ( empty($this->optionName) ) {
|
61 |
-
//BC: Initially the library only supported plugin updates and didn't use type prefixes
|
62 |
-
//in the option name. Lets use the same prefix-less name when possible.
|
63 |
-
if ( $this->filterSuffix === '' ) {
|
64 |
-
$this->optionName = 'external_updates-' . $this->slug;
|
65 |
-
} else {
|
66 |
-
$this->optionName = $this->getUniqueName('external_updates');
|
67 |
-
}
|
68 |
-
}
|
69 |
-
|
70 |
-
$this->scheduler = $this->createScheduler($checkPeriod);
|
71 |
-
$this->upgraderStatus = new Puc_v4p1_UpgraderStatus();
|
72 |
-
$this->updateState = new Puc_v4p1_StateStore($this->optionName);
|
73 |
-
|
74 |
-
if ( did_action('init') ) {
|
75 |
-
$this->loadTextDomain();
|
76 |
-
} else {
|
77 |
-
add_action('init', array($this, 'loadTextDomain'));
|
78 |
-
}
|
79 |
-
|
80 |
-
$this->installHooks();
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* @internal
|
85 |
-
*/
|
86 |
-
public function loadTextDomain() {
|
87 |
-
//We're not using load_plugin_textdomain() or its siblings because figuring out where
|
88 |
-
//the library is located (plugin, mu-plugin, theme, custom wp-content paths) is messy.
|
89 |
-
$domain = 'plugin-update-checker';
|
90 |
-
$locale = apply_filters(
|
91 |
-
'plugin_locale',
|
92 |
-
(is_admin() && function_exists('get_user_locale')) ? get_user_locale() : get_locale(),
|
93 |
-
$domain
|
94 |
-
);
|
95 |
-
|
96 |
-
$moFile = $domain . '-' . $locale . '.mo';
|
97 |
-
$path = realpath(dirname(__FILE__) . '/../../languages');
|
98 |
-
|
99 |
-
if ($path && file_exists($path)) {
|
100 |
-
load_textdomain($domain, $path . '/' . $moFile);
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
protected function installHooks() {
|
105 |
-
//Insert our update info into the update array maintained by WP.
|
106 |
-
add_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
|
107 |
-
|
108 |
-
//Insert translation updates into the update list.
|
109 |
-
add_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
|
110 |
-
|
111 |
-
//Clear translation updates when WP clears the update cache.
|
112 |
-
//This needs to be done directly because the library doesn't actually remove obsolete plugin updates,
|
113 |
-
//it just hides them (see getUpdate()). We can't do that with translations - too much disk I/O.
|
114 |
-
add_action(
|
115 |
-
'delete_site_transient_' . $this->updateTransient,
|
116 |
-
array($this, 'clearCachedTranslationUpdates')
|
117 |
-
);
|
118 |
-
|
119 |
-
//Rename the update directory to be the same as the existing directory.
|
120 |
-
if ( $this->directoryName !== '.' ) {
|
121 |
-
add_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10, 3);
|
122 |
-
}
|
123 |
-
|
124 |
-
//Allow HTTP requests to the metadata URL even if it's on a local host.
|
125 |
-
add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
|
126 |
-
|
127 |
-
//DebugBar integration.
|
128 |
-
if ( did_action('plugins_loaded') ) {
|
129 |
-
$this->maybeInitDebugBar();
|
130 |
-
} else {
|
131 |
-
add_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
/**
|
136 |
-
* Check if the current user has the required permissions to install updates.
|
137 |
-
*
|
138 |
-
* @return bool
|
139 |
-
*/
|
140 |
-
abstract public function userCanInstallUpdates();
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Explicitly allow HTTP requests to the metadata URL.
|
144 |
-
*
|
145 |
-
* WordPress has a security feature where the HTTP API will reject all requests that are sent to
|
146 |
-
* another site hosted on the same server as the current site (IP match), a local host, or a local
|
147 |
-
* IP, unless the host exactly matches the current site.
|
148 |
-
*
|
149 |
-
* This feature is opt-in (at least in WP 4.4). Apparently some people enable it.
|
150 |
-
*
|
151 |
-
* That can be a problem when you're developing your plugin and you decide to host the update information
|
152 |
-
* on the same server as your test site. Update requests will mysteriously fail.
|
153 |
-
*
|
154 |
-
* We fix that by adding an exception for the metadata host.
|
155 |
-
*
|
156 |
-
* @param bool $allow
|
157 |
-
* @param string $host
|
158 |
-
* @return bool
|
159 |
-
*/
|
160 |
-
public function allowMetadataHost($allow, $host) {
|
161 |
-
static $metadataHost = 0; //Using 0 instead of NULL because parse_url can return NULL.
|
162 |
-
if ( $metadataHost === 0 ) {
|
163 |
-
$metadataHost = @parse_url($this->metadataUrl, PHP_URL_HOST);
|
164 |
-
}
|
165 |
-
|
166 |
-
if ( is_string($metadataHost) && (strtolower($host) === strtolower($metadataHost)) ) {
|
167 |
-
return true;
|
168 |
-
}
|
169 |
-
return $allow;
|
170 |
-
}
|
171 |
-
|
172 |
-
/**
|
173 |
-
* Create an instance of the scheduler.
|
174 |
-
*
|
175 |
-
* This is implemented as a method to make it possible for plugins to subclass the update checker
|
176 |
-
* and substitute their own scheduler.
|
177 |
-
*
|
178 |
-
* @param int $checkPeriod
|
179 |
-
* @return Puc_v4p1_Scheduler
|
180 |
-
*/
|
181 |
-
abstract protected function createScheduler($checkPeriod);
|
182 |
-
|
183 |
-
/**
|
184 |
-
* Check for updates. The results are stored in the DB option specified in $optionName.
|
185 |
-
*
|
186 |
-
* @return Puc_v4p1_Update|null
|
187 |
-
*/
|
188 |
-
public function checkForUpdates() {
|
189 |
-
$installedVersion = $this->getInstalledVersion();
|
190 |
-
//Fail silently if we can't find the plugin/theme or read its header.
|
191 |
-
if ( $installedVersion === null ) {
|
192 |
-
$this->triggerError(
|
193 |
-
sprintf('Skipping update check for %s - installed version unknown.', $this->slug),
|
194 |
-
E_USER_WARNING
|
195 |
-
);
|
196 |
-
return null;
|
197 |
-
}
|
198 |
-
|
199 |
-
$state = $this->updateState;
|
200 |
-
$state->setLastCheckToNow()
|
201 |
-
->setCheckedVersion($installedVersion)
|
202 |
-
->save(); //Save before checking in case something goes wrong
|
203 |
-
|
204 |
-
$state->setUpdate($this->requestUpdate());
|
205 |
-
$state->save();
|
206 |
-
|
207 |
-
return $this->getUpdate();
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Load the update checker state from the DB.
|
212 |
-
*
|
213 |
-
* @return Puc_v4p1_StateStore
|
214 |
-
*/
|
215 |
-
public function getUpdateState() {
|
216 |
-
return $this->updateState->lazyLoad();
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Reset update checker state - i.e. last check time, cached update data and so on.
|
221 |
-
*
|
222 |
-
* Call this when your plugin is being uninstalled, or if you want to
|
223 |
-
* clear the update cache.
|
224 |
-
*/
|
225 |
-
public function resetUpdateState() {
|
226 |
-
$this->updateState->delete();
|
227 |
-
}
|
228 |
-
|
229 |
-
/**
|
230 |
-
* Get the details of the currently available update, if any.
|
231 |
-
*
|
232 |
-
* If no updates are available, or if the last known update version is below or equal
|
233 |
-
* to the currently installed version, this method will return NULL.
|
234 |
-
*
|
235 |
-
* Uses cached update data. To retrieve update information straight from
|
236 |
-
* the metadata URL, call requestUpdate() instead.
|
237 |
-
*
|
238 |
-
* @return Puc_v4p1_Update|null
|
239 |
-
*/
|
240 |
-
public function getUpdate() {
|
241 |
-
$update = $this->updateState->getUpdate();
|
242 |
-
|
243 |
-
//Is there an update available?
|
244 |
-
if ( isset($update) ) {
|
245 |
-
//Check if the update is actually newer than the currently installed version.
|
246 |
-
$installedVersion = $this->getInstalledVersion();
|
247 |
-
if ( ($installedVersion !== null) && version_compare($update->version, $installedVersion, '>') ){
|
248 |
-
return $update;
|
249 |
-
}
|
250 |
-
}
|
251 |
-
return null;
|
252 |
-
}
|
253 |
-
|
254 |
-
/**
|
255 |
-
* Retrieve the latest update (if any) from the configured API endpoint.
|
256 |
-
*
|
257 |
-
* Subclasses should run the update through filterUpdateResult before returning it.
|
258 |
-
*
|
259 |
-
* @return Puc_v4p1_Update An instance of Update, or NULL when no updates are available.
|
260 |
-
*/
|
261 |
-
abstract public function requestUpdate();
|
262 |
-
|
263 |
-
/**
|
264 |
-
* Filter the result of a requestUpdate() call.
|
265 |
-
*
|
266 |
-
* @param Puc_v4p1_Update|null $update
|
267 |
-
* @param array|WP_Error|null $httpResult The value returned by wp_remote_get(), if any.
|
268 |
-
* @return Puc_v4p1_Update
|
269 |
-
*/
|
270 |
-
protected function filterUpdateResult($update, $httpResult = null) {
|
271 |
-
//Let plugins/themes modify the update.
|
272 |
-
$update = apply_filters($this->getUniqueName('request_update_result'), $update, $httpResult);
|
273 |
-
|
274 |
-
if ( isset($update, $update->translations) ) {
|
275 |
-
//Keep only those translation updates that apply to this site.
|
276 |
-
$update->translations = $this->filterApplicableTranslations($update->translations);
|
277 |
-
}
|
278 |
-
|
279 |
-
return $update;
|
280 |
-
}
|
281 |
-
|
282 |
-
/**
|
283 |
-
* Get the currently installed version of the plugin or theme.
|
284 |
-
*
|
285 |
-
* @return string|null Version number.
|
286 |
-
*/
|
287 |
-
abstract public function getInstalledVersion();
|
288 |
-
|
289 |
-
/**
|
290 |
-
* Trigger a PHP error, but only when $debugMode is enabled.
|
291 |
-
*
|
292 |
-
* @param string $message
|
293 |
-
* @param int $errorType
|
294 |
-
*/
|
295 |
-
protected function triggerError($message, $errorType) {
|
296 |
-
if ($this->debugMode) {
|
297 |
-
trigger_error($message, $errorType);
|
298 |
-
}
|
299 |
-
}
|
300 |
-
|
301 |
-
/**
|
302 |
-
* Get the full name of an update checker filter, action or DB entry.
|
303 |
-
*
|
304 |
-
* This method adds the "puc_" prefix and the "-$slug" suffix to the filter name.
|
305 |
-
* For example, "pre_inject_update" becomes "puc_pre_inject_update-plugin-slug".
|
306 |
-
*
|
307 |
-
* @param string $baseTag
|
308 |
-
* @return string
|
309 |
-
*/
|
310 |
-
public function getUniqueName($baseTag) {
|
311 |
-
$name = 'puc_' . $baseTag;
|
312 |
-
if ($this->filterSuffix !== '') {
|
313 |
-
$name .= '_' . $this->filterSuffix;
|
314 |
-
}
|
315 |
-
return $name . '-' . $this->slug;
|
316 |
-
}
|
317 |
-
|
318 |
-
/* -------------------------------------------------------------------
|
319 |
-
* PUC filters and filter utilities
|
320 |
-
* -------------------------------------------------------------------
|
321 |
-
*/
|
322 |
-
|
323 |
-
/**
|
324 |
-
* Register a callback for one of the update checker filters.
|
325 |
-
*
|
326 |
-
* Identical to add_filter(), except it automatically adds the "puc_" prefix
|
327 |
-
* and the "-$slug" suffix to the filter name. For example, "request_info_result"
|
328 |
-
* becomes "puc_request_info_result-your_plugin_slug".
|
329 |
-
*
|
330 |
-
* @param string $tag
|
331 |
-
* @param callable $callback
|
332 |
-
* @param int $priority
|
333 |
-
* @param int $acceptedArgs
|
334 |
-
*/
|
335 |
-
public function addFilter($tag, $callback, $priority = 10, $acceptedArgs = 1) {
|
336 |
-
add_filter($this->getUniqueName($tag), $callback, $priority, $acceptedArgs);
|
337 |
-
}
|
338 |
-
|
339 |
-
/* -------------------------------------------------------------------
|
340 |
-
* Inject updates
|
341 |
-
* -------------------------------------------------------------------
|
342 |
-
*/
|
343 |
-
|
344 |
-
/**
|
345 |
-
* Insert the latest update (if any) into the update list maintained by WP.
|
346 |
-
*
|
347 |
-
* @param stdClass $updates Update list.
|
348 |
-
* @return stdClass Modified update list.
|
349 |
-
*/
|
350 |
-
public function injectUpdate($updates) {
|
351 |
-
//Is there an update to insert?
|
352 |
-
$update = $this->getUpdate();
|
353 |
-
|
354 |
-
if ( !$this->shouldShowUpdates() ) {
|
355 |
-
$update = null;
|
356 |
-
}
|
357 |
-
|
358 |
-
if ( !empty($update) ) {
|
359 |
-
//Let plugins filter the update info before it's passed on to WordPress.
|
360 |
-
$update = apply_filters($this->getUniqueName('pre_inject_update'), $update);
|
361 |
-
$updates = $this->addUpdateToList($updates, $update->toWpFormat());
|
362 |
-
} else {
|
363 |
-
//Clean up any stale update info.
|
364 |
-
$updates = $this->removeUpdateFromList($updates);
|
365 |
-
}
|
366 |
-
|
367 |
-
return $updates;
|
368 |
-
}
|
369 |
-
|
370 |
-
/**
|
371 |
-
* @param stdClass|null $updates
|
372 |
-
* @param stdClass|array $updateToAdd
|
373 |
-
* @return stdClass
|
374 |
-
*/
|
375 |
-
protected function addUpdateToList($updates, $updateToAdd) {
|
376 |
-
if ( !is_object($updates) ) {
|
377 |
-
$updates = new stdClass();
|
378 |
-
$updates->response = array();
|
379 |
-
}
|
380 |
-
|
381 |
-
$updates->response[$this->getUpdateListKey()] = $updateToAdd;
|
382 |
-
return $updates;
|
383 |
-
}
|
384 |
-
|
385 |
-
/**
|
386 |
-
* @param stdClass|null $updates
|
387 |
-
* @return stdClass|null
|
388 |
-
*/
|
389 |
-
protected function removeUpdateFromList($updates) {
|
390 |
-
if ( isset($updates, $updates->response) ) {
|
391 |
-
unset($updates->response[$this->getUpdateListKey()]);
|
392 |
-
}
|
393 |
-
return $updates;
|
394 |
-
}
|
395 |
-
|
396 |
-
/**
|
397 |
-
* Get the key that will be used when adding updates to the update list that's maintained
|
398 |
-
* by the WordPress core. The list is always an associative array, but the key is different
|
399 |
-
* for plugins and themes.
|
400 |
-
*
|
401 |
-
* @return string
|
402 |
-
*/
|
403 |
-
abstract protected function getUpdateListKey();
|
404 |
-
|
405 |
-
/**
|
406 |
-
* Should we show available updates?
|
407 |
-
*
|
408 |
-
* Usually the answer is "yes", but there are exceptions. For example, WordPress doesn't
|
409 |
-
* support automatic updates installation for mu-plugins, so PUC usually won't show update
|
410 |
-
* notifications in that case. See the plugin-specific subclass for details.
|
411 |
-
*
|
412 |
-
* Note: This method only applies to updates that are displayed (or not) in the WordPress
|
413 |
-
* admin. It doesn't affect APIs like requestUpdate and getUpdate.
|
414 |
-
*
|
415 |
-
* @return bool
|
416 |
-
*/
|
417 |
-
protected function shouldShowUpdates() {
|
418 |
-
return true;
|
419 |
-
}
|
420 |
-
|
421 |
-
/* -------------------------------------------------------------------
|
422 |
-
* JSON-based update API
|
423 |
-
* -------------------------------------------------------------------
|
424 |
-
*/
|
425 |
-
|
426 |
-
/**
|
427 |
-
* Retrieve plugin or theme metadata from the JSON document at $this->metadataUrl.
|
428 |
-
*
|
429 |
-
* @param string $metaClass Parse the JSON as an instance of this class. It must have a static fromJson method.
|
430 |
-
* @param string $filterRoot
|
431 |
-
* @param array $queryArgs Additional query arguments.
|
432 |
-
* @return array [Puc_v4p1_Metadata|null, array|WP_Error] A metadata instance and the value returned by wp_remote_get().
|
433 |
-
*/
|
434 |
-
protected function requestMetadata($metaClass, $filterRoot, $queryArgs = array()) {
|
435 |
-
//Query args to append to the URL. Plugins can add their own by using a filter callback (see addQueryArgFilter()).
|
436 |
-
$queryArgs = array_merge(
|
437 |
-
array(
|
438 |
-
'installed_version' => strval($this->getInstalledVersion()),
|
439 |
-
'php' => phpversion(),
|
440 |
-
'locale' => get_locale(),
|
441 |
-
),
|
442 |
-
$queryArgs
|
443 |
-
);
|
444 |
-
$queryArgs = apply_filters($this->getUniqueName($filterRoot . '_query_args'), $queryArgs);
|
445 |
-
|
446 |
-
//Various options for the wp_remote_get() call. Plugins can filter these, too.
|
447 |
-
$options = array(
|
448 |
-
'timeout' => 10, //seconds
|
449 |
-
'headers' => array(
|
450 |
-
'Accept' => 'application/json',
|
451 |
-
),
|
452 |
-
);
|
453 |
-
$options = apply_filters($this->getUniqueName($filterRoot . '_options'), $options);
|
454 |
-
|
455 |
-
//The metadata file should be at 'http://your-api.com/url/here/$slug/info.json'
|
456 |
-
$url = $this->metadataUrl;
|
457 |
-
if ( !empty($queryArgs) ){
|
458 |
-
$url = add_query_arg($queryArgs, $url);
|
459 |
-
}
|
460 |
-
|
461 |
-
$result = wp_remote_get($url, $options);
|
462 |
-
|
463 |
-
//Try to parse the response
|
464 |
-
$status = $this->validateApiResponse($result);
|
465 |
-
$metadata = null;
|
466 |
-
if ( !is_wp_error($status) ){
|
467 |
-
$metadata = call_user_func(array($metaClass, 'fromJson'), $result['body']);
|
468 |
-
} else {
|
469 |
-
$this->triggerError(
|
470 |
-
sprintf('The URL %s does not point to a valid metadata file. ', $url)
|
471 |
-
. $status->get_error_message(),
|
472 |
-
E_USER_WARNING
|
473 |
-
);
|
474 |
-
}
|
475 |
-
|
476 |
-
return array($metadata, $result);
|
477 |
-
}
|
478 |
-
|
479 |
-
/**
|
480 |
-
* Check if $result is a successful update API response.
|
481 |
-
*
|
482 |
-
* @param array|WP_Error $result
|
483 |
-
* @return true|WP_Error
|
484 |
-
*/
|
485 |
-
protected function validateApiResponse($result) {
|
486 |
-
if ( is_wp_error($result) ) { /** @var WP_Error $result */
|
487 |
-
return new WP_Error($result->get_error_code(), 'WP HTTP Error: ' . $result->get_error_message());
|
488 |
-
}
|
489 |
-
|
490 |
-
if ( !isset($result['response']['code']) ) {
|
491 |
-
return new WP_Error(
|
492 |
-
'puc_no_response_code',
|
493 |
-
'wp_remote_get() returned an unexpected result.'
|
494 |
-
);
|
495 |
-
}
|
496 |
-
|
497 |
-
if ( $result['response']['code'] !== 200 ) {
|
498 |
-
return new WP_Error(
|
499 |
-
'puc_unexpected_response_code',
|
500 |
-
'HTTP response code is ' . $result['response']['code'] . ' (expected: 200)'
|
501 |
-
);
|
502 |
-
}
|
503 |
-
|
504 |
-
if ( empty($result['body']) ) {
|
505 |
-
return new WP_Error('puc_empty_response', 'The metadata file appears to be empty.');
|
506 |
-
}
|
507 |
-
|
508 |
-
return true;
|
509 |
-
}
|
510 |
-
|
511 |
-
/* -------------------------------------------------------------------
|
512 |
-
* Language packs / Translation updates
|
513 |
-
* -------------------------------------------------------------------
|
514 |
-
*/
|
515 |
-
|
516 |
-
/**
|
517 |
-
* Filter a list of translation updates and return a new list that contains only updates
|
518 |
-
* that apply to the current site.
|
519 |
-
*
|
520 |
-
* @param array $translations
|
521 |
-
* @return array
|
522 |
-
*/
|
523 |
-
protected function filterApplicableTranslations($translations) {
|
524 |
-
$languages = array_flip(array_values(get_available_languages()));
|
525 |
-
$installedTranslations = $this->getInstalledTranslations();
|
526 |
-
|
527 |
-
$applicableTranslations = array();
|
528 |
-
foreach($translations as $translation) {
|
529 |
-
//Does it match one of the available core languages?
|
530 |
-
$isApplicable = array_key_exists($translation->language, $languages);
|
531 |
-
//Is it more recent than an already-installed translation?
|
532 |
-
if ( isset($installedTranslations[$translation->language]) ) {
|
533 |
-
$updateTimestamp = strtotime($translation->updated);
|
534 |
-
$installedTimestamp = strtotime($installedTranslations[$translation->language]['PO-Revision-Date']);
|
535 |
-
$isApplicable = $updateTimestamp > $installedTimestamp;
|
536 |
-
}
|
537 |
-
|
538 |
-
if ( $isApplicable ) {
|
539 |
-
$applicableTranslations[] = $translation;
|
540 |
-
}
|
541 |
-
}
|
542 |
-
|
543 |
-
return $applicableTranslations;
|
544 |
-
}
|
545 |
-
|
546 |
-
/**
|
547 |
-
* Get a list of installed translations for this plugin or theme.
|
548 |
-
*
|
549 |
-
* @return array
|
550 |
-
*/
|
551 |
-
protected function getInstalledTranslations() {
|
552 |
-
$installedTranslations = wp_get_installed_translations($this->translationType . 's');
|
553 |
-
if ( isset($installedTranslations[$this->directoryName]) ) {
|
554 |
-
$installedTranslations = $installedTranslations[$this->directoryName];
|
555 |
-
} else {
|
556 |
-
$installedTranslations = array();
|
557 |
-
}
|
558 |
-
return $installedTranslations;
|
559 |
-
}
|
560 |
-
|
561 |
-
/**
|
562 |
-
* Insert translation updates into the list maintained by WordPress.
|
563 |
-
*
|
564 |
-
* @param stdClass $updates
|
565 |
-
* @return stdClass
|
566 |
-
*/
|
567 |
-
public function injectTranslationUpdates($updates) {
|
568 |
-
$translationUpdates = $this->getTranslationUpdates();
|
569 |
-
if ( empty($translationUpdates) ) {
|
570 |
-
return $updates;
|
571 |
-
}
|
572 |
-
|
573 |
-
//Being defensive.
|
574 |
-
if ( !is_object($updates) ) {
|
575 |
-
$updates = new stdClass();
|
576 |
-
}
|
577 |
-
if ( !isset($updates->translations) ) {
|
578 |
-
$updates->translations = array();
|
579 |
-
}
|
580 |
-
|
581 |
-
//In case there's a name collision with a plugin or theme hosted on wordpress.org,
|
582 |
-
//remove any preexisting updates that match our thing.
|
583 |
-
$updates->translations = array_values(array_filter(
|
584 |
-
$updates->translations,
|
585 |
-
array($this, 'isNotMyTranslation')
|
586 |
-
));
|
587 |
-
|
588 |
-
//Add our updates to the list.
|
589 |
-
foreach($translationUpdates as $update) {
|
590 |
-
$convertedUpdate = array_merge(
|
591 |
-
array(
|
592 |
-
'type' => $this->translationType,
|
593 |
-
'slug' => $this->directoryName,
|
594 |
-
'autoupdate' => 0,
|
595 |
-
//AFAICT, WordPress doesn't actually use the "version" field for anything.
|
596 |
-
//But lets make sure it's there, just in case.
|
597 |
-
'version' => isset($update->version) ? $update->version : ('1.' . strtotime($update->updated)),
|
598 |
-
),
|
599 |
-
(array)$update
|
600 |
-
);
|
601 |
-
|
602 |
-
$updates->translations[] = $convertedUpdate;
|
603 |
-
}
|
604 |
-
|
605 |
-
return $updates;
|
606 |
-
}
|
607 |
-
|
608 |
-
/**
|
609 |
-
* Get a list of available translation updates.
|
610 |
-
*
|
611 |
-
* This method will return an empty array if there are no updates.
|
612 |
-
* Uses cached update data.
|
613 |
-
*
|
614 |
-
* @return array
|
615 |
-
*/
|
616 |
-
public function getTranslationUpdates() {
|
617 |
-
return $this->updateState->getTranslations();
|
618 |
-
}
|
619 |
-
|
620 |
-
/**
|
621 |
-
* Remove all cached translation updates.
|
622 |
-
*
|
623 |
-
* @see wp_clean_update_cache
|
624 |
-
*/
|
625 |
-
public function clearCachedTranslationUpdates() {
|
626 |
-
$this->updateState->setTranslations(array());
|
627 |
-
}
|
628 |
-
|
629 |
-
/**
|
630 |
-
* Filter callback. Keeps only translations that *don't* match this plugin or theme.
|
631 |
-
*
|
632 |
-
* @param array $translation
|
633 |
-
* @return bool
|
634 |
-
*/
|
635 |
-
protected function isNotMyTranslation($translation) {
|
636 |
-
$isMatch = isset($translation['type'], $translation['slug'])
|
637 |
-
&& ($translation['type'] === $this->translationType)
|
638 |
-
&& ($translation['slug'] === $this->directoryName);
|
639 |
-
|
640 |
-
return !$isMatch;
|
641 |
-
}
|
642 |
-
|
643 |
-
/* -------------------------------------------------------------------
|
644 |
-
* Fix directory name when installing updates
|
645 |
-
* -------------------------------------------------------------------
|
646 |
-
*/
|
647 |
-
|
648 |
-
/**
|
649 |
-
* Rename the update directory to match the existing plugin/theme directory.
|
650 |
-
*
|
651 |
-
* When WordPress installs a plugin or theme update, it assumes that the ZIP file will contain
|
652 |
-
* exactly one directory, and that the directory name will be the same as the directory where
|
653 |
-
* the plugin or theme is currently installed.
|
654 |
-
*
|
655 |
-
* GitHub and other repositories provide ZIP downloads, but they often use directory names like
|
656 |
-
* "project-branch" or "project-tag-hash". We need to change the name to the actual plugin folder.
|
657 |
-
*
|
658 |
-
* This is a hook callback. Don't call it from a plugin.
|
659 |
-
*
|
660 |
-
* @access protected
|
661 |
-
*
|
662 |
-
* @param string $source The directory to copy to /wp-content/plugins or /wp-content/themes. Usually a subdirectory of $remoteSource.
|
663 |
-
* @param string $remoteSource WordPress has extracted the update to this directory.
|
664 |
-
* @param WP_Upgrader $upgrader
|
665 |
-
* @return string|WP_Error
|
666 |
-
*/
|
667 |
-
public function fixDirectoryName($source, $remoteSource, $upgrader) {
|
668 |
-
global $wp_filesystem;
|
669 |
-
/** @var WP_Filesystem_Base $wp_filesystem */
|
670 |
-
|
671 |
-
//Basic sanity checks.
|
672 |
-
if ( !isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem) ) {
|
673 |
-
return $source;
|
674 |
-
}
|
675 |
-
|
676 |
-
//If WordPress is upgrading anything other than our plugin/theme, leave the directory name unchanged.
|
677 |
-
if ( !$this->isBeingUpgraded($upgrader) ) {
|
678 |
-
return $source;
|
679 |
-
}
|
680 |
-
|
681 |
-
//Rename the source to match the existing directory.
|
682 |
-
$correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
|
683 |
-
if ( $source !== $correctedSource ) {
|
684 |
-
//The update archive should contain a single directory that contains the rest of plugin/theme files.
|
685 |
-
//Otherwise, WordPress will try to copy the entire working directory ($source == $remoteSource).
|
686 |
-
//We can't rename $remoteSource because that would break WordPress code that cleans up temporary files
|
687 |
-
//after update.
|
688 |
-
if ( $this->isBadDirectoryStructure($remoteSource) ) {
|
689 |
-
return new WP_Error(
|
690 |
-
'puc-incorrect-directory-structure',
|
691 |
-
sprintf(
|
692 |
-
'The directory structure of the update is incorrect. All files should be inside ' .
|
693 |
-
'a directory named <span class="code">%s</span>, not at the root of the ZIP archive.',
|
694 |
-
htmlentities($this->slug)
|
695 |
-
)
|
696 |
-
);
|
697 |
-
}
|
698 |
-
|
699 |
-
/** @var WP_Upgrader_Skin $upgrader ->skin */
|
700 |
-
$upgrader->skin->feedback(sprintf(
|
701 |
-
'Renaming %s to %s…',
|
702 |
-
'<span class="code">' . basename($source) . '</span>',
|
703 |
-
'<span class="code">' . $this->directoryName . '</span>'
|
704 |
-
));
|
705 |
-
|
706 |
-
if ( $wp_filesystem->move($source, $correctedSource, true) ) {
|
707 |
-
$upgrader->skin->feedback('Directory successfully renamed.');
|
708 |
-
return $correctedSource;
|
709 |
-
} else {
|
710 |
-
return new WP_Error(
|
711 |
-
'puc-rename-failed',
|
712 |
-
'Unable to rename the update to match the existing directory.'
|
713 |
-
);
|
714 |
-
}
|
715 |
-
}
|
716 |
-
|
717 |
-
return $source;
|
718 |
-
}
|
719 |
-
|
720 |
-
/**
|
721 |
-
* Is there an update being installed right now, for this plugin or theme?
|
722 |
-
*
|
723 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
724 |
-
* @return bool
|
725 |
-
*/
|
726 |
-
abstract public function isBeingUpgraded($upgrader = null);
|
727 |
-
|
728 |
-
/**
|
729 |
-
* Check for incorrect update directory structure. An update must contain a single directory,
|
730 |
-
* all other files should be inside that directory.
|
731 |
-
*
|
732 |
-
* @param string $remoteSource Directory path.
|
733 |
-
* @return bool
|
734 |
-
*/
|
735 |
-
protected function isBadDirectoryStructure($remoteSource) {
|
736 |
-
global $wp_filesystem;
|
737 |
-
/** @var WP_Filesystem_Base $wp_filesystem */
|
738 |
-
|
739 |
-
$sourceFiles = $wp_filesystem->dirlist($remoteSource);
|
740 |
-
if ( is_array($sourceFiles) ) {
|
741 |
-
$sourceFiles = array_keys($sourceFiles);
|
742 |
-
$firstFilePath = trailingslashit($remoteSource) . $sourceFiles[0];
|
743 |
-
return (count($sourceFiles) > 1) || (!$wp_filesystem->is_dir($firstFilePath));
|
744 |
-
}
|
745 |
-
|
746 |
-
//Assume it's fine.
|
747 |
-
return false;
|
748 |
-
}
|
749 |
-
|
750 |
-
/* -------------------------------------------------------------------
|
751 |
-
* File header parsing
|
752 |
-
* -------------------------------------------------------------------
|
753 |
-
*/
|
754 |
-
|
755 |
-
/**
|
756 |
-
* Parse plugin or theme metadata from the header comment.
|
757 |
-
*
|
758 |
-
* This is basically a simplified version of the get_file_data() function from /wp-includes/functions.php.
|
759 |
-
* It's intended as a utility for subclasses that detect updates by parsing files in a VCS.
|
760 |
-
*
|
761 |
-
* @param string|null $content File contents.
|
762 |
-
* @return string[]
|
763 |
-
*/
|
764 |
-
public function getFileHeader($content) {
|
765 |
-
$content = (string) $content;
|
766 |
-
|
767 |
-
//WordPress only looks at the first 8 KiB of the file, so we do the same.
|
768 |
-
$content = substr($content, 0, 8192);
|
769 |
-
//Normalize line endings.
|
770 |
-
$content = str_replace("\r", "\n", $content);
|
771 |
-
|
772 |
-
$headers = $this->getHeaderNames();
|
773 |
-
$results = array();
|
774 |
-
foreach ($headers as $field => $name) {
|
775 |
-
$success = preg_match('/^[ \t\/*#@]*' . preg_quote($name, '/') . ':(.*)$/mi', $content, $matches);
|
776 |
-
|
777 |
-
if ( ($success === 1) && $matches[1] ) {
|
778 |
-
$value = $matches[1];
|
779 |
-
if ( function_exists('_cleanup_header_comment') ) {
|
780 |
-
$value = _cleanup_header_comment($value);
|
781 |
-
}
|
782 |
-
$results[$field] = $value;
|
783 |
-
} else {
|
784 |
-
$results[$field] = '';
|
785 |
-
}
|
786 |
-
}
|
787 |
-
|
788 |
-
return $results;
|
789 |
-
}
|
790 |
-
|
791 |
-
/**
|
792 |
-
* @return array Format: ['HeaderKey' => 'Header Name']
|
793 |
-
*/
|
794 |
-
abstract protected function getHeaderNames();
|
795 |
-
|
796 |
-
/* -------------------------------------------------------------------
|
797 |
-
* DebugBar integration
|
798 |
-
* -------------------------------------------------------------------
|
799 |
-
*/
|
800 |
-
|
801 |
-
/**
|
802 |
-
* Initialize the update checker Debug Bar plugin/add-on thingy.
|
803 |
-
*/
|
804 |
-
public function maybeInitDebugBar() {
|
805 |
-
if ( class_exists('Debug_Bar', false) && file_exists(dirname(__FILE__ . '/DebugBar')) ) {
|
806 |
-
$this->createDebugBarExtension();
|
807 |
-
}
|
808 |
-
}
|
809 |
-
|
810 |
-
protected function createDebugBarExtension() {
|
811 |
-
return new Puc_v4p1_DebugBar_Extension($this);
|
812 |
-
}
|
813 |
-
|
814 |
-
/**
|
815 |
-
* Display additional configuration details in the Debug Bar panel.
|
816 |
-
*
|
817 |
-
* @param Puc_v4p1_DebugBar_Panel $panel
|
818 |
-
*/
|
819 |
-
public function onDisplayConfiguration($panel) {
|
820 |
-
//Do nothing. Subclasses can use this to add additional info to the panel.
|
821 |
-
}
|
822 |
-
|
823 |
-
}
|
824 |
-
|
825 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/UpgraderStatus.php
DELETED
@@ -1,199 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_UpgraderStatus', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A utility class that helps figure out which plugin or theme WordPress is upgrading.
|
6 |
-
*
|
7 |
-
* It may seem strange to have a separate class just for that, but the task is surprisingly complicated.
|
8 |
-
* Core classes like Plugin_Upgrader don't expose the plugin file name during an in-progress update (AFAICT).
|
9 |
-
* This class uses a few workarounds and heuristics to get the file name.
|
10 |
-
*/
|
11 |
-
class Puc_v4p1_UpgraderStatus {
|
12 |
-
private $currentType = null; //"plugin" or "theme".
|
13 |
-
private $currentId = null; //Plugin basename or theme directory name.
|
14 |
-
|
15 |
-
public function __construct() {
|
16 |
-
//Keep track of which plugin/theme WordPress is currently upgrading.
|
17 |
-
add_filter('upgrader_pre_install', array($this, 'setUpgradedThing'), 10, 2);
|
18 |
-
add_filter('upgrader_package_options', array($this, 'setUpgradedPluginFromOptions'), 10, 1);
|
19 |
-
add_filter('upgrader_post_install', array($this, 'clearUpgradedThing'), 10, 1);
|
20 |
-
add_action('upgrader_process_complete', array($this, 'clearUpgradedThing'), 10, 1);
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Is there and update being installed RIGHT NOW, for a specific plugin?
|
25 |
-
*
|
26 |
-
* Caution: This method is unreliable. WordPress doesn't make it easy to figure out what it is upgrading,
|
27 |
-
* and upgrader implementations are liable to change without notice.
|
28 |
-
*
|
29 |
-
* @param string $pluginFile The plugin to check.
|
30 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
31 |
-
* @return bool True if the plugin identified by $pluginFile is being upgraded.
|
32 |
-
*/
|
33 |
-
public function isPluginBeingUpgraded($pluginFile, $upgrader = null) {
|
34 |
-
return $this->isBeingUpgraded('plugin', $pluginFile, $upgrader);
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Is there an update being installed for a specific theme?
|
39 |
-
*
|
40 |
-
* @param string $stylesheet Theme directory name.
|
41 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
42 |
-
* @return bool
|
43 |
-
*/
|
44 |
-
public function isThemeBeingUpgraded($stylesheet, $upgrader = null) {
|
45 |
-
return $this->isBeingUpgraded('theme', $stylesheet, $upgrader);
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Check if a specific theme or plugin is being upgraded.
|
50 |
-
*
|
51 |
-
* @param string $type
|
52 |
-
* @param string $id
|
53 |
-
* @param Plugin_Upgrader|WP_Upgrader|null $upgrader
|
54 |
-
* @return bool
|
55 |
-
*/
|
56 |
-
protected function isBeingUpgraded($type, $id, $upgrader = null) {
|
57 |
-
if ( isset($upgrader) ) {
|
58 |
-
list($currentType, $currentId) = $this->getThingBeingUpgradedBy($upgrader);
|
59 |
-
if ( $currentType !== null ) {
|
60 |
-
$this->currentType = $currentType;
|
61 |
-
$this->currentId = $currentId;
|
62 |
-
}
|
63 |
-
}
|
64 |
-
return ($this->currentType === $type) && ($this->currentId === $id);
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Figure out which theme or plugin is being upgraded by a WP_Upgrader instance.
|
69 |
-
*
|
70 |
-
* Returns an array with two items. The first item is the type of the thing that's being
|
71 |
-
* upgraded: "plugin" or "theme". The second item is either the plugin basename or
|
72 |
-
* the theme directory name. If we can't determine what the upgrader is doing, both items
|
73 |
-
* will be NULL.
|
74 |
-
*
|
75 |
-
* Examples:
|
76 |
-
* ['plugin', 'plugin-dir-name/plugin.php']
|
77 |
-
* ['theme', 'theme-dir-name']
|
78 |
-
*
|
79 |
-
* @param Plugin_Upgrader|WP_Upgrader $upgrader
|
80 |
-
* @return array
|
81 |
-
*/
|
82 |
-
private function getThingBeingUpgradedBy($upgrader) {
|
83 |
-
if ( !isset($upgrader, $upgrader->skin) ) {
|
84 |
-
return array(null, null);
|
85 |
-
}
|
86 |
-
|
87 |
-
//Figure out which plugin or theme is being upgraded.
|
88 |
-
$pluginFile = null;
|
89 |
-
$themeDirectoryName = null;
|
90 |
-
|
91 |
-
$skin = $upgrader->skin;
|
92 |
-
if ( isset($skin->theme_info) && ($skin->theme_info instanceof WP_Theme) ) {
|
93 |
-
$themeDirectoryName = $skin->theme_info->get_stylesheet();
|
94 |
-
} elseif ( $skin instanceof Plugin_Upgrader_Skin ) {
|
95 |
-
if ( isset($skin->plugin) && is_string($skin->plugin) && ($skin->plugin !== '') ) {
|
96 |
-
$pluginFile = $skin->plugin;
|
97 |
-
}
|
98 |
-
} elseif ( $skin instanceof Theme_Upgrader_Skin ) {
|
99 |
-
if ( isset($skin->theme) && is_string($skin->theme) && ($skin->theme !== '') ) {
|
100 |
-
$themeDirectoryName = $skin->theme;
|
101 |
-
}
|
102 |
-
} elseif ( isset($skin->plugin_info) && is_array($skin->plugin_info) ) {
|
103 |
-
//This case is tricky because Bulk_Plugin_Upgrader_Skin (etc) doesn't actually store the plugin
|
104 |
-
//filename anywhere. Instead, it has the plugin headers in $plugin_info. So the best we can
|
105 |
-
//do is compare those headers to the headers of installed plugins.
|
106 |
-
$pluginFile = $this->identifyPluginByHeaders($skin->plugin_info);
|
107 |
-
}
|
108 |
-
|
109 |
-
if ( $pluginFile !== null ) {
|
110 |
-
return array('plugin', $pluginFile);
|
111 |
-
} elseif ( $themeDirectoryName !== null ) {
|
112 |
-
return array('theme', $themeDirectoryName);
|
113 |
-
}
|
114 |
-
return array(null, null);
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Identify an installed plugin based on its headers.
|
119 |
-
*
|
120 |
-
* @param array $searchHeaders The plugin file header to look for.
|
121 |
-
* @return string|null Plugin basename ("foo/bar.php"), or NULL if we can't identify the plugin.
|
122 |
-
*/
|
123 |
-
private function identifyPluginByHeaders($searchHeaders) {
|
124 |
-
if ( !function_exists('get_plugins') ){
|
125 |
-
/** @noinspection PhpIncludeInspection */
|
126 |
-
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
127 |
-
}
|
128 |
-
|
129 |
-
$installedPlugins = get_plugins();
|
130 |
-
$matches = array();
|
131 |
-
foreach($installedPlugins as $pluginBasename => $headers) {
|
132 |
-
$diff1 = array_diff_assoc($headers, $searchHeaders);
|
133 |
-
$diff2 = array_diff_assoc($searchHeaders, $headers);
|
134 |
-
if ( empty($diff1) && empty($diff2) ) {
|
135 |
-
$matches[] = $pluginBasename;
|
136 |
-
}
|
137 |
-
}
|
138 |
-
|
139 |
-
//It's possible (though very unlikely) that there could be two plugins with identical
|
140 |
-
//headers. In that case, we can't unambiguously identify the plugin that's being upgraded.
|
141 |
-
if ( count($matches) !== 1 ) {
|
142 |
-
return null;
|
143 |
-
}
|
144 |
-
|
145 |
-
return reset($matches);
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* @access private
|
150 |
-
*
|
151 |
-
* @param mixed $input
|
152 |
-
* @param array $hookExtra
|
153 |
-
* @return mixed Returns $input unaltered.
|
154 |
-
*/
|
155 |
-
public function setUpgradedThing($input, $hookExtra) {
|
156 |
-
if ( !empty($hookExtra['plugin']) && is_string($hookExtra['plugin']) ) {
|
157 |
-
$this->currentId = $hookExtra['plugin'];
|
158 |
-
$this->currentType = 'plugin';
|
159 |
-
} elseif ( !empty($hookExtra['theme']) && is_string($hookExtra['theme']) ) {
|
160 |
-
$this->currentId = $hookExtra['theme'];
|
161 |
-
$this->currentType = 'theme';
|
162 |
-
} else {
|
163 |
-
$this->currentType = null;
|
164 |
-
$this->currentId = null;
|
165 |
-
}
|
166 |
-
return $input;
|
167 |
-
}
|
168 |
-
|
169 |
-
/**
|
170 |
-
* @access private
|
171 |
-
*
|
172 |
-
* @param array $options
|
173 |
-
* @return array
|
174 |
-
*/
|
175 |
-
public function setUpgradedPluginFromOptions($options) {
|
176 |
-
if ( isset($options['hook_extra']['plugin']) && is_string($options['hook_extra']['plugin']) ) {
|
177 |
-
$this->currentType = 'plugin';
|
178 |
-
$this->currentId = $options['hook_extra']['plugin'];
|
179 |
-
} else {
|
180 |
-
$this->currentType = null;
|
181 |
-
$this->currentId = null;
|
182 |
-
}
|
183 |
-
return $options;
|
184 |
-
}
|
185 |
-
|
186 |
-
/**
|
187 |
-
* @access private
|
188 |
-
*
|
189 |
-
* @param mixed $input
|
190 |
-
* @return mixed Returns $input unaltered.
|
191 |
-
*/
|
192 |
-
public function clearUpgradedThing($input = null) {
|
193 |
-
$this->currentId = null;
|
194 |
-
$this->currentType = null;
|
195 |
-
return $input;
|
196 |
-
}
|
197 |
-
}
|
198 |
-
|
199 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Utils.php
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_Utils', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_Utils {
|
6 |
-
/**
|
7 |
-
* Get a value from a nested array or object based on a path.
|
8 |
-
*
|
9 |
-
* @param array|object|null $collection Get an entry from this array.
|
10 |
-
* @param array|string $path A list of array keys in hierarchy order, or a string path like "foo.bar.baz".
|
11 |
-
* @param mixed $default The value to return if the specified path is not found.
|
12 |
-
* @param string $separator Path element separator. Only applies to string paths.
|
13 |
-
* @return mixed
|
14 |
-
*/
|
15 |
-
public static function get($collection, $path, $default = null, $separator = '.') {
|
16 |
-
if ( is_string($path) ) {
|
17 |
-
$path = explode($separator, $path);
|
18 |
-
}
|
19 |
-
if ( empty($path) ) {
|
20 |
-
return $default;
|
21 |
-
}
|
22 |
-
|
23 |
-
//Follow the $path into $input as far as possible.
|
24 |
-
$currentValue = $collection;
|
25 |
-
$pathExists = true;
|
26 |
-
foreach ($path as $node) {
|
27 |
-
if ( is_array($currentValue) && isset($currentValue[$node]) ) {
|
28 |
-
$currentValue = $currentValue[$node];
|
29 |
-
} else if ( is_object($currentValue) && isset($currentValue->$node) ) {
|
30 |
-
$currentValue = $currentValue->$node;
|
31 |
-
} else {
|
32 |
-
$pathExists = false;
|
33 |
-
break;
|
34 |
-
}
|
35 |
-
}
|
36 |
-
|
37 |
-
if ( $pathExists ) {
|
38 |
-
return $currentValue;
|
39 |
-
}
|
40 |
-
return $default;
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Get the first array element that is not empty.
|
45 |
-
*
|
46 |
-
* @param array $values
|
47 |
-
* @param mixed|null $default Returns this value if there are no non-empty elements.
|
48 |
-
* @return mixed|null
|
49 |
-
*/
|
50 |
-
public static function findNotEmpty($values, $default = null) {
|
51 |
-
if ( empty($values) ) {
|
52 |
-
return $default;
|
53 |
-
}
|
54 |
-
|
55 |
-
foreach ($values as $value) {
|
56 |
-
if ( !empty($value) ) {
|
57 |
-
return $value;
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
return $default;
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Check if the input string starts with the specified prefix.
|
66 |
-
*
|
67 |
-
* @param string $input
|
68 |
-
* @param string $prefix
|
69 |
-
* @return bool
|
70 |
-
*/
|
71 |
-
public static function startsWith($input, $prefix) {
|
72 |
-
$length = strlen($prefix);
|
73 |
-
return (substr($input, 0, $length) === $prefix);
|
74 |
-
}
|
75 |
-
}
|
76 |
-
|
77 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Vcs/Api.php
DELETED
@@ -1,243 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Vcs_Api') ):
|
3 |
-
|
4 |
-
abstract class Puc_v4p1_Vcs_Api {
|
5 |
-
protected $tagNameProperty = 'name';
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var string
|
9 |
-
*/
|
10 |
-
protected $repositoryUrl = '';
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var mixed Authentication details for private repositories. Format depends on service.
|
14 |
-
*/
|
15 |
-
protected $credentials = null;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string The filter tag that's used to filter options passed to wp_remote_get.
|
19 |
-
* For example, "puc_request_info_options-slug" or "puc_request_update_options_theme-slug".
|
20 |
-
*/
|
21 |
-
protected $httpFilterName = '';
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Puc_v4p1_Vcs_Api constructor.
|
25 |
-
*
|
26 |
-
* @param string $repositoryUrl
|
27 |
-
* @param array|string|null $credentials
|
28 |
-
*/
|
29 |
-
public function __construct($repositoryUrl, $credentials = null) {
|
30 |
-
$this->repositoryUrl = $repositoryUrl;
|
31 |
-
$this->setAuthentication($credentials);
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @return string
|
36 |
-
*/
|
37 |
-
public function getRepositoryUrl() {
|
38 |
-
return $this->repositoryUrl;
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Figure out which reference (i.e tag or branch) contains the latest version.
|
43 |
-
*
|
44 |
-
* @param string $configBranch Start looking in this branch.
|
45 |
-
* @return null|Puc_v4p1_Vcs_Reference
|
46 |
-
*/
|
47 |
-
abstract public function chooseReference($configBranch);
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Get the readme.txt file from the remote repository and parse it
|
51 |
-
* according to the plugin readme standard.
|
52 |
-
*
|
53 |
-
* @param string $ref Tag or branch name.
|
54 |
-
* @return array Parsed readme.
|
55 |
-
*/
|
56 |
-
public function getRemoteReadme($ref = 'master') {
|
57 |
-
$fileContents = $this->getRemoteFile('readme.txt', $ref);
|
58 |
-
if ( empty($fileContents) ) {
|
59 |
-
return array();
|
60 |
-
}
|
61 |
-
|
62 |
-
$parser = new PucReadmeParser();
|
63 |
-
return $parser->parse_readme_contents($fileContents);
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Get a branch.
|
68 |
-
*
|
69 |
-
* @param string $branchName
|
70 |
-
* @return Puc_v4p1_Vcs_Reference|null
|
71 |
-
*/
|
72 |
-
abstract public function getBranch($branchName);
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Get a specific tag.
|
76 |
-
*
|
77 |
-
* @param string $tagName
|
78 |
-
* @return Puc_v4p1_Vcs_Reference|null
|
79 |
-
*/
|
80 |
-
abstract public function getTag($tagName);
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Get the tag that looks like the highest version number.
|
84 |
-
* (Implementations should skip pre-release versions if possible.)
|
85 |
-
*
|
86 |
-
* @return Puc_v4p1_Vcs_Reference|null
|
87 |
-
*/
|
88 |
-
abstract public function getLatestTag();
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Check if a tag name string looks like a version number.
|
92 |
-
*
|
93 |
-
* @param string $name
|
94 |
-
* @return bool
|
95 |
-
*/
|
96 |
-
protected function looksLikeVersion($name) {
|
97 |
-
//Tag names may be prefixed with "v", e.g. "v1.2.3".
|
98 |
-
$name = ltrim($name, 'v');
|
99 |
-
|
100 |
-
//The version string must start with a number.
|
101 |
-
if ( !is_numeric(substr($name, 0, 1)) ) {
|
102 |
-
return false;
|
103 |
-
}
|
104 |
-
|
105 |
-
//The goal is to accept any SemVer-compatible or "PHP-standardized" version number.
|
106 |
-
return (preg_match('@^(\d{1,5}?)(\.\d{1,10}?){0,4}?($|[abrdp+_\-]|\s)@i', $name) === 1);
|
107 |
-
}
|
108 |
-
|
109 |
-
/**
|
110 |
-
* Check if a tag appears to be named like a version number.
|
111 |
-
*
|
112 |
-
* @param stdClass $tag
|
113 |
-
* @return bool
|
114 |
-
*/
|
115 |
-
protected function isVersionTag($tag) {
|
116 |
-
$property = $this->tagNameProperty;
|
117 |
-
return isset($tag->$property) && $this->looksLikeVersion($tag->$property);
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* Sort a list of tags as if they were version numbers.
|
122 |
-
* Tags that don't look like version number will be removed.
|
123 |
-
*
|
124 |
-
* @param stdClass[] $tags Array of tag objects.
|
125 |
-
* @return stdClass[] Filtered array of tags sorted in descending order.
|
126 |
-
*/
|
127 |
-
protected function sortTagsByVersion($tags) {
|
128 |
-
//Keep only those tags that look like version numbers.
|
129 |
-
$versionTags = array_filter($tags, array($this, 'isVersionTag'));
|
130 |
-
//Sort them in descending order.
|
131 |
-
usort($versionTags, array($this, 'compareTagNames'));
|
132 |
-
|
133 |
-
return $versionTags;
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Compare two tags as if they were version number.
|
138 |
-
*
|
139 |
-
* @param stdClass $tag1 Tag object.
|
140 |
-
* @param stdClass $tag2 Another tag object.
|
141 |
-
* @return int
|
142 |
-
*/
|
143 |
-
protected function compareTagNames($tag1, $tag2) {
|
144 |
-
$property = $this->tagNameProperty;
|
145 |
-
if ( !isset($tag1->$property) ) {
|
146 |
-
return 1;
|
147 |
-
}
|
148 |
-
if ( !isset($tag2->$property) ) {
|
149 |
-
return -1;
|
150 |
-
}
|
151 |
-
return -version_compare(ltrim($tag1->$property, 'v'), ltrim($tag2->$property, 'v'));
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* Get the contents of a file from a specific branch or tag.
|
156 |
-
*
|
157 |
-
* @param string $path File name.
|
158 |
-
* @param string $ref
|
159 |
-
* @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
|
160 |
-
*/
|
161 |
-
abstract public function getRemoteFile($path, $ref = 'master');
|
162 |
-
|
163 |
-
/**
|
164 |
-
* Get the timestamp of the latest commit that changed the specified branch or tag.
|
165 |
-
*
|
166 |
-
* @param string $ref Reference name (e.g. branch or tag).
|
167 |
-
* @return string|null
|
168 |
-
*/
|
169 |
-
abstract public function getLatestCommitTime($ref);
|
170 |
-
|
171 |
-
/**
|
172 |
-
* Get the contents of the changelog file from the repository.
|
173 |
-
*
|
174 |
-
* @param string $ref
|
175 |
-
* @param string $localDirectory Full path to the local plugin or theme directory.
|
176 |
-
* @return null|string The HTML contents of the changelog.
|
177 |
-
*/
|
178 |
-
public function getRemoteChangelog($ref, $localDirectory) {
|
179 |
-
$filename = $this->findChangelogName($localDirectory);
|
180 |
-
if ( empty($filename) ) {
|
181 |
-
return null;
|
182 |
-
}
|
183 |
-
|
184 |
-
$changelog = $this->getRemoteFile($filename, $ref);
|
185 |
-
if ( $changelog === null ) {
|
186 |
-
return null;
|
187 |
-
}
|
188 |
-
|
189 |
-
/** @noinspection PhpUndefinedClassInspection */
|
190 |
-
return Parsedown::instance()->text($changelog);
|
191 |
-
}
|
192 |
-
|
193 |
-
/**
|
194 |
-
* Guess the name of the changelog file.
|
195 |
-
*
|
196 |
-
* @param string $directory
|
197 |
-
* @return string|null
|
198 |
-
*/
|
199 |
-
protected function findChangelogName($directory) {
|
200 |
-
if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
|
201 |
-
return null;
|
202 |
-
}
|
203 |
-
|
204 |
-
$possibleNames = array('CHANGES.md', 'CHANGELOG.md', 'changes.md', 'changelog.md');
|
205 |
-
$files = scandir($directory);
|
206 |
-
$foundNames = array_intersect($possibleNames, $files);
|
207 |
-
|
208 |
-
if ( !empty($foundNames) ) {
|
209 |
-
return reset($foundNames);
|
210 |
-
}
|
211 |
-
return null;
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Set authentication credentials.
|
216 |
-
*
|
217 |
-
* @param $credentials
|
218 |
-
*/
|
219 |
-
public function setAuthentication($credentials) {
|
220 |
-
$this->credentials = $credentials;
|
221 |
-
}
|
222 |
-
|
223 |
-
public function isAuthenticationEnabled() {
|
224 |
-
return !empty($this->credentials);
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* @param string $url
|
229 |
-
* @return string
|
230 |
-
*/
|
231 |
-
public function signDownloadUrl($url) {
|
232 |
-
return $url;
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* @param string $filterName
|
237 |
-
*/
|
238 |
-
public function setHttpFilterName($filterName) {
|
239 |
-
$this->httpFilterName = $filterName;
|
240 |
-
}
|
241 |
-
}
|
242 |
-
|
243 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Vcs/BaseChecker.php
DELETED
@@ -1,22 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !interface_exists('Puc_v4p1_Vcs_BaseChecker', false) ):
|
3 |
-
|
4 |
-
interface Puc_v4p1_Vcs_BaseChecker {
|
5 |
-
/**
|
6 |
-
* Set the repository branch to use for updates. Defaults to 'master'.
|
7 |
-
*
|
8 |
-
* @param string $branch
|
9 |
-
* @return $this
|
10 |
-
*/
|
11 |
-
public function setBranch($branch);
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Set authentication credentials.
|
15 |
-
*
|
16 |
-
* @param array|string $credentials
|
17 |
-
* @return $this
|
18 |
-
*/
|
19 |
-
public function setAuthentication($credentials);
|
20 |
-
}
|
21 |
-
|
22 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Vcs/BitBucketApi.php
DELETED
@@ -1,251 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Vcs_BitBucketApi', false) ):
|
3 |
-
|
4 |
-
class Puc_v4p1_Vcs_BitBucketApi extends Puc_v4p1_Vcs_Api {
|
5 |
-
/**
|
6 |
-
* @var Puc_v4p1_OAuthSignature
|
7 |
-
*/
|
8 |
-
private $oauth = null;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var string
|
12 |
-
*/
|
13 |
-
private $username;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
private $repository;
|
19 |
-
|
20 |
-
public function __construct($repositoryUrl, $credentials = array()) {
|
21 |
-
$path = @parse_url($repositoryUrl, PHP_URL_PATH);
|
22 |
-
if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
|
23 |
-
$this->username = $matches['username'];
|
24 |
-
$this->repository = $matches['repository'];
|
25 |
-
} else {
|
26 |
-
throw new InvalidArgumentException('Invalid BitBucket repository URL: "' . $repositoryUrl . '"');
|
27 |
-
}
|
28 |
-
|
29 |
-
parent::__construct($repositoryUrl, $credentials);
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Figure out which reference (i.e tag or branch) contains the latest version.
|
34 |
-
*
|
35 |
-
* @param string $configBranch Start looking in this branch.
|
36 |
-
* @return null|Puc_v4p1_Vcs_Reference
|
37 |
-
*/
|
38 |
-
public function chooseReference($configBranch) {
|
39 |
-
$updateSource = null;
|
40 |
-
|
41 |
-
//Check if there's a "Stable tag: 1.2.3" header that points to a valid tag.
|
42 |
-
$updateSource = $this->getStableTag($configBranch);
|
43 |
-
|
44 |
-
//Look for version-like tags.
|
45 |
-
if ( !$updateSource && ($configBranch === 'master') ) {
|
46 |
-
$updateSource = $this->getLatestTag();
|
47 |
-
}
|
48 |
-
//If all else fails, use the specified branch itself.
|
49 |
-
if ( !$updateSource ) {
|
50 |
-
$updateSource = $this->getBranch($configBranch);
|
51 |
-
}
|
52 |
-
|
53 |
-
return $updateSource;
|
54 |
-
}
|
55 |
-
|
56 |
-
public function getBranch($branchName) {
|
57 |
-
$branch = $this->api('/refs/branches/' . $branchName);
|
58 |
-
if ( is_wp_error($branch) || empty($branch) ) {
|
59 |
-
return null;
|
60 |
-
}
|
61 |
-
|
62 |
-
return new Puc_v4p1_Vcs_Reference(array(
|
63 |
-
'name' => $branch->name,
|
64 |
-
'updated' => $branch->target->date,
|
65 |
-
'downloadUrl' => $this->getDownloadUrl($branch->name),
|
66 |
-
));
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Get a specific tag.
|
71 |
-
*
|
72 |
-
* @param string $tagName
|
73 |
-
* @return Puc_v4p1_Vcs_Reference|null
|
74 |
-
*/
|
75 |
-
public function getTag($tagName) {
|
76 |
-
$tag = $this->api('/refs/tags/' . $tagName);
|
77 |
-
if ( is_wp_error($tag) || empty($tag) ) {
|
78 |
-
return null;
|
79 |
-
}
|
80 |
-
|
81 |
-
return new Puc_v4p1_Vcs_Reference(array(
|
82 |
-
'name' => $tag->name,
|
83 |
-
'version' => ltrim($tag->name, 'v'),
|
84 |
-
'updated' => $tag->target->date,
|
85 |
-
'downloadUrl' => $this->getDownloadUrl($tag->name),
|
86 |
-
));
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Get the tag that looks like the highest version number.
|
91 |
-
*
|
92 |
-
* @return Puc_v4p1_Vcs_Reference|null
|
93 |
-
*/
|
94 |
-
public function getLatestTag() {
|
95 |
-
$tags = $this->api('/refs/tags?sort=-target.date');
|
96 |
-
if ( !isset($tags, $tags->values) || !is_array($tags->values) ) {
|
97 |
-
return null;
|
98 |
-
}
|
99 |
-
|
100 |
-
//Filter and sort the list of tags.
|
101 |
-
$versionTags = $this->sortTagsByVersion($tags->values);
|
102 |
-
|
103 |
-
//Return the first result.
|
104 |
-
if ( !empty($versionTags) ) {
|
105 |
-
$tag = $versionTags[0];
|
106 |
-
return new Puc_v4p1_Vcs_Reference(array(
|
107 |
-
'name' => $tag->name,
|
108 |
-
'version' => ltrim($tag->name, 'v'),
|
109 |
-
'updated' => $tag->target->date,
|
110 |
-
'downloadUrl' => $this->getDownloadUrl($tag->name),
|
111 |
-
));
|
112 |
-
}
|
113 |
-
return null;
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
|
118 |
-
*
|
119 |
-
* @param string $branch
|
120 |
-
* @return null|Puc_v4p1_Vcs_Reference
|
121 |
-
*/
|
122 |
-
protected function getStableTag($branch) {
|
123 |
-
$remoteReadme = $this->getRemoteReadme($branch);
|
124 |
-
if ( !empty($remoteReadme['stable_tag']) ) {
|
125 |
-
$tag = $remoteReadme['stable_tag'];
|
126 |
-
|
127 |
-
//You can explicitly opt out of using tags by setting "Stable tag" to
|
128 |
-
//"trunk" or the name of the current branch.
|
129 |
-
if ( ($tag === $branch) || ($tag === 'trunk') ) {
|
130 |
-
return $this->getBranch($branch);
|
131 |
-
}
|
132 |
-
|
133 |
-
return $this->getTag($tag);
|
134 |
-
}
|
135 |
-
|
136 |
-
return null;
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* @param string $ref
|
141 |
-
* @return string
|
142 |
-
*/
|
143 |
-
protected function getDownloadUrl($ref) {
|
144 |
-
return sprintf(
|
145 |
-
'https://bitbucket.org/%s/%s/get/%s.zip',
|
146 |
-
$this->username,
|
147 |
-
$this->repository,
|
148 |
-
$ref
|
149 |
-
);
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Get the contents of a file from a specific branch or tag.
|
154 |
-
*
|
155 |
-
* @param string $path File name.
|
156 |
-
* @param string $ref
|
157 |
-
* @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
|
158 |
-
*/
|
159 |
-
public function getRemoteFile($path, $ref = 'master') {
|
160 |
-
$response = $this->api('src/' . $ref . '/' . ltrim($path), '1.0');
|
161 |
-
if ( is_wp_error($response) || !isset($response, $response->data) ) {
|
162 |
-
return null;
|
163 |
-
}
|
164 |
-
return $response->data;
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Get the timestamp of the latest commit that changed the specified branch or tag.
|
169 |
-
*
|
170 |
-
* @param string $ref Reference name (e.g. branch or tag).
|
171 |
-
* @return string|null
|
172 |
-
*/
|
173 |
-
public function getLatestCommitTime($ref) {
|
174 |
-
$response = $this->api('commits/' . $ref);
|
175 |
-
if ( isset($response->values, $response->values[0], $response->values[0]->date) ) {
|
176 |
-
return $response->values[0]->date;
|
177 |
-
}
|
178 |
-
return null;
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Perform a BitBucket API 2.0 request.
|
183 |
-
*
|
184 |
-
* @param string $url
|
185 |
-
* @param string $version
|
186 |
-
* @return mixed|WP_Error
|
187 |
-
*/
|
188 |
-
public function api($url, $version = '2.0') {
|
189 |
-
$url = implode('/', array(
|
190 |
-
'https://api.bitbucket.org',
|
191 |
-
$version,
|
192 |
-
'repositories',
|
193 |
-
$this->username,
|
194 |
-
$this->repository,
|
195 |
-
ltrim($url, '/')
|
196 |
-
));
|
197 |
-
|
198 |
-
if ( $this->oauth ) {
|
199 |
-
$url = $this->oauth->sign($url,'GET');
|
200 |
-
}
|
201 |
-
|
202 |
-
$options = array('timeout' => 10);
|
203 |
-
if ( !empty($this->httpFilterName) ) {
|
204 |
-
$options = apply_filters($this->httpFilterName, $options);
|
205 |
-
}
|
206 |
-
$response = wp_remote_get($url, $options);
|
207 |
-
if ( is_wp_error($response) ) {
|
208 |
-
return $response;
|
209 |
-
}
|
210 |
-
|
211 |
-
$code = wp_remote_retrieve_response_code($response);
|
212 |
-
$body = wp_remote_retrieve_body($response);
|
213 |
-
if ( $code === 200 ) {
|
214 |
-
$document = json_decode($body);
|
215 |
-
return $document;
|
216 |
-
}
|
217 |
-
|
218 |
-
return new WP_Error(
|
219 |
-
'puc-bitbucket-http-error',
|
220 |
-
'BitBucket API error. HTTP status: ' . $code
|
221 |
-
);
|
222 |
-
}
|
223 |
-
|
224 |
-
/**
|
225 |
-
* @param array $credentials
|
226 |
-
*/
|
227 |
-
public function setAuthentication($credentials) {
|
228 |
-
parent::setAuthentication($credentials);
|
229 |
-
|
230 |
-
if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
|
231 |
-
$this->oauth = new Puc_v4p1_OAuthSignature(
|
232 |
-
$credentials['consumer_key'],
|
233 |
-
$credentials['consumer_secret']
|
234 |
-
);
|
235 |
-
} else {
|
236 |
-
$this->oauth = null;
|
237 |
-
}
|
238 |
-
}
|
239 |
-
|
240 |
-
public function signDownloadUrl($url) {
|
241 |
-
//Add authentication data to download URLs. Since OAuth signatures incorporate
|
242 |
-
//timestamps, we have to do this immediately before inserting the update. Otherwise
|
243 |
-
//authentication could fail due to a stale timestamp.
|
244 |
-
if ( $this->oauth ) {
|
245 |
-
$url = $this->oauth->sign($url);
|
246 |
-
}
|
247 |
-
return $url;
|
248 |
-
}
|
249 |
-
}
|
250 |
-
|
251 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Vcs/GitHubApi.php
DELETED
@@ -1,289 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_Vcs_GitHubApi', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_Vcs_GitHubApi extends Puc_v4p1_Vcs_Api {
|
6 |
-
/**
|
7 |
-
* @var string GitHub username.
|
8 |
-
*/
|
9 |
-
protected $userName;
|
10 |
-
/**
|
11 |
-
* @var string GitHub repository name.
|
12 |
-
*/
|
13 |
-
protected $repositoryName;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var string Either a fully qualified repository URL, or just "user/repo-name".
|
17 |
-
*/
|
18 |
-
protected $repositoryUrl;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @var string GitHub authentication token. Optional.
|
22 |
-
*/
|
23 |
-
protected $accessToken;
|
24 |
-
|
25 |
-
public function __construct($repositoryUrl, $accessToken = null) {
|
26 |
-
$path = @parse_url($repositoryUrl, PHP_URL_PATH);
|
27 |
-
if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
|
28 |
-
$this->userName = $matches['username'];
|
29 |
-
$this->repositoryName = $matches['repository'];
|
30 |
-
} else {
|
31 |
-
throw new InvalidArgumentException('Invalid GitHub repository URL: "' . $repositoryUrl . '"');
|
32 |
-
}
|
33 |
-
|
34 |
-
parent::__construct($repositoryUrl, $accessToken);
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Get the latest release from GitHub.
|
39 |
-
*
|
40 |
-
* @return Puc_v4p1_Vcs_Reference|null
|
41 |
-
*/
|
42 |
-
public function getLatestRelease() {
|
43 |
-
$release = $this->api('/repos/:user/:repo/releases/latest');
|
44 |
-
if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
|
45 |
-
return null;
|
46 |
-
}
|
47 |
-
|
48 |
-
$reference = new Puc_v4p1_Vcs_Reference(array(
|
49 |
-
'name' => $release->tag_name,
|
50 |
-
'version' => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
|
51 |
-
'downloadUrl' => $this->signDownloadUrl($release->zipball_url),
|
52 |
-
'updated' => $release->created_at,
|
53 |
-
'apiResponse' => $release,
|
54 |
-
));
|
55 |
-
|
56 |
-
if ( !empty($release->body) ) {
|
57 |
-
/** @noinspection PhpUndefinedClassInspection */
|
58 |
-
$reference->changelog = Parsedown::instance()->text($release->body);
|
59 |
-
}
|
60 |
-
if ( isset($release->assets[0]) ) {
|
61 |
-
$reference->downloadCount = $release->assets[0]->download_count;
|
62 |
-
}
|
63 |
-
|
64 |
-
return $reference;
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Get the tag that looks like the highest version number.
|
69 |
-
*
|
70 |
-
* @return Puc_v4p1_Vcs_Reference|null
|
71 |
-
*/
|
72 |
-
public function getLatestTag() {
|
73 |
-
$tags = $this->api('/repos/:user/:repo/tags');
|
74 |
-
|
75 |
-
if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
|
76 |
-
return null;
|
77 |
-
}
|
78 |
-
|
79 |
-
$versionTags = $this->sortTagsByVersion($tags);
|
80 |
-
if ( empty($versionTags) ) {
|
81 |
-
return null;
|
82 |
-
}
|
83 |
-
|
84 |
-
$tag = $versionTags[0];
|
85 |
-
return new Puc_v4p1_Vcs_Reference(array(
|
86 |
-
'name' => $tag->name,
|
87 |
-
'version' => ltrim($tag->name, 'v'),
|
88 |
-
'downloadUrl' => $this->signDownloadUrl($tag->zipball_url),
|
89 |
-
'apiResponse' => $tag,
|
90 |
-
));
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Get a branch by name.
|
95 |
-
*
|
96 |
-
* @param string $branchName
|
97 |
-
* @return null|Puc_v4p1_Vcs_Reference
|
98 |
-
*/
|
99 |
-
public function getBranch($branchName) {
|
100 |
-
$branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
|
101 |
-
if ( is_wp_error($branch) || empty($branch) ) {
|
102 |
-
return null;
|
103 |
-
}
|
104 |
-
|
105 |
-
$reference = new Puc_v4p1_Vcs_Reference(array(
|
106 |
-
'name' => $branch->name,
|
107 |
-
'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
|
108 |
-
'apiResponse' => $branch,
|
109 |
-
));
|
110 |
-
|
111 |
-
if ( isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date) ) {
|
112 |
-
$reference->updated = $branch->commit->commit->author->date;
|
113 |
-
}
|
114 |
-
|
115 |
-
return $reference;
|
116 |
-
}
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Get the latest commit that changed the specified file.
|
120 |
-
*
|
121 |
-
* @param string $filename
|
122 |
-
* @param string $ref Reference name (e.g. branch or tag).
|
123 |
-
* @return StdClass|null
|
124 |
-
*/
|
125 |
-
public function getLatestCommit($filename, $ref = 'master') {
|
126 |
-
$commits = $this->api(
|
127 |
-
'/repos/:user/:repo/commits',
|
128 |
-
array(
|
129 |
-
'path' => $filename,
|
130 |
-
'sha' => $ref,
|
131 |
-
)
|
132 |
-
);
|
133 |
-
if ( !is_wp_error($commits) && is_array($commits) && isset($commits[0]) ) {
|
134 |
-
return $commits[0];
|
135 |
-
}
|
136 |
-
return null;
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Get the timestamp of the latest commit that changed the specified branch or tag.
|
141 |
-
*
|
142 |
-
* @param string $ref Reference name (e.g. branch or tag).
|
143 |
-
* @return string|null
|
144 |
-
*/
|
145 |
-
public function getLatestCommitTime($ref) {
|
146 |
-
$commits = $this->api('/repos/:user/:repo/commits', array('sha' => $ref));
|
147 |
-
if ( !is_wp_error($commits) && is_array($commits) && isset($commits[0]) ) {
|
148 |
-
return $commits[0]->commit->author->date;
|
149 |
-
}
|
150 |
-
return null;
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* Perform a GitHub API request.
|
155 |
-
*
|
156 |
-
* @param string $url
|
157 |
-
* @param array $queryParams
|
158 |
-
* @return mixed|WP_Error
|
159 |
-
*/
|
160 |
-
protected function api($url, $queryParams = array()) {
|
161 |
-
$variables = array(
|
162 |
-
'user' => $this->userName,
|
163 |
-
'repo' => $this->repositoryName,
|
164 |
-
);
|
165 |
-
foreach ($variables as $name => $value) {
|
166 |
-
$url = str_replace('/:' . $name, '/' . urlencode($value), $url);
|
167 |
-
}
|
168 |
-
$url = 'https://api.github.com' . $url;
|
169 |
-
|
170 |
-
if ( !empty($this->accessToken) ) {
|
171 |
-
$queryParams['access_token'] = $this->accessToken;
|
172 |
-
}
|
173 |
-
if ( !empty($queryParams) ) {
|
174 |
-
$url = add_query_arg($queryParams, $url);
|
175 |
-
}
|
176 |
-
|
177 |
-
$options = array('timeout' => 10);
|
178 |
-
if ( !empty($this->httpFilterName) ) {
|
179 |
-
$options = apply_filters($this->httpFilterName, $options);
|
180 |
-
}
|
181 |
-
$response = wp_remote_get($url, $options);
|
182 |
-
if ( is_wp_error($response) ) {
|
183 |
-
return $response;
|
184 |
-
}
|
185 |
-
|
186 |
-
$code = wp_remote_retrieve_response_code($response);
|
187 |
-
$body = wp_remote_retrieve_body($response);
|
188 |
-
if ( $code === 200 ) {
|
189 |
-
$document = json_decode($body);
|
190 |
-
return $document;
|
191 |
-
}
|
192 |
-
|
193 |
-
return new WP_Error(
|
194 |
-
'puc-github-http-error',
|
195 |
-
'GitHub API error. HTTP status: ' . $code
|
196 |
-
);
|
197 |
-
}
|
198 |
-
|
199 |
-
/**
|
200 |
-
* Get the contents of a file from a specific branch or tag.
|
201 |
-
*
|
202 |
-
* @param string $path File name.
|
203 |
-
* @param string $ref
|
204 |
-
* @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
|
205 |
-
*/
|
206 |
-
public function getRemoteFile($path, $ref = 'master') {
|
207 |
-
$apiUrl = '/repos/:user/:repo/contents/' . $path;
|
208 |
-
$response = $this->api($apiUrl, array('ref' => $ref));
|
209 |
-
|
210 |
-
if ( is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64') ) {
|
211 |
-
return null;
|
212 |
-
}
|
213 |
-
return base64_decode($response->content);
|
214 |
-
}
|
215 |
-
|
216 |
-
/**
|
217 |
-
* Generate a URL to download a ZIP archive of the specified branch/tag/etc.
|
218 |
-
*
|
219 |
-
* @param string $ref
|
220 |
-
* @return string
|
221 |
-
*/
|
222 |
-
public function buildArchiveDownloadUrl($ref = 'master') {
|
223 |
-
$url = sprintf(
|
224 |
-
'https://api.github.com/repos/%1$s/%2$s/zipball/%3$s',
|
225 |
-
urlencode($this->userName),
|
226 |
-
urlencode($this->repositoryName),
|
227 |
-
urlencode($ref)
|
228 |
-
);
|
229 |
-
if ( !empty($this->accessToken) ) {
|
230 |
-
$url = $this->signDownloadUrl($url);
|
231 |
-
}
|
232 |
-
return $url;
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* Get a specific tag.
|
237 |
-
*
|
238 |
-
* @param string $tagName
|
239 |
-
* @return Puc_v4p1_Vcs_Reference|null
|
240 |
-
*/
|
241 |
-
public function getTag($tagName) {
|
242 |
-
//The current GitHub update checker doesn't use getTag, so I didn't bother to implement it.
|
243 |
-
throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
|
244 |
-
}
|
245 |
-
|
246 |
-
public function setAuthentication($credentials) {
|
247 |
-
parent::setAuthentication($credentials);
|
248 |
-
$this->accessToken = is_string($credentials) ? $credentials : null;
|
249 |
-
}
|
250 |
-
|
251 |
-
/**
|
252 |
-
* Figure out which reference (i.e tag or branch) contains the latest version.
|
253 |
-
*
|
254 |
-
* @param string $configBranch Start looking in this branch.
|
255 |
-
* @return null|Puc_v4p1_Vcs_Reference
|
256 |
-
*/
|
257 |
-
public function chooseReference($configBranch) {
|
258 |
-
$updateSource = null;
|
259 |
-
|
260 |
-
if ( $configBranch === 'master' ) {
|
261 |
-
//Use the latest release.
|
262 |
-
$updateSource = $this->getLatestRelease();
|
263 |
-
if ( $updateSource === null ) {
|
264 |
-
//Failing that, use the tag with the highest version number.
|
265 |
-
$updateSource = $this->getLatestTag();
|
266 |
-
}
|
267 |
-
}
|
268 |
-
//Alternatively, just use the branch itself.
|
269 |
-
if ( empty($updateSource) ) {
|
270 |
-
$updateSource = $this->getBranch($configBranch);
|
271 |
-
}
|
272 |
-
|
273 |
-
return $updateSource;
|
274 |
-
}
|
275 |
-
|
276 |
-
/**
|
277 |
-
* @param string $url
|
278 |
-
* @return string
|
279 |
-
*/
|
280 |
-
public function signDownloadUrl($url) {
|
281 |
-
if ( empty($this->credentials) ) {
|
282 |
-
return $url;
|
283 |
-
}
|
284 |
-
return add_query_arg('access_token', $this->credentials, $url);
|
285 |
-
}
|
286 |
-
|
287 |
-
}
|
288 |
-
|
289 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Vcs/PluginUpdateChecker.php
DELETED
@@ -1,198 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Vcs_PluginUpdateChecker') ):
|
3 |
-
|
4 |
-
class Puc_v4p1_Vcs_PluginUpdateChecker extends Puc_v4p1_Plugin_UpdateChecker implements Puc_v4p1_Vcs_BaseChecker {
|
5 |
-
/**
|
6 |
-
* @var string The branch where to look for updates. Defaults to "master".
|
7 |
-
*/
|
8 |
-
protected $branch = 'master';
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var Puc_v4p1_Vcs_Api Repository API client.
|
12 |
-
*/
|
13 |
-
protected $api = null;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Puc_v4p1_Vcs_PluginUpdateChecker constructor.
|
17 |
-
*
|
18 |
-
* @param Puc_v4p1_Vcs_Api $api
|
19 |
-
* @param string $pluginFile
|
20 |
-
* @param string $slug
|
21 |
-
* @param int $checkPeriod
|
22 |
-
* @param string $optionName
|
23 |
-
* @param string $muPluginFile
|
24 |
-
*/
|
25 |
-
public function __construct($api, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
|
26 |
-
$this->api = $api;
|
27 |
-
$this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
|
28 |
-
|
29 |
-
parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
|
30 |
-
}
|
31 |
-
|
32 |
-
public function requestInfo($unusedParameter = null) {
|
33 |
-
//We have to make several remote API requests to gather all the necessary info
|
34 |
-
//which can take a while on slow networks.
|
35 |
-
set_time_limit(60);
|
36 |
-
|
37 |
-
$api = $this->api;
|
38 |
-
|
39 |
-
$info = new Puc_v4p1_Plugin_Info();
|
40 |
-
$info->filename = $this->pluginFile;
|
41 |
-
$info->slug = $this->slug;
|
42 |
-
|
43 |
-
$this->setInfoFromHeader($this->getPluginHeader(), $info);
|
44 |
-
|
45 |
-
//Pick a branch or tag.
|
46 |
-
$updateSource = $api->chooseReference($this->branch);
|
47 |
-
if ( $updateSource ) {
|
48 |
-
$ref = $updateSource->name;
|
49 |
-
$info->version = $updateSource->version;
|
50 |
-
$info->last_updated = $updateSource->updated;
|
51 |
-
$info->download_url = $updateSource->downloadUrl;
|
52 |
-
|
53 |
-
if ( !empty($updateSource->changelog) ) {
|
54 |
-
$info->sections['changelog'] = $updateSource->changelog;
|
55 |
-
}
|
56 |
-
if ( isset($updateSource->downloadCount) ) {
|
57 |
-
$info->downloaded = $updateSource->downloadCount;
|
58 |
-
}
|
59 |
-
} else {
|
60 |
-
//There's probably a network problem or an authentication error.
|
61 |
-
return null;
|
62 |
-
}
|
63 |
-
|
64 |
-
//Get headers from the main plugin file in this branch/tag. Its "Version" header and other metadata
|
65 |
-
//are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
|
66 |
-
$mainPluginFile = basename($this->pluginFile);
|
67 |
-
$remotePlugin = $api->getRemoteFile($mainPluginFile, $ref);
|
68 |
-
if ( !empty($remotePlugin) ) {
|
69 |
-
$remoteHeader = $this->getFileHeader($remotePlugin);
|
70 |
-
$this->setInfoFromHeader($remoteHeader, $info);
|
71 |
-
}
|
72 |
-
|
73 |
-
//Try parsing readme.txt. If it's formatted according to WordPress.org standards, it will contain
|
74 |
-
//a lot of useful information like the required/tested WP version, changelog, and so on.
|
75 |
-
if ( $this->readmeTxtExistsLocally() ) {
|
76 |
-
$this->setInfoFromRemoteReadme($ref, $info);
|
77 |
-
}
|
78 |
-
|
79 |
-
//The changelog might be in a separate file.
|
80 |
-
if ( empty($info->sections['changelog']) ) {
|
81 |
-
$info->sections['changelog'] = $api->getRemoteChangelog($ref, dirname($this->getAbsolutePath()));
|
82 |
-
if ( empty($info->sections['changelog']) ) {
|
83 |
-
$info->sections['changelog'] = __('There is no changelog available.', 'plugin-update-checker');
|
84 |
-
}
|
85 |
-
}
|
86 |
-
|
87 |
-
if ( empty($info->last_updated) ) {
|
88 |
-
//Fetch the latest commit that changed the tag or branch and use it as the "last_updated" date.
|
89 |
-
$latestCommitTime = $api->getLatestCommitTime($ref);
|
90 |
-
if ( $latestCommitTime !== null ) {
|
91 |
-
$info->last_updated = $latestCommitTime;
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
$info = apply_filters($this->getUniqueName('request_info_result'), $info, null);
|
96 |
-
return $info;
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Check if the currently installed version has a readme.txt file.
|
101 |
-
*
|
102 |
-
* @return bool
|
103 |
-
*/
|
104 |
-
protected function readmeTxtExistsLocally() {
|
105 |
-
$pluginDirectory = dirname($this->pluginAbsolutePath);
|
106 |
-
if ( empty($this->pluginAbsolutePath) || !is_dir($pluginDirectory) || ($pluginDirectory === '.') ) {
|
107 |
-
return false;
|
108 |
-
}
|
109 |
-
return is_file($pluginDirectory . '/readme.txt');
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Copy plugin metadata from a file header to a Plugin Info object.
|
114 |
-
*
|
115 |
-
* @param array $fileHeader
|
116 |
-
* @param Puc_v4p1_Plugin_Info $pluginInfo
|
117 |
-
*/
|
118 |
-
protected function setInfoFromHeader($fileHeader, $pluginInfo) {
|
119 |
-
$headerToPropertyMap = array(
|
120 |
-
'Version' => 'version',
|
121 |
-
'Name' => 'name',
|
122 |
-
'PluginURI' => 'homepage',
|
123 |
-
'Author' => 'author',
|
124 |
-
'AuthorName' => 'author',
|
125 |
-
'AuthorURI' => 'author_homepage',
|
126 |
-
|
127 |
-
'Requires WP' => 'requires',
|
128 |
-
'Tested WP' => 'tested',
|
129 |
-
'Requires at least' => 'requires',
|
130 |
-
'Tested up to' => 'tested',
|
131 |
-
);
|
132 |
-
foreach ($headerToPropertyMap as $headerName => $property) {
|
133 |
-
if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
|
134 |
-
$pluginInfo->$property = $fileHeader[$headerName];
|
135 |
-
}
|
136 |
-
}
|
137 |
-
|
138 |
-
if ( !empty($fileHeader['Description']) ) {
|
139 |
-
$pluginInfo->sections['description'] = $fileHeader['Description'];
|
140 |
-
}
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Copy plugin metadata from the remote readme.txt file.
|
145 |
-
*
|
146 |
-
* @param string $ref GitHub tag or branch where to look for the readme.
|
147 |
-
* @param Puc_v4p1_Plugin_Info $pluginInfo
|
148 |
-
*/
|
149 |
-
protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
|
150 |
-
$readme = $this->api->getRemoteReadme($ref);
|
151 |
-
if ( empty($readme) ) {
|
152 |
-
return;
|
153 |
-
}
|
154 |
-
|
155 |
-
if ( isset($readme['sections']) ) {
|
156 |
-
$pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
|
157 |
-
}
|
158 |
-
if ( !empty($readme['tested_up_to']) ) {
|
159 |
-
$pluginInfo->tested = $readme['tested_up_to'];
|
160 |
-
}
|
161 |
-
if ( !empty($readme['requires_at_least']) ) {
|
162 |
-
$pluginInfo->requires = $readme['requires_at_least'];
|
163 |
-
}
|
164 |
-
|
165 |
-
if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
|
166 |
-
$pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
|
167 |
-
}
|
168 |
-
}
|
169 |
-
|
170 |
-
public function setBranch($branch) {
|
171 |
-
$this->branch = $branch;
|
172 |
-
return $this;
|
173 |
-
}
|
174 |
-
|
175 |
-
public function setAuthentication($credentials) {
|
176 |
-
$this->api->setAuthentication($credentials);
|
177 |
-
return $this;
|
178 |
-
}
|
179 |
-
|
180 |
-
public function getUpdate() {
|
181 |
-
$update = parent::getUpdate();
|
182 |
-
|
183 |
-
if ( isset($update) && !empty($update->download_url) ) {
|
184 |
-
$update->download_url = $this->api->signDownloadUrl($update->download_url);
|
185 |
-
}
|
186 |
-
|
187 |
-
return $update;
|
188 |
-
}
|
189 |
-
|
190 |
-
public function onDisplayConfiguration($panel) {
|
191 |
-
parent::onDisplayConfiguration($panel);
|
192 |
-
$panel->row('Branch', $this->branch);
|
193 |
-
$panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
|
194 |
-
$panel->row('API client', get_class($this->api));
|
195 |
-
}
|
196 |
-
}
|
197 |
-
|
198 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Vcs/Reference.php
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4p1_Vcs_Reference', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* This class represents a VCS branch or tag. It's intended as a read only, short-lived container
|
6 |
-
* that only exists to provide a limited degree of type checking.
|
7 |
-
*
|
8 |
-
* @property string $name
|
9 |
-
* @property string|null version
|
10 |
-
* @property string $downloadUrl
|
11 |
-
* @property string $updated
|
12 |
-
*
|
13 |
-
* @property string|null $changelog
|
14 |
-
* @property int|null $downloadCount
|
15 |
-
*/
|
16 |
-
class Puc_v4p1_Vcs_Reference {
|
17 |
-
private $properties = array();
|
18 |
-
|
19 |
-
public function __construct($properties = array()) {
|
20 |
-
$this->properties = $properties;
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @param string $name
|
25 |
-
* @return mixed|null
|
26 |
-
*/
|
27 |
-
function __get($name) {
|
28 |
-
return array_key_exists($name, $this->properties) ? $this->properties[$name] : null;
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @param string $name
|
33 |
-
* @param mixed $value
|
34 |
-
*/
|
35 |
-
function __set($name, $value) {
|
36 |
-
$this->properties[$name] = $value;
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* @param string $name
|
41 |
-
* @return bool
|
42 |
-
*/
|
43 |
-
function __isset($name) {
|
44 |
-
return isset($this->properties[$name]);
|
45 |
-
}
|
46 |
-
|
47 |
-
}
|
48 |
-
|
49 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/Puc/v4p1/Vcs/ThemeUpdateChecker.php
DELETED
@@ -1,101 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4p1_Vcs_ThemeUpdateChecker', false) ):
|
4 |
-
|
5 |
-
class Puc_v4p1_Vcs_ThemeUpdateChecker extends Puc_v4p1_Theme_UpdateChecker implements Puc_v4p1_Vcs_BaseChecker {
|
6 |
-
/**
|
7 |
-
* @var string The branch where to look for updates. Defaults to "master".
|
8 |
-
*/
|
9 |
-
protected $branch = 'master';
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @var Puc_v4p1_Vcs_Api Repository API client.
|
13 |
-
*/
|
14 |
-
protected $api = null;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Puc_v4p1_Vcs_ThemeUpdateChecker constructor.
|
18 |
-
*
|
19 |
-
* @param Puc_v4p1_Vcs_Api $api
|
20 |
-
* @param null $stylesheet
|
21 |
-
* @param null $customSlug
|
22 |
-
* @param int $checkPeriod
|
23 |
-
* @param string $optionName
|
24 |
-
*/
|
25 |
-
public function __construct($api, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') {
|
26 |
-
$this->api = $api;
|
27 |
-
$this->api->setHttpFilterName($this->getUniqueName('request_update_options'));
|
28 |
-
|
29 |
-
parent::__construct($api->getRepositoryUrl(), $stylesheet, $customSlug, $checkPeriod, $optionName);
|
30 |
-
}
|
31 |
-
|
32 |
-
public function requestUpdate() {
|
33 |
-
$api = $this->api;
|
34 |
-
|
35 |
-
$update = new Puc_v4p1_Theme_Update();
|
36 |
-
$update->slug = $this->slug;
|
37 |
-
|
38 |
-
//Figure out which reference (tag or branch) we'll use to get the latest version of the theme.
|
39 |
-
$updateSource = $api->chooseReference($this->branch);
|
40 |
-
if ( $updateSource ) {
|
41 |
-
$ref = $updateSource->name;
|
42 |
-
$update->download_url = $updateSource->downloadUrl;
|
43 |
-
} else {
|
44 |
-
$ref = $this->branch;
|
45 |
-
}
|
46 |
-
|
47 |
-
//Get headers from the main stylesheet in this branch/tag. Its "Version" header and other metadata
|
48 |
-
//are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
|
49 |
-
$remoteHeader = $this->getFileHeader($api->getRemoteFile('style.css', $ref));
|
50 |
-
$update->version = Puc_v4p1_Utils::findNotEmpty(array(
|
51 |
-
$remoteHeader['Version'],
|
52 |
-
Puc_v4p1_Utils::get($updateSource, 'version'),
|
53 |
-
));
|
54 |
-
|
55 |
-
//The details URL defaults to the Theme URI header or the repository URL.
|
56 |
-
$update->details_url = Puc_v4p1_Utils::findNotEmpty(array(
|
57 |
-
$remoteHeader['ThemeURI'],
|
58 |
-
$this->theme->get('ThemeURI'),
|
59 |
-
$this->metadataUrl,
|
60 |
-
));
|
61 |
-
|
62 |
-
if ( empty($update->version) ) {
|
63 |
-
//It looks like we didn't find a valid update after all.
|
64 |
-
$update = null;
|
65 |
-
}
|
66 |
-
|
67 |
-
$update = $this->filterUpdateResult($update);
|
68 |
-
return $update;
|
69 |
-
}
|
70 |
-
|
71 |
-
//FIXME: This is duplicated code. Both theme and plugin subclasses that use VCS share these methods.
|
72 |
-
|
73 |
-
public function setBranch($branch) {
|
74 |
-
$this->branch = $branch;
|
75 |
-
return $this;
|
76 |
-
}
|
77 |
-
|
78 |
-
public function setAuthentication($credentials) {
|
79 |
-
$this->api->setAuthentication($credentials);
|
80 |
-
return $this;
|
81 |
-
}
|
82 |
-
|
83 |
-
public function getUpdate() {
|
84 |
-
$update = parent::getUpdate();
|
85 |
-
|
86 |
-
if ( isset($update) && !empty($update->download_url) ) {
|
87 |
-
$update->download_url = $this->api->signDownloadUrl($update->download_url);
|
88 |
-
}
|
89 |
-
|
90 |
-
return $update;
|
91 |
-
}
|
92 |
-
|
93 |
-
public function onDisplayConfiguration($panel) {
|
94 |
-
parent::onDisplayConfiguration($panel);
|
95 |
-
$panel->row('Branch', $this->branch);
|
96 |
-
$panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
|
97 |
-
$panel->row('API client', get_class($this->api));
|
98 |
-
}
|
99 |
-
}
|
100 |
-
|
101 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/plugin-update-checker/plugin-update-checker.php
DELETED
@@ -1,22 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Plugin Update Checker Library 4.1
|
4 |
-
* http://w-shadow.com/
|
5 |
-
*
|
6 |
-
* Copyright 2017 Janis Elsts
|
7 |
-
* Released under the MIT license. See license.txt for details.
|
8 |
-
*/
|
9 |
-
|
10 |
-
require dirname(__FILE__) . '/Puc/v4/Factory.php';
|
11 |
-
require dirname(__FILE__) . '/Puc/v4p1/Autoloader.php';
|
12 |
-
new Puc_v4p1_Autoloader();
|
13 |
-
|
14 |
-
//Register classes defined in this file with the factory.
|
15 |
-
Puc_v4_Factory::addVersion('Plugin_UpdateChecker', 'Puc_v4p1_Plugin_UpdateChecker', '4.1');
|
16 |
-
Puc_v4_Factory::addVersion('Theme_UpdateChecker', 'Puc_v4p1_Theme_UpdateChecker', '4.1');
|
17 |
-
|
18 |
-
Puc_v4_Factory::addVersion('Vcs_PluginUpdateChecker', 'Puc_v4p1_Vcs_PluginUpdateChecker', '4.1');
|
19 |
-
Puc_v4_Factory::addVersion('Vcs_ThemeUpdateChecker', 'Puc_v4p1_Vcs_ThemeUpdateChecker', '4.1');
|
20 |
-
|
21 |
-
Puc_v4_Factory::addVersion('GitHubApi', 'Puc_v4p1_Vcs_GitHubApi', '4.1');
|
22 |
-
Puc_v4_Factory::addVersion('BitBucketApi', 'Puc_v4p1_Vcs_BitBucketApi', '4.1');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/stopwords-json/README.md
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
# stopwords-json [![Build Status](https://travis-ci.org/6/stopwords-json.svg?branch=travis)](https://travis-ci.org/6/stopwords-json) [![npm](https://img.shields.io/npm/v/stopwords-json.svg?maxAge=3600)](https://www.npmjs.com/package/stopwords-json) [![Bower](https://img.shields.io/bower/v/stopwords-json.svg?maxAge=3600)](https://bower.io/)
|
2 |
-
|
3 |
-
Stopwords for various languages in JSON format. Per [Wikipedia](http://en.wikipedia.org/wiki/Stop_words):
|
4 |
-
|
5 |
-
> Stop words are words which are filtered out prior to, or after, processing of natural language data [...] these are some of the most common, short function words, such as *the*, *is*, *at*, *which*, and *on*.
|
6 |
-
|
7 |
-
You can use all stopwords with [stopwords-all.json](stopwords-all.json) (keyed by language ISO 639-1 code), or see the below table for individual language stopword files.
|
8 |
-
|
9 |
-
## Languages
|
10 |
-
There are a total of 50 supported languages:
|
11 |
-
|
12 |
-
Language | Stopword count | Filename
|
13 |
-
--- | --- | ---
|
14 |
-
Afrikaans | 51 | [af.json](dist/af.json)
|
15 |
-
Arabic | 162 | [ar.json](dist/ar.json)
|
16 |
-
Armenian | 45 | [hy.json](dist/hy.json)
|
17 |
-
Basque | 98 | [eu.json](dist/eu.json)
|
18 |
-
Bengali | 116 | [bn.json](dist/bn.json)
|
19 |
-
Breton | 126 | [br.json](dist/br.json)
|
20 |
-
Bulgarian | 259 | [bg.json](dist/bg.json)
|
21 |
-
Catalan | 218 | [ca.json](dist/ca.json)
|
22 |
-
Chinese | 542 | [zh.json](dist/zh.json)
|
23 |
-
Croatian | 179 | [hr.json](dist/hr.json)
|
24 |
-
Czech | 346 | [cs.json](dist/cs.json)
|
25 |
-
Danish | 101 | [da.json](dist/da.json)
|
26 |
-
Dutch | 275 | [nl.json](dist/nl.json)
|
27 |
-
English | 570 | [en.json](dist/en.json)
|
28 |
-
Esperanto | 173 | [eo.json](dist/eo.json)
|
29 |
-
Estonian | 35 | [et.json](dist/et.json)
|
30 |
-
Finnish | 772 | [fi.json](dist/fi.json)
|
31 |
-
French | 606 | [fr.json](dist/fr.json)
|
32 |
-
Galician | 160 | [gl.json](dist/gl.json)
|
33 |
-
German | 596 | [de.json](dist/de.json)
|
34 |
-
Greek | 75 | [el.json](dist/el.json)
|
35 |
-
Hausa | 39 | [ha.json](dist/ha.json)
|
36 |
-
Hebrew | 194 | [he.json](dist/he.json)
|
37 |
-
Hindi | 225 | [hi.json](dist/hi.json)
|
38 |
-
Hungarian | 781 | [hu.json](dist/hu.json)
|
39 |
-
Indonesian | 355 | [id.json](dist/id.json)
|
40 |
-
Irish | 109 | [ga.json](dist/ga.json)
|
41 |
-
Italian | 619 | [it.json](dist/it.json)
|
42 |
-
Japanese | 109 | [ja.json](dist/ja.json)
|
43 |
-
Korean | 679 | [ko.json](dist/ko.json)
|
44 |
-
Latin | 49 | [la.json](dist/la.json)
|
45 |
-
Latvian | 161 | [lv.json](dist/lv.json)
|
46 |
-
Marathi | 99 | [mr.json](dist/mr.json)
|
47 |
-
Norwegian | 172 | [no.json](dist/no.json)
|
48 |
-
Persian | 332 | [fa.json](dist/fa.json)
|
49 |
-
Polish | 260 | [pl.json](dist/pl.json)
|
50 |
-
Portuguese | 408 | [pt.json](dist/pt.json)
|
51 |
-
Romanian | 282 | [ro.json](dist/ro.json)
|
52 |
-
Russian | 539 | [ru.json](dist/ru.json)
|
53 |
-
Slovak | 110 | [sk.json](dist/sk.json)
|
54 |
-
Slovenian | 446 | [sl.json](dist/sl.json)
|
55 |
-
Somalia | 30 | [so.json](dist/so.json)
|
56 |
-
Southern Sotho | 31 | [st.json](dist/st.json)
|
57 |
-
Spanish | 577 | [es.json](dist/es.json)
|
58 |
-
Swahili | 74 | [sw.json](dist/sw.json)
|
59 |
-
Swedish | 401 | [sv.json](dist/sv.json)
|
60 |
-
Thai | 115 | [th.json](dist/th.json)
|
61 |
-
Turkish | 279 | [tr.json](dist/tr.json)
|
62 |
-
Yoruba | 60 | [yo.json](dist/yo.json)
|
63 |
-
Zulu | 29 | [zu.json](dist/zu.json)
|
64 |
-
|
65 |
-
|
66 |
-
## Sources
|
67 |
-
|
68 |
-
- [Apache Lucene](http://lucene.apache.org/) - [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0)
|
69 |
-
- [Carrot2](https://github.com/carrot2/carrot2) - [License](http://project.carrot2.org/license.html)
|
70 |
-
- [cue.language](https://github.com/vcl/cue.language) - [Apache 2.0 License](https://github.com/vcl/cue.language/blob/master/license.txt)
|
71 |
-
- [Jacques Savoy](http://members.unine.ch/jacques.savoy/clef/index.html) - BSD License
|
72 |
-
- SMART Information Retrieval System: ftp://ftp.cs.cornell.edu/pub/smart/
|
73 |
-
- [ASP Stoplist Project](https://github.com/dohliam/more-stoplists) - CC-BY and Apache 2.0
|
74 |
-
|
75 |
-
## License and Copyright
|
76 |
-
Copyright (c) 2017 Peter Graham, contributors.
|
77 |
-
Released under the Apache-2.0 license.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/ext/stopwords-json/dist/af.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["'n","aan","af","al","as","baie","by","daar","dag","dat","die","dit","een","ek","en","gaan","gesê","haar","het","hom","hulle","hy","in","is","jou","jy","kan","kom","ma","maar","met","my","na","nie","om","ons","op","saam","sal","se","sien","so","sy","te","toe","uit","van","vir","was","wat","ʼn"]
|
|
includes/ext/stopwords-json/dist/ar.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["،","أ","ا","اثر","اجل","احد","اخرى","اذا","اربعة","اطار","اعادة","اعلنت","اف","اكثر","اكد","الا","الاخيرة","الان","الاول","الاولى","التى","التي","الثاني","الثانية","الذاتي","الذى","الذي","الذين","السابق","الف","الماضي","المقبل","الوقت","الى","اليوم","اما","امام","امس","ان","انه","انها","او","اول","اي","ايار","ايام","ايضا","ب","باسم","بان","برس","بسبب","بشكل","بعد","بعض","بن","به","بها","بين","تم","ثلاثة","ثم","جميع","حاليا","حتى","حوالى","حول","حيث","حين","خلال","دون","ذلك","زيارة","سنة","سنوات","شخصا","صباح","صفر","ضد","ضمن","عام","عاما","عدة","عدد","عدم","عشر","عشرة","على","عليه","عليها","عن","عند","عندما","غدا","غير","ـ","ف","فان","فى","في","فيه","فيها","قال","قبل","قد","قوة","كان","كانت","كل","كلم","كما","لا","لدى","لقاء","لكن","للامم","لم","لن","له","لها","لوكالة","ما","مايو","مساء","مع","مقابل","مليار","مليون","من","منذ","منها","نحو","نفسه","نهاية","هذا","هذه","هناك","هو","هي","و","و6","واحد","واضاف","واضافت","واكد","وان","واوضح","وفي","وقال","وقالت","وقد","وقف","وكان","وكانت","ولا","ولم","ومن","وهو","وهي","يكون","يمكن","يوم"]
|
|
includes/ext/stopwords-json/dist/bg.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["а","автентичен","аз","ако","ала","бе","без","беше","би","бивш","бивша","бившо","бил","била","били","било","благодаря","близо","бъдат","бъде","бяха","в","вас","ваш","ваша","вероятно","вече","взема","ви","вие","винаги","внимава","време","все","всеки","всички","всичко","всяка","във","въпреки","върху","г","ги","главен","главна","главно","глас","го","година","години","годишен","д","да","дали","два","двама","двамата","две","двете","ден","днес","дни","до","добра","добре","добро","добър","докато","докога","дори","досега","доста","друг","друга","други","е","евтин","едва","един","една","еднаква","еднакви","еднакъв","едно","екип","ето","живот","за","забавям","зад","заедно","заради","засега","заспал","затова","защо","защото","и","из","или","им","има","имат","иска","й","каза","как","каква","какво","както","какъв","като","кога","когато","което","които","кой","който","колко","която","къде","където","към","лесен","лесно","ли","лош","м","май","малко","ме","между","мек","мен","месец","ми","много","мнозина","мога","могат","може","мокър","моля","момента","му","н","на","над","назад","най","направи","напред","например","нас","не","него","нещо","нея","ни","ние","никой","нито","нищо","но","нов","нова","нови","новина","някои","някой","няколко","няма","обаче","около","освен","особено","от","отгоре","отново","още","пак","по","повече","повечето","под","поне","поради","после","почти","прави","пред","преди","през","при","пък","първата","първи","първо","пъти","равен","равна","с","са","сам","само","се","сега","си","син","скоро","след","следващ","сме","смях","според","сред","срещу","сте","съм","със","също","т","т.н.","тази","така","такива","такъв","там","твой","те","тези","ти","то","това","тогава","този","той","толкова","точно","три","трябва","тук","тъй","тя","тях","у","утре","харесва","хиляди","ч","часа","че","често","чрез","ще","щом","юмрук","я","як"]
|
|
includes/ext/stopwords-json/dist/bn.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["অনেক","অন্য","অবশ্য","আগে","আছে","আজ","আবার","আমরা","আমাদের","আর","ই","উত্তর","উপর","উপরে","এ","এই","এক্","এখন","এত","এব","এমন","এমনি","এর","এস","এসে","ও","ওই","কমনে","করা","করে","কাছে","কাজ","কাজে","কারণ","কি","কিছু","কে","কেউ","কেখা","কেন","কোটি","কোনো","কয়েক","খুব","গিয়ে","গেল","চার","চালু","চেষ্টা","ছিল","জানা","জ্নজন","টি","তখন","তবে","তা","তাই","তো","থাকা","থেকে","দিন","দু","দুই","দেওয়া","ধামার","নতুন","না","নাগাদ","নিয়ে","নেওয়া","নয়","পর","পরে","পাচ","পি","পেয়্র্","প্রতি","প্রথম","প্রযন্ত","প্রাথমিক","প্রায়","বক্তব্য","বন","বলা","বলে","বলেন","বহু","বা","বি","বিভিন্ন","বেশ","বেশি","মতো","মধ্যে","মনে","যখন","যদি","যা","যাওয়া","যে","র","রকম","লক্ষ","শুধু","শুরু","সঙ্গে","সব","সহ","সাধারণ","সামনে","সি","সে","সেই","হতে","হাজার","হয়"]
|
|
includes/ext/stopwords-json/dist/br.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","ainda","alem","ambas","ambos","antes","ao","aonde","aos","apos","aquele","aqueles","as","assim","com","como","contra","contudo","cuja","cujas","cujo","cujos","da","das","de","dela","dele","deles","demais","depois","desde","desta","deste","dispoe","dispoem","diversa","diversas","diversos","do","dos","durante","e","ela","elas","ele","eles","em","entao","entre","essa","essas","esse","esses","esta","estas","este","estes","ha","isso","isto","logo","mais","mas","mediante","menos","mesma","mesmas","mesmo","mesmos","na","nao","nas","nem","nesse","neste","nos","o","os","ou","outra","outras","outro","outros","pelas","pelo","pelos","perante","pois","por","porque","portanto","propios","proprio","quais","qual","qualquer","quando","quanto","que","quem","quer","se","seja","sem","sendo","seu","seus","sob","sobre","sua","suas","tal","tambem","teu","teus","toda","todas","todo","todos","tua","tuas","tudo","um","uma","umas","uns"]
|
|
includes/ext/stopwords-json/dist/ca.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","abans","ací","ah","així","això","al","aleshores","algun","alguna","algunes","alguns","alhora","allà","allí","allò","als","altra","altre","altres","amb","ambdues","ambdós","apa","aquell","aquella","aquelles","aquells","aquest","aquesta","aquestes","aquests","aquí","baix","cada","cadascuna","cadascunes","cadascuns","cadascú","com","contra","d'un","d'una","d'unes","d'uns","dalt","de","del","dels","des","després","dins","dintre","donat","doncs","durant","e","eh","el","els","em","en","encara","ens","entre","eren","es","esta","estaven","esteu","està","estàvem","estàveu","et","etc","ets","fins","fora","gairebé","ha","han","has","havia","he","hem","heu","hi","ho","i","igual","iguals","ja","l'hi","la","les","li","li'n","llavors","m'he","ma","mal","malgrat","mateix","mateixa","mateixes","mateixos","me","mentre","meu","meus","meva","meves","molt","molta","moltes","molts","mon","mons","més","n'he","n'hi","ne","ni","no","nogensmenys","només","nosaltres","nostra","nostre","nostres","o","oh","oi","on","pas","pel","pels","per","perquè","però","poc","poca","pocs","poques","potser","propi","qual","quals","quan","quant","que","quelcom","qui","quin","quina","quines","quins","què","s'ha","s'han","sa","semblant","semblants","ses","seu","seus","seva","seves","si","sobre","sobretot","solament","sols","son","sons","sota","sou","sóc","són","t'ha","t'han","t'he","ta","tal","també","tampoc","tan","tant","tanta","tantes","teu","teus","teva","teves","ton","tons","tot","tota","totes","tots","un","una","unes","uns","us","va","vaig","vam","van","vas","veu","vosaltres","vostra","vostre","vostres","érem","éreu","és"]
|
|
includes/ext/stopwords-json/dist/cs.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","aby","ahoj","aj","ale","anebo","ani","ano","asi","aspoň","atd","atp","ačkoli","až","bez","beze","blízko","bohužel","brzo","bude","budem","budeme","budete","budeš","budou","budu","by","byl","byla","byli","bylo","byly","bys","být","během","chce","chceme","chcete","chceš","chci","chtít","chtějí","chut'","chuti","co","což","cz","daleko","další","den","deset","devatenáct","devět","dnes","do","dobrý","docela","dva","dvacet","dvanáct","dvě","dál","dále","děkovat","děkujeme","děkuji","ho","hodně","i","jak","jakmile","jako","jakož","jde","je","jeden","jedenáct","jedna","jedno","jednou","jedou","jeho","jehož","jej","jejich","její","jelikož","jemu","jen","jenom","jestli","jestliže","ještě","jež","ji","jich","jimi","jinak","jiné","již","jsem","jseš","jsi","jsme","jsou","jste","já","jí","jím","jíž","k","kam","kde","kdo","kdy","když","ke","kolik","kromě","kterou","která","které","který","kteří","kvůli","mají","mezi","mi","mne","mnou","mně","moc","mohl","mohou","moje","moji","možná","musí","my","má","málo","mám","máme","máte","máš","mé","mí","mít","mě","můj","může","na","nad","nade","napište","naproti","načež","naše","naši","ne","nebo","nebyl","nebyla","nebyli","nebyly","nedělají","nedělá","nedělám","neděláme","neděláte","neděláš","neg","nejsi","nejsou","nemají","nemáme","nemáte","neměl","není","nestačí","nevadí","než","nic","nich","nimi","nové","nový","nula","nám","námi","nás","náš","ním","ně","něco","nějak","někde","někdo","němu","němuž","o","od","ode","on","ona","oni","ono","ony","osm","osmnáct","pak","patnáct","po","pod","podle","pokud","potom","pouze","pozdě","pořád","pravé","pro","prostě","prosím","proti","proto","protože","proč","první","pta","pět","před","přes","přese","při","přičemž","re","rovně","s","se","sedm","sedmnáct","si","skoro","smí","smějí","snad","spolu","sta","sto","strana","sté","své","svých","svým","svými","ta","tady","tak","takhle","taky","také","takže","tam","tamhle","tamhleto","tamto","tato","tebe","tebou","ted'","tedy","ten","tento","teto","ti","tipy","tisíc","tisíce","to","tobě","tohle","toho","tohoto","tom","tomto","tomu","tomuto","toto","trošku","tu","tuto","tvoje","tvá","tvé","tvůj","ty","tyto","téma","tím","tímto","tě","těm","těmu","třeba","tři","třináct","u","určitě","už","v","vaše","vaši","ve","vedle","večer","vlastně","vy","vám","vámi","vás","váš","více","však","všechno","všichni","vůbec","vždy","z","za","zatímco","zač","zda","zde","ze","zprávy","zpět","čau","či","článku","články","čtrnáct","čtyři","šest","šestnáct","že"]
|
|
includes/ext/stopwords-json/dist/da.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["af","alle","andet","andre","at","begge","da","de","den","denne","der","deres","det","dette","dig","din","dog","du","ej","eller","en","end","ene","eneste","enhver","et","fem","fire","flere","fleste","for","fordi","forrige","fra","få","før","god","han","hans","har","hendes","her","hun","hvad","hvem","hver","hvilken","hvis","hvor","hvordan","hvorfor","hvornår","i","ikke","ind","ingen","intet","jeg","jeres","kan","kom","kommer","lav","lidt","lille","man","mand","mange","med","meget","men","mens","mere","mig","ned","ni","nogen","noget","ny","nyt","nær","næste","næsten","og","op","otte","over","på","se","seks","ses","som","stor","store","syv","ti","til","to","tre","ud","var"]
|
|
includes/ext/stopwords-json/dist/de.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["Ernst","Ordnung","Schluss","a","ab","aber","ach","acht","achte","achten","achter","achtes","ag","alle","allein","allem","allen","aller","allerdings","alles","allgemeinen","als","also","am","an","andere","anderen","andern","anders","au","auch","auf","aus","ausser","ausserdem","außer","außerdem","b","bald","bei","beide","beiden","beim","beispiel","bekannt","bereits","besonders","besser","besten","bin","bis","bisher","bist","c","d","d.h","da","dabei","dadurch","dafür","dagegen","daher","dahin","dahinter","damals","damit","danach","daneben","dank","dann","daran","darauf","daraus","darf","darfst","darin","darum","darunter","darüber","das","dasein","daselbst","dass","dasselbe","davon","davor","dazu","dazwischen","daß","dein","deine","deinem","deiner","dem","dementsprechend","demgegenüber","demgemäss","demgemäß","demselben","demzufolge","den","denen","denn","denselben","der","deren","derjenige","derjenigen","dermassen","dermaßen","derselbe","derselben","des","deshalb","desselben","dessen","deswegen","dich","die","diejenige","diejenigen","dies","diese","dieselbe","dieselben","diesem","diesen","dieser","dieses","dir","doch","dort","drei","drin","dritte","dritten","dritter","drittes","du","durch","durchaus","durfte","durften","dürfen","dürft","e","eben","ebenso","ehrlich","ei","ei,","eigen","eigene","eigenen","eigener","eigenes","ein","einander","eine","einem","einen","einer","eines","einige","einigen","einiger","einiges","einmal","eins","elf","en","ende","endlich","entweder","er","erst","erste","ersten","erster","erstes","es","etwa","etwas","euch","euer","eure","f","folgende","früher","fünf","fünfte","fünften","fünfter","fünftes","für","g","gab","ganz","ganze","ganzen","ganzer","ganzes","gar","gedurft","gegen","gegenüber","gehabt","gehen","geht","gekannt","gekonnt","gemacht","gemocht","gemusst","genug","gerade","gern","gesagt","geschweige","gewesen","gewollt","geworden","gibt","ging","gleich","gott","gross","grosse","grossen","grosser","grosses","groß","große","großen","großer","großes","gut","gute","guter","gutes","h","habe","haben","habt","hast","hat","hatte","hatten","hattest","hattet","heisst","her","heute","hier","hin","hinter","hoch","hätte","hätten","i","ich","ihm","ihn","ihnen","ihr","ihre","ihrem","ihren","ihrer","ihres","im","immer","in","indem","infolgedessen","ins","irgend","ist","j","ja","jahr","jahre","jahren","je","jede","jedem","jeden","jeder","jedermann","jedermanns","jedes","jedoch","jemand","jemandem","jemanden","jene","jenem","jenen","jener","jenes","jetzt","k","kam","kann","kannst","kaum","kein","keine","keinem","keinen","keiner","kleine","kleinen","kleiner","kleines","kommen","kommt","konnte","konnten","kurz","können","könnt","könnte","l","lang","lange","leicht","leide","lieber","los","m","machen","macht","machte","mag","magst","mahn","mal","man","manche","manchem","manchen","mancher","manches","mann","mehr","mein","meine","meinem","meinen","meiner","meines","mensch","menschen","mich","mir","mit","mittel","mochte","mochten","morgen","muss","musst","musste","mussten","muß","mußt","möchte","mögen","möglich","mögt","müssen","müsst","müßt","n","na","nach","nachdem","nahm","natürlich","neben","nein","neue","neuen","neun","neunte","neunten","neunter","neuntes","nicht","nichts","nie","niemand","niemandem","niemanden","noch","nun","nur","o","ob","oben","oder","offen","oft","ohne","p","q","r","recht","rechte","rechten","rechter","rechtes","richtig","rund","s","sa","sache","sagt","sagte","sah","satt","schlecht","schon","sechs","sechste","sechsten","sechster","sechstes","sehr","sei","seid","seien","sein","seine","seinem","seinen","seiner","seines","seit","seitdem","selbst","sich","sie","sieben","siebente","siebenten","siebenter","siebentes","sind","so","solang","solche","solchem","solchen","solcher","solches","soll","sollen","sollst","sollt","sollte","sollten","sondern","sonst","soweit","sowie","später","startseite","statt","steht","suche","t","tag","tage","tagen","tat","teil","tel","tritt","trotzdem","tun","u","uhr","um","und","und?","uns","unser","unsere","unserer","unter","v","vergangenen","viel","viele","vielem","vielen","vielleicht","vier","vierte","vierten","vierter","viertes","vom","von","vor","w","wahr?","wann","war","waren","wart","warum","was","wegen","weil","weit","weiter","weitere","weiteren","weiteres","welche","welchem","welchen","welcher","welches","wem","wen","wenig","wenige","weniger","weniges","wenigstens","wenn","wer","werde","werden","werdet","weshalb","wessen","wie","wieder","wieso","will","willst","wir","wird","wirklich","wirst","wissen","wo","wohl","wollen","wollt","wollte","wollten","worden","wurde","wurden","während","währenddem","währenddessen","wäre","würde","würden","x","y","z","z.b","zehn","zehnte","zehnten","zehnter","zehntes","zeit","zu","zuerst","zugleich","zum","zunächst","zur","zurück","zusammen","zwanzig","zwar","zwei","zweite","zweiten","zweiter","zweites","zwischen","zwölf","über","überhaupt","übrigens"]
|
|
includes/ext/stopwords-json/dist/el.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["αλλα","αν","αντι","απο","αυτα","αυτεσ","αυτη","αυτο","αυτοι","αυτοσ","αυτουσ","αυτων","για","δε","δεν","εαν","ειμαι","ειμαστε","ειναι","εισαι","ειστε","εκεινα","εκεινεσ","εκεινη","εκεινο","εκεινοι","εκεινοσ","εκεινουσ","εκεινων","ενω","επι","η","θα","ισωσ","κ","και","κατα","κι","μα","με","μετα","μη","μην","να","ο","οι","ομωσ","οπωσ","οσο","οτι","παρα","ποια","ποιεσ","ποιο","ποιοι","ποιοσ","ποιουσ","ποιων","που","προσ","πωσ","σε","στη","στην","στο","στον","τα","την","τησ","το","τον","τοτε","του","των","ωσ"]
|
|
includes/ext/stopwords-json/dist/en.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","a's","able","about","above","according","accordingly","across","actually","after","afterwards","again","against","ain't","all","allow","allows","almost","alone","along","already","also","although","always","am","among","amongst","an","and","another","any","anybody","anyhow","anyone","anything","anyway","anyways","anywhere","apart","appear","appreciate","appropriate","are","aren't","around","as","aside","ask","asking","associated","at","available","away","awfully","b","be","became","because","become","becomes","becoming","been","before","beforehand","behind","being","believe","below","beside","besides","best","better","between","beyond","both","brief","but","by","c","c'mon","c's","came","can","can't","cannot","cant","cause","causes","certain","certainly","changes","clearly","co","com","come","comes","concerning","consequently","consider","considering","contain","containing","contains","corresponding","could","couldn't","course","currently","d","definitely","described","despite","did","didn't","different","do","does","doesn't","doing","don't","done","down","downwards","during","e","each","edu","eg","eight","either","else","elsewhere","enough","entirely","especially","et","etc","even","ever","every","everybody","everyone","everything","everywhere","ex","exactly","example","except","f","far","few","fifth","first","five","followed","following","follows","for","former","formerly","forth","four","from","further","furthermore","g","get","gets","getting","given","gives","go","goes","going","gone","got","gotten","greetings","h","had","hadn't","happens","hardly","has","hasn't","have","haven't","having","he","he's","hello","help","hence","her","here","here's","hereafter","hereby","herein","hereupon","hers","herself","hi","him","himself","his","hither","hopefully","how","howbeit","however","i","i'd","i'll","i'm","i've","ie","if","ignored","immediate","in","inasmuch","inc","indeed","indicate","indicated","indicates","inner","insofar","instead","into","inward","is","isn't","it","it'd","it'll","it's","its","itself","j","just","k","keep","keeps","kept","know","known","knows","l","last","lately","later","latter","latterly","least","less","lest","let","let's","like","liked","likely","little","look","looking","looks","ltd","m","mainly","many","may","maybe","me","mean","meanwhile","merely","might","more","moreover","most","mostly","much","must","my","myself","n","name","namely","nd","near","nearly","necessary","need","needs","neither","never","nevertheless","new","next","nine","no","nobody","non","none","noone","nor","normally","not","nothing","novel","now","nowhere","o","obviously","of","off","often","oh","ok","okay","old","on","once","one","ones","only","onto","or","other","others","otherwise","ought","our","ours","ourselves","out","outside","over","overall","own","p","particular","particularly","per","perhaps","placed","please","plus","possible","presumably","probably","provides","q","que","quite","qv","r","rather","rd","re","really","reasonably","regarding","regardless","regards","relatively","respectively","right","s","said","same","saw","say","saying","says","second","secondly","see","seeing","seem","seemed","seeming","seems","seen","self","selves","sensible","sent","serious","seriously","seven","several","shall","she","should","shouldn't","since","six","so","some","somebody","somehow","someone","something","sometime","sometimes","somewhat","somewhere","soon","sorry","specified","specify","specifying","still","sub","such","sup","sure","t","t's","take","taken","tell","tends","th","than","thank","thanks","thanx","that","that's","thats","the","their","theirs","them","themselves","then","thence","there","there's","thereafter","thereby","therefore","therein","theres","thereupon","these","they","they'd","they'll","they're","they've","think","third","this","thorough","thoroughly","those","though","three","through","throughout","thru","thus","to","together","too","took","toward","towards","tried","tries","truly","try","trying","twice","two","u","un","under","unfortunately","unless","unlikely","until","unto","up","upon","us","use","used","useful","uses","using","usually","uucp","v","value","various","very","via","viz","vs","w","want","wants","was","wasn't","way","we","we'd","we'll","we're","we've","welcome","well","went","were","weren't","what","what's","whatever","when","whence","whenever","where","where's","whereafter","whereas","whereby","wherein","whereupon","wherever","whether","which","while","whither","who","who's","whoever","whole","whom","whose","why","will","willing","wish","with","within","without","won't","wonder","would","wouldn't","x","y","yes","yet","you","you'd","you'll","you're","you've","your","yours","yourself","yourselves","z","zero"]
|
|
includes/ext/stopwords-json/dist/eo.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["adiaŭ","ajn","al","ankoraŭ","antaŭ","aŭ","bonan","bonvole","bonvolu","bv","ci","cia","cian","cin","d-ro","da","de","dek","deka","do","doktor'","doktoro","du","dua","dum","eble","ekz","ekzemple","en","estas","estis","estos","estu","estus","eĉ","f-no","feliĉan","for","fraŭlino","ha","havas","havis","havos","havu","havus","he","ho","hu","ili","ilia","ilian","ilin","inter","io","ion","iu","iujn","iun","ja","jam","je","jes","k","kaj","ke","kio","kion","kiu","kiujn","kiun","kvankam","kvar","kvara","kvazaŭ","kvin","kvina","la","li","lia","lian","lin","malantaŭ","male","malgraŭ","mem","mi","mia","mian","min","minus","naŭ","naŭa","ne","nek","nenio","nenion","neniu","neniun","nepre","ni","nia","nian","nin","nu","nun","nur","ok","oka","oni","onia","onian","onin","plej","pli","plu","plus","por","post","preter","s-no","s-ro","se","sed","sep","sepa","ses","sesa","si","sia","sian","sin","sinjor'","sinjorino","sinjoro","sub","super","supren","sur","tamen","tio","tion","tiu","tiujn","tiun","tra","tri","tria","tuj","tute","unu","unua","ve","verŝajne","vi","via","vian","vin","ĉi","ĉio","ĉion","ĉiu","ĉiujn","ĉiun","ĉu","ĝi","ĝia","ĝian","ĝin","ĝis","ĵus","ŝi","ŝia","ŝin"]
|
|
includes/ext/stopwords-json/dist/es.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","actualmente","acuerdo","adelante","ademas","además","adrede","afirmó","agregó","ahi","ahora","ahí","al","algo","alguna","algunas","alguno","algunos","algún","alli","allí","alrededor","ambos","ampleamos","antano","antaño","ante","anterior","antes","apenas","aproximadamente","aquel","aquella","aquellas","aquello","aquellos","aqui","aquél","aquélla","aquéllas","aquéllos","aquí","arriba","arribaabajo","aseguró","asi","así","atras","aun","aunque","ayer","añadió","aún","b","bajo","bastante","bien","breve","buen","buena","buenas","bueno","buenos","c","cada","casi","cerca","cierta","ciertas","cierto","ciertos","cinco","claro","comentó","como","con","conmigo","conocer","conseguimos","conseguir","considera","consideró","consigo","consigue","consiguen","consigues","contigo","contra","cosas","creo","cual","cuales","cualquier","cuando","cuanta","cuantas","cuanto","cuantos","cuatro","cuenta","cuál","cuáles","cuándo","cuánta","cuántas","cuánto","cuántos","cómo","d","da","dado","dan","dar","de","debajo","debe","deben","debido","decir","dejó","del","delante","demasiado","demás","dentro","deprisa","desde","despacio","despues","después","detras","detrás","dia","dias","dice","dicen","dicho","dieron","diferente","diferentes","dijeron","dijo","dio","donde","dos","durante","día","días","dónde","e","ejemplo","el","ella","ellas","ello","ellos","embargo","empleais","emplean","emplear","empleas","empleo","en","encima","encuentra","enfrente","enseguida","entonces","entre","era","eramos","eran","eras","eres","es","esa","esas","ese","eso","esos","esta","estaba","estaban","estado","estados","estais","estamos","estan","estar","estará","estas","este","esto","estos","estoy","estuvo","está","están","ex","excepto","existe","existen","explicó","expresó","f","fin","final","fue","fuera","fueron","fui","fuimos","g","general","gran","grandes","gueno","h","ha","haber","habia","habla","hablan","habrá","había","habían","hace","haceis","hacemos","hacen","hacer","hacerlo","haces","hacia","haciendo","hago","han","hasta","hay","haya","he","hecho","hemos","hicieron","hizo","horas","hoy","hubo","i","igual","incluso","indicó","informo","informó","intenta","intentais","intentamos","intentan","intentar","intentas","intento","ir","j","junto","k","l","la","lado","largo","las","le","lejos","les","llegó","lleva","llevar","lo","los","luego","lugar","m","mal","manera","manifestó","mas","mayor","me","mediante","medio","mejor","mencionó","menos","menudo","mi","mia","mias","mientras","mio","mios","mis","misma","mismas","mismo","mismos","modo","momento","mucha","muchas","mucho","muchos","muy","más","mí","mía","mías","mío","míos","n","nada","nadie","ni","ninguna","ningunas","ninguno","ningunos","ningún","no","nos","nosotras","nosotros","nuestra","nuestras","nuestro","nuestros","nueva","nuevas","nuevo","nuevos","nunca","o","ocho","os","otra","otras","otro","otros","p","pais","para","parece","parte","partir","pasada","pasado","paìs","peor","pero","pesar","poca","pocas","poco","pocos","podeis","podemos","poder","podria","podriais","podriamos","podrian","podrias","podrá","podrán","podría","podrían","poner","por","porque","posible","primer","primera","primero","primeros","principalmente","pronto","propia","propias","propio","propios","proximo","próximo","próximos","pudo","pueda","puede","pueden","puedo","pues","q","qeu","que","quedó","queremos","quien","quienes","quiere","quiza","quizas","quizá","quizás","quién","quiénes","qué","r","raras","realizado","realizar","realizó","repente","respecto","s","sabe","sabeis","sabemos","saben","saber","sabes","salvo","se","sea","sean","segun","segunda","segundo","según","seis","ser","sera","será","serán","sería","señaló","si","sido","siempre","siendo","siete","sigue","siguiente","sin","sino","sobre","sois","sola","solamente","solas","solo","solos","somos","son","soy","soyos","su","supuesto","sus","suya","suyas","suyo","sé","sí","sólo","t","tal","tambien","también","tampoco","tan","tanto","tarde","te","temprano","tendrá","tendrán","teneis","tenemos","tener","tenga","tengo","tenido","tenía","tercera","ti","tiempo","tiene","tienen","toda","todas","todavia","todavía","todo","todos","total","trabaja","trabajais","trabajamos","trabajan","trabajar","trabajas","trabajo","tras","trata","través","tres","tu","tus","tuvo","tuya","tuyas","tuyo","tuyos","tú","u","ultimo","un","una","unas","uno","unos","usa","usais","usamos","usan","usar","usas","uso","usted","ustedes","v","va","vais","valor","vamos","van","varias","varios","vaya","veces","ver","verdad","verdadera","verdadero","vez","vosotras","vosotros","voy","vuestra","vuestras","vuestro","vuestros","w","x","y","ya","yo","z","él","ésa","ésas","ése","ésos","ésta","éstas","éste","éstos","última","últimas","último","últimos"]
|
|
includes/ext/stopwords-json/dist/et.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["aga","ei","et","ja","jah","kas","kui","kõik","ma","me","mida","midagi","mind","minu","mis","mu","mul","mulle","nad","nii","oled","olen","oli","oma","on","pole","sa","seda","see","selle","siin","siis","ta","te","ära"]
|
|
includes/ext/stopwords-json/dist/eu.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["al","anitz","arabera","asko","baina","bat","batean","batek","bati","batzuei","batzuek","batzuetan","batzuk","bera","beraiek","berau","berauek","bere","berori","beroriek","beste","bezala","da","dago","dira","ditu","du","dute","edo","egin","ere","eta","eurak","ez","gainera","gu","gutxi","guzti","haiei","haiek","haietan","hainbeste","hala","han","handik","hango","hara","hari","hark","hartan","hau","hauei","hauek","hauetan","hemen","hemendik","hemengo","hi","hona","honek","honela","honetan","honi","hor","hori","horiei","horiek","horietan","horko","horra","horrek","horrela","horretan","horri","hortik","hura","izan","ni","noiz","nola","non","nondik","nongo","nor","nora","ze","zein","zen","zenbait","zenbat","zer","zergatik","ziren","zituen","zu","zuek","zuen","zuten"]
|
|
includes/ext/stopwords-json/dist/fa.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["آباد","آره","آری","آمد","آمده","آن","آنان","آنجا","آنكه","آنها","آنچه","آورد","آورده","آيد","آیا","اثرِ","از","است","استفاده","اش","اكنون","البته","البتّه","ام","اما","امروز","امسال","اند","انکه","او","اول","اي","ايشان","ايم","اين","اينكه","اگر","با","بار","بارة","باره","باشد","باشند","باشيم","بالا","بالایِ","بايد","بدون","بر","برابرِ","براساس","براي","برایِ","برخوردار","برخي","برداري","بروز","بسيار","بسياري","بعد","بعری","بعضي","بلكه","بله","بلکه","بلی","بنابراين","بندي","به","بهترين","بود","بودن","بودند","بوده","بي","بيست","بيش","بيشتر","بيشتري","بين","بی","بیرونِ","تا","تازه","تاكنون","تان","تحت","تر","ترين","تمام","تمامي","تنها","تواند","توانند","توسط","تولِ","تویِ","جا","جاي","جايي","جدا","جديد","جريان","جز","جلوگيري","جلویِ","حتي","حدودِ","حق","خارجِ","خدمات","خواست","خواهد","خواهند","خواهيم","خود","خويش","خیاه","داد","دادن","دادند","داده","دارد","دارند","داريم","داشت","داشتن","داشتند","داشته","دانست","دانند","در","درباره","دنبالِ","ده","دهد","دهند","دو","دوم","ديده","ديروز","ديگر","ديگران","ديگري","دیگر","را","راه","رفت","رفته","روب","روزهاي","روي","رویِ","ريزي","زياد","زير","زيرا","زیرِ","سابق","ساخته","سازي","سراسر","سریِ","سعي","سمتِ","سوم","سوي","سویِ","سپس","شان","شايد","شد","شدن","شدند","شده","شش","شما","شناسي","شود","شوند","صورت","ضدِّ","ضمن","طبقِ","طريق","طور","طي","عقبِ","علّتِ","عنوانِ","غير","فقط","فكر","فوق","قابل","قبل","قصدِ","كرد","كردم","كردن","كردند","كرده","كسي","كل","كمتر","كند","كنم","كنند","كنيد","كنيم","كه","لطفاً","ما","مان","مانند","مانندِ","مثل","مثلِ","مختلف","مدّتی","مردم","مرسی","مقابل","من","مورد","مي","ميليارد","ميليون","مگر","ناشي","نام","نبايد","نبود","نخست","نخستين","نخواهد","ندارد","ندارند","نداشته","نزديك","نزدِ","نزدیکِ","نشان","نشده","نظير","نكرده","نمايد","نمي","نه","نوعي","نيز","نيست","ها","هاي","هايي","هر","هرگز","هزار","هست","هستند","هستيم","هفت","هم","همان","همه","همواره","همين","همچنان","همچنين","همچون","همین","هنوز","هنگام","هنگامِ","هنگامی","هيچ","هیچ","و","وسطِ","وقتي","وقتیکه","ولی","وي","وگو","يا","يابد","يك","يكديگر","يكي","ّه","پاعینِ","پس","پنج","پيش","پیش","پیشِ","چرا","چطور","چند","چندین","چنين","چه","چهار","چون","چيزي","چگونه","چیز","چیزی","چیست","کجا","کجاست","کدام","کس","کسی","کنارِ","که","کَی","کی","گذاري","گذاشته","گردد","گرفت","گرفته","گروهي","گفت","گفته","گويد","گويند","گيرد","گيري","یا","یک"]
|
|
includes/ext/stopwords-json/dist/fi.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["aiemmin","aika","aikaa","aikaan","aikaisemmin","aikaisin","aikajen","aikana","aikoina","aikoo","aikovat","aina","ainakaan","ainakin","ainoa","ainoat","aiomme","aion","aiotte","aist","aivan","ajan","alas","alemmas","alkuisin","alkuun","alla","alle","aloitamme","aloitan","aloitat","aloitatte","aloitattivat","aloitettava","aloitettevaksi","aloitettu","aloitimme","aloitin","aloitit","aloititte","aloittaa","aloittamatta","aloitti","aloittivat","alta","aluksi","alussa","alusta","annettavaksi","annetteva","annettu","ansiosta","antaa","antamatta","antoi","aoua","apu","asia","asiaa","asian","asiasta","asiat","asioiden","asioihin","asioita","asti","avuksi","avulla","avun","avutta","edelle","edelleen","edellä","edeltä","edemmäs","edes","edessä","edestä","ehkä","ei","eikä","eilen","eivät","eli","ellei","elleivät","ellemme","ellen","ellet","ellette","emme","en","enemmän","eniten","ennen","ensi","ensimmäinen","ensimmäiseksi","ensimmäisen","ensimmäisenä","ensimmäiset","ensimmäisiksi","ensimmäisinä","ensimmäisiä","ensimmäistä","ensin","entinen","entisen","entisiä","entisten","entistä","enää","eri","erittäin","erityisesti","eräiden","eräs","eräät","esi","esiin","esillä","esimerkiksi","et","eteen","etenkin","etessa","ette","ettei","että","haikki","halua","haluaa","haluamatta","haluamme","haluan","haluat","haluatte","haluavat","halunnut","halusi","halusimme","halusin","halusit","halusitte","halusivat","halutessa","haluton","he","hei","heidän","heihin","heille","heiltä","heissä","heistä","heitä","helposti","heti","hetkellä","hieman","hitaasti","hoikein","huolimatta","huomenna","hyvien","hyviin","hyviksi","hyville","hyviltä","hyvin","hyvinä","hyvissä","hyvistä","hyviä","hyvä","hyvät","hyvää","hän","häneen","hänelle","hänellä","häneltä","hänen","hänessä","hänestä","hänet","ihan","ilman","ilmeisesti","itse","itsensä","itseään","ja","jo","johon","joiden","joihin","joiksi","joilla","joille","joilta","joissa","joista","joita","joka","jokainen","jokin","joko","joku","jolla","jolle","jolloin","jolta","jompikumpi","jonka","jonkin","jonne","joo","jopa","jos","joskus","jossa","josta","jota","jotain","joten","jotenkin","jotenkuten","jotka","jotta","jouduimme","jouduin","jouduit","jouduitte","joudumme","joudun","joudutte","joukkoon","joukossa","joukosta","joutua","joutui","joutuivat","joutumaan","joutuu","joutuvat","juuri","jälkeen","jälleen","jää","kahdeksan","kahdeksannen","kahdella","kahdelle","kahdelta","kahden","kahdessa","kahdesta","kahta","kahteen","kai","kaiken","kaikille","kaikilta","kaikkea","kaikki","kaikkia","kaikkiaan","kaikkialla","kaikkialle","kaikkialta","kaikkien","kaikkin","kaksi","kannalta","kannattaa","kanssa","kanssaan","kanssamme","kanssani","kanssanne","kanssasi","kauan","kauemmas","kaukana","kautta","kehen","keiden","keihin","keiksi","keille","keillä","keiltä","keinä","keissä","keistä","keitten","keittä","keitä","keneen","keneksi","kenelle","kenellä","keneltä","kenen","kenenä","kenessä","kenestä","kenet","kenettä","kennessästä","kenties","kerran","kerta","kertaa","keskellä","kesken","keskimäärin","ketkä","ketä","kiitos","kohti","koko","kokonaan","kolmas","kolme","kolmen","kolmesti","koska","koskaan","kovin","kuin","kuinka","kuinkan","kuitenkaan","kuitenkin","kuka","kukaan","kukin","kukka","kumpainen","kumpainenkaan","kumpi","kumpikaan","kumpikin","kun","kuten","kuuden","kuusi","kuutta","kylliksi","kyllä","kymmenen","kyse","liian","liki","lisäksi","lisää","lla","luo","luona","lähekkäin","lähelle","lähellä","läheltä","lähemmäs","lähes","lähinnä","lähtien","läpi","mahdollisimman","mahdollista","me","meidän","meille","meillä","melkein","melko","menee","meneet","menemme","menen","menet","menette","menevät","meni","menimme","menin","menit","menivät","mennessä","mennyt","menossa","mihin","mikin","miksi","mikä","mikäli","mikään","milloin","milloinkan","minne","minun","minut","minä","missä","mistä","miten","mitä","mitään","moi","molemmat","mones","monesti","monet","moni","moniaalla","moniaalle","moniaalta","monta","muassa","muiden","muita","muka","mukaan","mukaansa","mukana","mutta","muu","muualla","muualle","muualta","muuanne","muulloin","muun","muut","muuta","muutama","muutaman","muuten","myöhemmin","myös","myöskin","myöskään","myötä","ne","neljä","neljän","neljää","niiden","niin","niistä","niitä","noin","nopeammin","nopeasti","nopeiten","nro","nuo","nyt","näiden","näin","näissä","näissähin","näissälle","näissältä","näissästä","näitä","nämä","ohi","oikea","oikealla","oikein","ole","olemme","olen","olet","olette","oleva","olevan","olevat","oli","olimme","olin","olisi","olisimme","olisin","olisit","olisitte","olisivat","olit","olitte","olivat","olla","olleet","olli","ollut","oma","omaa","omaan","omaksi","omalle","omalta","oman","omassa","omat","omia","omien","omiin","omiksi","omille","omilta","omissa","omista","on","onkin","onko","ovat","paikoittain","paitsi","pakosti","paljon","paremmin","parempi","parhaillaan","parhaiten","perusteella","peräti","pian","pieneen","pieneksi","pienelle","pienellä","pieneltä","pienempi","pienestä","pieni","pienin","puolesta","puolestaan","päälle","runsaasti","saakka","sadam","sama","samaa","samaan","samalla","samallalta","samallassa","samallasta","saman","samat","samoin","sata","sataa","satojen","se","seitsemän","sekä","sen","seuraavat","siellä","sieltä","siihen","siinä","siis","siitä","sijaan","siksi","silloin","sillä","silti","sinne","sinua","sinulle","sinulta","sinun","sinussa","sinusta","sinut","sinä","sisäkkäin","sisällä","siten","sitten","sitä","ssa","sta","suoraan","suuntaan","suuren","suuret","suuri","suuria","suurin","suurten","taa","taas","taemmas","tahansa","tai","takaa","takaisin","takana","takia","tapauksessa","tarpeeksi","tavalla","tavoitteena","te","tietysti","todella","toinen","toisaalla","toisaalle","toisaalta","toiseen","toiseksi","toisella","toiselle","toiselta","toisemme","toisen","toisensa","toisessa","toisesta","toista","toistaiseksi","toki","tosin","tuhannen","tuhat","tule","tulee","tulemme","tulen","tulet","tulette","tulevat","tulimme","tulin","tulisi","tulisimme","tulisin","tulisit","tulisitte","tulisivat","tulit","tulitte","tulivat","tulla","tulleet","tullut","tuntuu","tuo","tuolla","tuolloin","tuolta","tuonne","tuskin","tykö","tähän","tällä","tällöin","tämä","tämän","tänne","tänä","tänään","tässä","tästä","täten","tätä","täysin","täytyvät","täytyy","täällä","täältä","ulkopuolella","usea","useasti","useimmiten","usein","useita","uudeksi","uudelleen","uuden","uudet","uusi","uusia","uusien","uusinta","uuteen","uutta","vaan","vahemmän","vai","vaiheessa","vaikea","vaikean","vaikeat","vaikeilla","vaikeille","vaikeilta","vaikeissa","vaikeista","vaikka","vain","varmasti","varsin","varsinkin","varten","vasen","vasenmalla","vasta","vastaan","vastakkain","vastan","verran","vielä","vierekkäin","vieressä","vieri","viiden","viime","viimeinen","viimeisen","viimeksi","viisi","voi","voidaan","voimme","voin","voisi","voit","voitte","voivat","vuoden","vuoksi","vuosi","vuosien","vuosina","vuotta","vähemmän","vähintään","vähiten","vähän","välillä","yhdeksän","yhden","yhdessä","yhteen","yhteensä","yhteydessä","yhteyteen","yhtä","yhtäälle","yhtäällä","yhtäältä","yhtään","yhä","yksi","yksin","yksittäin","yleensä","ylemmäs","yli","ylös","ympäri","älköön","älä"]
|
|
includes/ext/stopwords-json/dist/fr.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","abord","absolument","afin","ah","ai","aie","ailleurs","ainsi","ait","allaient","allo","allons","allô","alors","anterieur","anterieure","anterieures","apres","après","as","assez","attendu","au","aucun","aucune","aujourd","aujourd'hui","aupres","auquel","aura","auraient","aurait","auront","aussi","autre","autrefois","autrement","autres","autrui","aux","auxquelles","auxquels","avaient","avais","avait","avant","avec","avoir","avons","ayant","b","bah","bas","basee","bat","beau","beaucoup","bien","bigre","boum","bravo","brrr","c","car","ce","ceci","cela","celle","celle-ci","celle-là","celles","celles-ci","celles-là","celui","celui-ci","celui-là","cent","cependant","certain","certaine","certaines","certains","certes","ces","cet","cette","ceux","ceux-ci","ceux-là","chacun","chacune","chaque","cher","chers","chez","chiche","chut","chère","chères","ci","cinq","cinquantaine","cinquante","cinquantième","cinquième","clac","clic","combien","comme","comment","comparable","comparables","compris","concernant","contre","couic","crac","d","da","dans","de","debout","dedans","dehors","deja","delà","depuis","dernier","derniere","derriere","derrière","des","desormais","desquelles","desquels","dessous","dessus","deux","deuxième","deuxièmement","devant","devers","devra","different","differentes","differents","différent","différente","différentes","différents","dire","directe","directement","dit","dite","dits","divers","diverse","diverses","dix","dix-huit","dix-neuf","dix-sept","dixième","doit","doivent","donc","dont","douze","douzième","dring","du","duquel","durant","dès","désormais","e","effet","egale","egalement","egales","eh","elle","elle-même","elles","elles-mêmes","en","encore","enfin","entre","envers","environ","es","est","et","etant","etc","etre","eu","euh","eux","eux-mêmes","exactement","excepté","extenso","exterieur","f","fais","faisaient","faisant","fait","façon","feront","fi","flac","floc","font","g","gens","h","ha","hein","hem","hep","hi","ho","holà","hop","hormis","hors","hou","houp","hue","hui","huit","huitième","hum","hurrah","hé","hélas","i","il","ils","importe","j","je","jusqu","jusque","juste","k","l","la","laisser","laquelle","las","le","lequel","les","lesquelles","lesquels","leur","leurs","longtemps","lors","lorsque","lui","lui-meme","lui-même","là","lès","m","ma","maint","maintenant","mais","malgre","malgré","maximale","me","meme","memes","merci","mes","mien","mienne","miennes","miens","mille","mince","minimale","moi","moi-meme","moi-même","moindres","moins","mon","moyennant","multiple","multiples","même","mêmes","n","na","naturel","naturelle","naturelles","ne","neanmoins","necessaire","necessairement","neuf","neuvième","ni","nombreuses","nombreux","non","nos","notamment","notre","nous","nous-mêmes","nouveau","nul","néanmoins","nôtre","nôtres","o","oh","ohé","ollé","olé","on","ont","onze","onzième","ore","ou","ouf","ouias","oust","ouste","outre","ouvert","ouverte","ouverts","o|","où","p","paf","pan","par","parce","parfois","parle","parlent","parler","parmi","parseme","partant","particulier","particulière","particulièrement","pas","passé","pendant","pense","permet","personne","peu","peut","peuvent","peux","pff","pfft","pfut","pif","pire","plein","plouf","plus","plusieurs","plutôt","possessif","possessifs","possible","possibles","pouah","pour","pourquoi","pourrais","pourrait","pouvait","prealable","precisement","premier","première","premièrement","pres","probable","probante","procedant","proche","près","psitt","pu","puis","puisque","pur","pure","q","qu","quand","quant","quant-à-soi","quanta","quarante","quatorze","quatre","quatre-vingt","quatrième","quatrièmement","que","quel","quelconque","quelle","quelles","quelqu'un","quelque","quelques","quels","qui","quiconque","quinze","quoi","quoique","r","rare","rarement","rares","relative","relativement","remarquable","rend","rendre","restant","reste","restent","restrictif","retour","revoici","revoilà","rien","s","sa","sacrebleu","sait","sans","sapristi","sauf","se","sein","seize","selon","semblable","semblaient","semble","semblent","sent","sept","septième","sera","seraient","serait","seront","ses","seul","seule","seulement","si","sien","sienne","siennes","siens","sinon","six","sixième","soi","soi-même","soit","soixante","son","sont","sous","souvent","specifique","specifiques","speculatif","stop","strictement","subtiles","suffisant","suffisante","suffit","suis","suit","suivant","suivante","suivantes","suivants","suivre","superpose","sur","surtout","t","ta","tac","tant","tardive","te","tel","telle","tellement","telles","tels","tenant","tend","tenir","tente","tes","tic","tien","tienne","tiennes","tiens","toc","toi","toi-même","ton","touchant","toujours","tous","tout","toute","toutefois","toutes","treize","trente","tres","trois","troisième","troisièmement","trop","très","tsoin","tsouin","tu","té","u","un","une","unes","uniformement","unique","uniques","uns","v","va","vais","vas","vers","via","vif","vifs","vingt","vivat","vive","vives","vlan","voici","voilà","vont","vos","votre","vous","vous-mêmes","vu","vé","vôtre","vôtres","w","x","y","z","zut","à","â","ça","ès","étaient","étais","était","étant","été","être","ô"]
|
|
includes/ext/stopwords-json/dist/ga.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","ach","ag","agus","an","aon","ar","arna","as","b'","ba","beirt","bhúr","caoga","ceathair","ceathrar","chomh","chtó","chuig","chun","cois","céad","cúig","cúigear","d'","daichead","dar","de","deich","deichniúr","den","dhá","do","don","dtí","dá","dár","dó","faoi","faoin","faoina","faoinár","fara","fiche","gach","gan","go","gur","haon","hocht","i","iad","idir","in","ina","ins","inár","is","le","leis","lena","lenár","m'","mar","mo","mé","na","nach","naoi","naonúr","ná","ní","níor","nó","nócha","ocht","ochtar","os","roimh","sa","seacht","seachtar","seachtó","seasca","seisear","siad","sibh","sinn","sna","sé","sí","tar","thar","thú","triúr","trí","trína","trínár","tríocha","tú","um","ár","é","éis","í","ó","ón","óna","ónár"]
|
|
includes/ext/stopwords-json/dist/gl.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","alí","ao","aos","aquel","aquela","aquelas","aqueles","aquilo","aquí","as","así","aínda","ben","cando","che","co","coa","coas","comigo","con","connosco","contigo","convosco","cos","cun","cunha","cunhas","cuns","da","dalgunha","dalgunhas","dalgún","dalgúns","das","de","del","dela","delas","deles","desde","deste","do","dos","dun","dunha","dunhas","duns","e","el","ela","elas","eles","en","era","eran","esa","esas","ese","eses","esta","estaba","estar","este","estes","estiven","estou","está","están","eu","facer","foi","foron","fun","había","hai","iso","isto","la","las","lle","lles","lo","los","mais","me","meu","meus","min","miña","miñas","moi","na","nas","neste","nin","no","non","nos","nosa","nosas","noso","nosos","nun","nunha","nunhas","nuns","nós","o","os","ou","para","pero","pode","pois","pola","polas","polo","polos","por","que","se","senón","ser","seu","seus","sexa","sido","sobre","súa","súas","tamén","tan","te","ten","ter","teu","teus","teñen","teño","ti","tido","tiven","tiña","túa","túas","un","unha","unhas","uns","vos","vosa","vosas","voso","vosos","vós","á","é","ó","ós"]
|
|
includes/ext/stopwords-json/dist/ha.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","amma","ba","ban","ce","cikin","da","don","ga","in","ina","ita","ji","ka","ko","kuma","lokacin","ma","mai","na","ne","ni","sai","shi","su","suka","sun","ta","tafi","take","tana","wani","wannan","wata","ya","yake","yana","yi","za"]
|
|
includes/ext/stopwords-json/dist/he.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["אבל","או","אולי","אותה","אותו","אותי","אותך","אותם","אותן","אותנו","אז","אחר","אחרות","אחרי","אחריכן","אחרים","אחרת","אי","איזה","איך","אין","איפה","איתה","איתו","איתי","איתך","איתכם","איתכן","איתם","איתן","איתנו","אך","אל","אלה","אלו","אם","אנחנו","אני","אס","אף","אצל","אשר","את","אתה","אתכם","אתכן","אתם","אתן","באיזומידה","באמצע","באמצעות","בגלל","בין","בלי","במידה","במקוםשבו","ברם","בשביל","בשעהש","בתוך","גם","דרך","הוא","היא","היה","היכן","היתה","היתי","הם","הן","הנה","הסיבהשבגללה","הרי","ואילו","ואת","זאת","זה","זות","יהיה","יוכל","יוכלו","יותרמדי","יכול","יכולה","יכולות","יכולים","יכל","יכלה","יכלו","יש","כאן","כאשר","כולם","כולן","כזה","כי","כיצד","כך","ככה","כל","כלל","כמו","כן","כפי","כש","לא","לאו","לאיזותכלית","לאן","לבין","לה","להיות","להם","להן","לו","לי","לכם","לכן","למה","למטה","למעלה","למקוםשבו","למרות","לנו","לעבר","לעיכן","לפיכך","לפני","מאד","מאחורי","מאיזוסיבה","מאין","מאיפה","מבלי","מבעד","מדוע","מה","מהיכן","מול","מחוץ","מי","מכאן","מכיוון","מלבד","מן","מנין","מסוגל","מעט","מעטים","מעל","מצד","מקוםבו","מתחת","מתי","נגד","נגר","נו","עד","עז","על","עלי","עליה","עליהם","עליהן","עליו","עליך","עליכם","עלינו","עם","עצמה","עצמהם","עצמהן","עצמו","עצמי","עצמם","עצמן","עצמנו","פה","רק","שוב","של","שלה","שלהם","שלהן","שלו","שלי","שלך","שלכה","שלכם","שלכן","שלנו","שם","תהיה","תחת"]
|
|
includes/ext/stopwords-json/dist/hi.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["अंदर","अत","अदि","अप","अपना","अपनि","अपनी","अपने","अभि","अभी","आदि","आप","इंहिं","इंहें","इंहों","इतयादि","इत्यादि","इन","इनका","इन्हीं","इन्हें","इन्हों","इस","इसका","इसकि","इसकी","इसके","इसमें","इसि","इसी","इसे","उंहिं","उंहें","उंहों","उन","उनका","उनकि","उनकी","उनके","उनको","उन्हीं","उन्हें","उन्हों","उस","उसके","उसि","उसी","उसे","एक","एवं","एस","एसे","ऐसे","ओर","और","कइ","कई","कर","करता","करते","करना","करने","करें","कहते","कहा","का","काफि","काफ़ी","कि","किंहें","किंहों","कितना","किन्हें","किन्हों","किया","किर","किस","किसि","किसी","किसे","की","कुछ","कुल","के","को","कोइ","कोई","कोन","कोनसा","कौन","कौनसा","गया","घर","जब","जहाँ","जहां","जा","जिंहें","जिंहों","जितना","जिधर","जिन","जिन्हें","जिन्हों","जिस","जिसे","जीधर","जेसा","जेसे","जैसा","जैसे","जो","तक","तब","तरह","तिंहें","तिंहों","तिन","तिन्हें","तिन्हों","तिस","तिसे","तो","था","थि","थी","थे","दबारा","दवारा","दिया","दुसरा","दुसरे","दूसरे","दो","द्वारा","न","नहिं","नहीं","ना","निचे","निहायत","नीचे","ने","पर","पहले","पुरा","पूरा","पे","फिर","बनि","बनी","बहि","बही","बहुत","बाद","बाला","बिलकुल","भि","भितर","भी","भीतर","मगर","मानो","मे","में","यदि","यह","यहाँ","यहां","यहि","यही","या","यिह","ये","रखें","रवासा","रहा","रहे","ऱ्वासा","लिए","लिये","लेकिन","व","वगेरह","वरग","वर्ग","वह","वहाँ","वहां","वहिं","वहीं","वाले","वुह","वे","वग़ैरह","संग","सकता","सकते","सबसे","सभि","सभी","साथ","साबुत","साभ","सारा","से","सो","हि","ही","हुअ","हुआ","हुइ","हुई","हुए","हे","हें","है","हैं","हो","होता","होति","होती","होते","होना","होने"]
|
|
includes/ext/stopwords-json/dist/hr.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","ako","ali","bi","bih","bila","bili","bilo","bio","bismo","biste","biti","bumo","da","do","duž","ga","hoće","hoćemo","hoćete","hoćeš","hoću","i","iako","ih","ili","iz","ja","je","jedna","jedne","jedno","jer","jesam","jesi","jesmo","jest","jeste","jesu","jim","joj","još","ju","kada","kako","kao","koja","koje","koji","kojima","koju","kroz","li","me","mene","meni","mi","mimo","moj","moja","moje","mu","na","nad","nakon","nam","nama","nas","naš","naša","naše","našeg","ne","nego","neka","neki","nekog","neku","nema","netko","neće","nećemo","nećete","nećeš","neću","nešto","ni","nije","nikoga","nikoje","nikoju","nisam","nisi","nismo","niste","nisu","njega","njegov","njegova","njegovo","njemu","njezin","njezina","njezino","njih","njihov","njihova","njihovo","njim","njima","njoj","nju","no","o","od","odmah","on","ona","oni","ono","ova","pa","pak","po","pod","pored","prije","s","sa","sam","samo","se","sebe","sebi","si","smo","ste","su","sve","svi","svog","svoj","svoja","svoje","svom","ta","tada","taj","tako","te","tebe","tebi","ti","to","toj","tome","tu","tvoj","tvoja","tvoje","u","uz","vam","vama","vas","vaš","vaša","vaše","već","vi","vrlo","za","zar","će","ćemo","ćete","ćeš","ću","što"]
|
|
includes/ext/stopwords-json/dist/hu.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","abba","abban","abból","addig","ahhoz","ahogy","ahol","aki","akik","akkor","akár","alapján","alatt","alatta","alattad","alattam","alattatok","alattuk","alattunk","alá","alád","alájuk","alám","alánk","alátok","alól","alóla","alólad","alólam","alólatok","alóluk","alólunk","amely","amelybol","amelyek","amelyekben","amelyeket","amelyet","amelyik","amelynek","ami","amikor","amit","amolyan","amott","amíg","annak","annál","arra","arról","attól","az","aznap","azok","azokat","azokba","azokban","azokból","azokhoz","azokig","azokkal","azokká","azoknak","azoknál","azokon","azokra","azokról","azoktól","azokért","azon","azonban","azonnal","azt","aztán","azután","azzal","azzá","azért","bal","balra","ban","be","belé","beléd","beléjük","belém","belénk","belétek","belül","belőle","belőled","belőlem","belőletek","belőlük","belőlünk","ben","benne","benned","bennem","bennetek","bennük","bennünk","bár","bárcsak","bármilyen","búcsú","cikk","cikkek","cikkeket","csak","csakhogy","csupán","de","dehogy","e","ebbe","ebben","ebből","eddig","egy","egyebek","egyebet","egyedül","egyelőre","egyes","egyet","egyetlen","egyik","egymás","egyre","egyszerre","egyéb","együtt","egész","egészen","ehhez","ekkor","el","eleinte","ellen","ellenes","elleni","ellenére","elmondta","első","elsők","elsősorban","elsőt","elé","eléd","elég","eléjük","elém","elénk","elétek","elő","előbb","elől","előle","előled","előlem","előletek","előlük","előlünk","először","előtt","előtte","előtted","előttem","előttetek","előttük","előttünk","előző","emilyen","engem","ennek","ennyi","ennél","enyém","erre","erről","esetben","ettől","ez","ezek","ezekbe","ezekben","ezekből","ezeken","ezeket","ezekhez","ezekig","ezekkel","ezekké","ezeknek","ezeknél","ezekre","ezekről","ezektől","ezekért","ezen","ezentúl","ezer","ezret","ezt","ezután","ezzel","ezzé","ezért","fel","fele","felek","felet","felett","felé","fent","fenti","fél","fölé","gyakran","ha","halló","hamar","hanem","harmadik","harmadikat","harminc","hat","hatodik","hatodikat","hatot","hatvan","helyett","hetedik","hetediket","hetet","hetven","hirtelen","hiszen","hiába","hogy","hogyan","hol","holnap","holnapot","honnan","hova","hozzá","hozzád","hozzájuk","hozzám","hozzánk","hozzátok","hurrá","huszadik","hány","hányszor","hármat","három","hát","hátha","hátulsó","hét","húsz","ide","ide-оda","idén","igazán","igen","ill","illetve","ilyen","ilyenkor","immár","inkább","is","ismét","ison","itt","jelenleg","jobban","jobbra","jó","jól","jólesik","jóval","jövőre","kell","kellene","kellett","kelljen","keressünk","keresztül","ketten","kettő","kettőt","kevés","ki","kiben","kiből","kicsit","kicsoda","kihez","kik","kikbe","kikben","kikből","kiken","kiket","kikhez","kikkel","kikké","kiknek","kiknél","kikre","kikről","kiktől","kikért","kilenc","kilencedik","kilencediket","kilencet","kilencven","kin","kinek","kinél","kire","kiről","kit","kitől","kivel","kivé","kié","kiért","korábban","képest","kérem","kérlek","kész","késő","később","későn","két","kétszer","kívül","körül","köszönhetően","köszönöm","közben","közel","közepesen","közepén","közé","között","közül","külön","különben","különböző","különbözőbb","különbözőek","lassan","le","legalább","legyen","lehet","lehetetlen","lehetett","lehetőleg","lehetőség","lenne","lenni","lennék","lennének","lesz","leszek","lesznek","leszünk","lett","lettek","lettem","lettünk","lévő","ma","maga","magad","magam","magatokat","magukat","magunkat","magát","mai","majd","majdnem","manapság","meg","megcsinál","megcsinálnak","megint","megvan","mellett","mellette","melletted","mellettem","mellettetek","mellettük","mellettünk","mellé","melléd","melléjük","mellém","mellénk","mellétek","mellől","mellőle","mellőled","mellőlem","mellőletek","mellőlük","mellőlünk","mely","melyek","melyik","mennyi","mert","mi","miatt","miatta","miattad","miattam","miattatok","miattuk","miattunk","mibe","miben","miből","mihez","mik","mikbe","mikben","mikből","miken","miket","mikhez","mikkel","mikké","miknek","miknél","mikor","mikre","mikről","miktől","mikért","milyen","min","mind","mindegyik","mindegyiket","minden","mindenesetre","mindenki","mindent","mindenütt","mindig","mindketten","minek","minket","mint","mintha","minél","mire","miről","mit","mitől","mivel","mivé","miért","mondta","most","mostanáig","már","más","másik","másikat","másnap","második","másodszor","mások","másokat","mást","még","mégis","míg","mögé","mögéd","mögéjük","mögém","mögénk","mögétek","mögött","mögötte","mögötted","mögöttem","mögöttetek","mögöttük","mögöttünk","mögül","mögüle","mögüled","mögülem","mögületek","mögülük","mögülünk","múltkor","múlva","na","nagy","nagyobb","nagyon","naponta","napot","ne","negyedik","negyediket","negyven","neked","nekem","neki","nekik","nektek","nekünk","nem","nemcsak","nemrég","nincs","nyolc","nyolcadik","nyolcadikat","nyolcat","nyolcvan","nála","nálad","nálam","nálatok","náluk","nálunk","négy","négyet","néha","néhány","nélkül","o","oda","ok","olyan","onnan","ott","pedig","persze","pár","például","rajta","rajtad","rajtam","rajtatok","rajtuk","rajtunk","rendben","rosszul","rá","rád","rájuk","rám","ránk","rátok","régen","régóta","részére","róla","rólad","rólam","rólatok","róluk","rólunk","rögtön","s","saját","se","sem","semmi","semmilyen","semmiség","senki","soha","sok","sokan","sokat","sokkal","sokszor","sokáig","során","stb.","szemben","szerbusz","szerint","szerinte","szerinted","szerintem","szerintetek","szerintük","szerintünk","szervusz","szinte","számára","száz","századik","százat","szépen","szét","szíves","szívesen","szíveskedjék","sőt","talán","tavaly","te","tegnap","tegnapelőtt","tehát","tele","teljes","tessék","ti","tied","titeket","tizedik","tizediket","tizenegy","tizenegyedik","tizenhat","tizenhárom","tizenhét","tizenkettedik","tizenkettő","tizenkilenc","tizenkét","tizennyolc","tizennégy","tizenöt","tizet","tovább","további","továbbá","távol","téged","tényleg","tíz","több","többi","többször","túl","tőle","tőled","tőlem","tőletek","tőlük","tőlünk","ugyanakkor","ugyanez","ugyanis","ugye","urak","uram","urat","utoljára","utolsó","után","utána","vagy","vagyis","vagyok","vagytok","vagyunk","vajon","valahol","valaki","valakit","valamelyik","valami","valamint","való","van","vannak","vele","veled","velem","veletek","velük","velünk","vissza","viszlát","viszont","viszontlátásra","volna","volnának","volnék","volt","voltak","voltam","voltunk","végre","végén","végül","által","általában","ám","át","éljen","én","éppen","érte","érted","értem","értetek","értük","értünk","és","év","évben","éve","évek","éves","évi","évvel","így","óta","ön","önbe","önben","önből","önhöz","önnek","önnel","önnél","önre","önről","önt","öntől","önért","önök","önökbe","önökben","önökből","önöket","önökhöz","önökkel","önöknek","önöknél","önökre","önökről","önöktől","önökért","önökön","önön","össze","öt","ötven","ötödik","ötödiket","ötöt","úgy","úgyis","úgynevezett","új","újabb","újra","úr","ő","ők","őket","őt"]
|
|
includes/ext/stopwords-json/dist/hy.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["այդ","այլ","այն","այս","դու","դուք","եմ","են","ենք","ես","եք","է","էի","էին","էինք","էիր","էիք","էր","ըստ","թ","ի","ին","իսկ","իր","կամ","համար","հետ","հետո","մենք","մեջ","մի","ն","նա","նաև","նրա","նրանք","որ","որը","որոնք","որպես","ու","ում","պիտի","վրա","և"]
|
|
includes/ext/stopwords-json/dist/id.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["ada","adalah","adanya","adapun","agak","agaknya","agar","akan","akankah","akhirnya","aku","akulah","amat","amatlah","anda","andalah","antar","antara","antaranya","apa","apaan","apabila","apakah","apalagi","apatah","atau","ataukah","ataupun","bagai","bagaikan","bagaimana","bagaimanakah","bagaimanapun","bagi","bahkan","bahwa","bahwasanya","banyak","beberapa","begini","beginian","beginikah","beginilah","begitu","begitukah","begitulah","begitupun","belum","belumlah","berapa","berapakah","berapalah","berapapun","bermacam","bersama","betulkah","biasa","biasanya","bila","bilakah","bisa","bisakah","boleh","bolehkah","bolehlah","buat","bukan","bukankah","bukanlah","bukannya","cuma","dahulu","dalam","dan","dapat","dari","daripada","dekat","demi","demikian","demikianlah","dengan","depan","di","dia","dialah","diantara","diantaranya","dikarenakan","dini","diri","dirinya","disini","disinilah","dong","dulu","enggak","enggaknya","entah","entahlah","hal","hampir","hanya","hanyalah","harus","haruslah","harusnya","hendak","hendaklah","hendaknya","hingga","ia","ialah","ibarat","ingin","inginkah","inginkan","ini","inikah","inilah","itu","itukah","itulah","jangan","jangankan","janganlah","jika","jikalau","juga","justru","kala","kalau","kalaulah","kalaupun","kalian","kami","kamilah","kamu","kamulah","kan","kapan","kapankah","kapanpun","karena","karenanya","ke","kecil","kemudian","kenapa","kepada","kepadanya","ketika","khususnya","kini","kinilah","kiranya","kita","kitalah","kok","lagi","lagian","lah","lain","lainnya","lalu","lama","lamanya","lebih","macam","maka","makanya","makin","malah","malahan","mampu","mampukah","mana","manakala","manalagi","masih","masihkah","masing","mau","maupun","melainkan","melalui","memang","mengapa","mereka","merekalah","merupakan","meski","meskipun","mungkin","mungkinkah","nah","namun","nanti","nantinya","nyaris","oleh","olehnya","pada","padahal","padanya","paling","pantas","para","pasti","pastilah","per","percuma","pernah","pula","pun","rupanya","saat","saatnya","saja","sajalah","saling","sama","sambil","sampai","sana","sangat","sangatlah","saya","sayalah","se","sebab","sebabnya","sebagai","sebagaimana","sebagainya","sebaliknya","sebanyak","sebegini","sebegitu","sebelum","sebelumnya","sebenarnya","seberapa","sebetulnya","sebisanya","sebuah","sedang","sedangkan","sedemikian","sedikit","sedikitnya","segala","segalanya","segera","seharusnya","sehingga","sejak","sejenak","sekali","sekalian","sekaligus","sekalipun","sekarang","seketika","sekiranya","sekitar","sekitarnya","sela","selagi","selain","selaku","selalu","selama","selamanya","seluruh","seluruhnya","semacam","semakin","semasih","semaunya","sementara","sempat","semua","semuanya","semula","sendiri","sendirinya","seolah","seorang","sepanjang","sepantasnya","sepantasnyalah","seperti","sepertinya","sering","seringnya","serta","serupa","sesaat","sesama","sesegera","sesekali","seseorang","sesuatu","sesuatunya","sesudah","sesudahnya","setelah","seterusnya","setiap","setidaknya","sewaktu","siapa","siapakah","siapapun","sini","sinilah","suatu","sudah","sudahkah","sudahlah","supaya","tadi","tadinya","tak","tanpa","tapi","telah","tentang","tentu","tentulah","tentunya","terdiri","terhadap","terhadapnya","terlalu","terlebih","tersebut","tersebutlah","tertentu","tetapi","tiap","tidak","tidakkah","tidaklah","toh","waduh","wah","wahai","walau","walaupun","wong","yaitu","yakni","yang"]
|
|
includes/ext/stopwords-json/dist/it.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["IE","a","abbastanza","abbia","abbiamo","abbiano","abbiate","accidenti","ad","adesso","affinche","agl","agli","ahime","ahimè","ai","al","alcuna","alcuni","alcuno","all","alla","alle","allo","allora","altri","altrimenti","altro","altrove","altrui","anche","ancora","anni","anno","ansa","anticipo","assai","attesa","attraverso","avanti","avemmo","avendo","avente","aver","avere","averlo","avesse","avessero","avessi","avessimo","aveste","avesti","avete","aveva","avevamo","avevano","avevate","avevi","avevo","avrai","avranno","avrebbe","avrebbero","avrei","avremmo","avremo","avreste","avresti","avrete","avrà","avrò","avuta","avute","avuti","avuto","basta","bene","benissimo","berlusconi","brava","bravo","c","casa","caso","cento","certa","certe","certi","certo","che","chi","chicchessia","chiunque","ci","ciascuna","ciascuno","cima","cio","cioe","cioè","circa","citta","città","ciò","co","codesta","codesti","codesto","cogli","coi","col","colei","coll","coloro","colui","come","cominci","comunque","con","concernente","conciliarsi","conclusione","consiglio","contro","cortesia","cos","cosa","cosi","così","cui","d","da","dagl","dagli","dai","dal","dall","dalla","dalle","dallo","dappertutto","davanti","degl","degli","dei","del","dell","della","delle","dello","dentro","detto","deve","di","dice","dietro","dire","dirimpetto","diventa","diventare","diventato","dopo","dov","dove","dovra","dovrà","dovunque","due","dunque","durante","e","ebbe","ebbero","ebbi","ecc","ecco","ed","effettivamente","egli","ella","entrambi","eppure","era","erano","eravamo","eravate","eri","ero","esempio","esse","essendo","esser","essere","essi","ex","fa","faccia","facciamo","facciano","facciate","faccio","facemmo","facendo","facesse","facessero","facessi","facessimo","faceste","facesti","faceva","facevamo","facevano","facevate","facevi","facevo","fai","fanno","farai","faranno","fare","farebbe","farebbero","farei","faremmo","faremo","fareste","faresti","farete","farà","farò","fatto","favore","fece","fecero","feci","fin","finalmente","finche","fine","fino","forse","forza","fosse","fossero","fossi","fossimo","foste","fosti","fra","frattempo","fu","fui","fummo","fuori","furono","futuro","generale","gia","giacche","giorni","giorno","già","gli","gliela","gliele","glieli","glielo","gliene","governo","grande","grazie","gruppo","ha","haha","hai","hanno","ho","i","ieri","il","improvviso","in","inc","infatti","inoltre","insieme","intanto","intorno","invece","io","l","la","lasciato","lato","lavoro","le","lei","li","lo","lontano","loro","lui","lungo","luogo","là","ma","macche","magari","maggior","mai","male","malgrado","malissimo","mancanza","marche","me","medesimo","mediante","meglio","meno","mentre","mesi","mezzo","mi","mia","mie","miei","mila","miliardi","milioni","minimi","ministro","mio","modo","molti","moltissimo","molto","momento","mondo","mosto","nazionale","ne","negl","negli","nei","nel","nell","nella","nelle","nello","nemmeno","neppure","nessun","nessuna","nessuno","niente","no","noi","non","nondimeno","nonostante","nonsia","nostra","nostre","nostri","nostro","novanta","nove","nulla","nuovo","o","od","oggi","ogni","ognuna","ognuno","oltre","oppure","ora","ore","osi","ossia","ottanta","otto","paese","parecchi","parecchie","parecchio","parte","partendo","peccato","peggio","per","perche","perchè","perché","percio","perciò","perfino","pero","persino","persone","però","piedi","pieno","piglia","piu","piuttosto","più","po","pochissimo","poco","poi","poiche","possa","possedere","posteriore","posto","potrebbe","preferibilmente","presa","press","prima","primo","principalmente","probabilmente","proprio","puo","pure","purtroppo","può","qualche","qualcosa","qualcuna","qualcuno","quale","quali","qualunque","quando","quanta","quante","quanti","quanto","quantunque","quasi","quattro","quel","quella","quelle","quelli","quello","quest","questa","queste","questi","questo","qui","quindi","realmente","recente","recentemente","registrazione","relativo","riecco","salvo","sara","sarai","saranno","sarebbe","sarebbero","sarei","saremmo","saremo","sareste","saresti","sarete","sarà","sarò","scola","scopo","scorso","se","secondo","seguente","seguito","sei","sembra","sembrare","sembrato","sembri","sempre","senza","sette","si","sia","siamo","siano","siate","siete","sig","solito","solo","soltanto","sono","sopra","sotto","spesso","srl","sta","stai","stando","stanno","starai","staranno","starebbe","starebbero","starei","staremmo","staremo","stareste","staresti","starete","starà","starò","stata","state","stati","stato","stava","stavamo","stavano","stavate","stavi","stavo","stemmo","stessa","stesse","stessero","stessi","stessimo","stesso","steste","stesti","stette","stettero","stetti","stia","stiamo","stiano","stiate","sto","su","sua","subito","successivamente","successivo","sue","sugl","sugli","sui","sul","sull","sulla","sulle","sullo","suo","suoi","tale","tali","talvolta","tanto","te","tempo","ti","titolo","torino","tra","tranne","tre","trenta","troppo","trovato","tu","tua","tue","tuo","tuoi","tutta","tuttavia","tutte","tutti","tutto","uguali","ulteriore","ultimo","un","una","uno","uomo","va","vale","vari","varia","varie","vario","verso","vi","via","vicino","visto","vita","voi","volta","volte","vostra","vostre","vostri","vostro","è"]
|
|
includes/ext/stopwords-json/dist/ja.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["あっ","あり","ある","い","いう","いる","う","うち","お","および","おり","か","かつて","から","が","き","ここ","こと","この","これ","これら","さ","さらに","し","しかし","する","ず","せ","せる","そして","その","その他","その後","それ","それぞれ","た","ただし","たち","ため","たり","だ","だっ","つ","て","で","でき","できる","です","では","でも","と","という","といった","とき","ところ","として","とともに","とも","と共に","な","ない","なお","なかっ","ながら","なく","なっ","など","なら","なり","なる","に","において","における","について","にて","によって","により","による","に対して","に対する","に関する","の","ので","のみ","は","ば","へ","ほか","ほとんど","ほど","ます","また","または","まで","も","もの","ものの","や","よう","より","ら","られ","られる","れ","れる","を","ん","及び","特に"]
|
|
includes/ext/stopwords-json/dist/ko.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["!","\"","$","%","&","'","(",")","*","+",",","-",".","...","0","1","2","3","4","5","6","7","8","9",";","<","=",">","?","@","\\","^","_","`","|","~","·","—","——","‘","’","“","”","…","、","。","〈","〉","《","》","가","가까스로","가령","각","각각","각자","각종","갖고말하자면","같다","같이","개의치않고","거니와","거바","거의","것","것과 같이","것들","게다가","게우다","겨우","견지에서","결과에 이르다","결국","결론을 낼 수 있다","겸사겸사","고려하면","고로","곧","공동으로","과","과연","관계가 있다","관계없이","관련이 있다","관하여","관한","관해서는","구","구체적으로","구토하다","그","그들","그때","그래","그래도","그래서","그러나","그러니","그러니까","그러면","그러므로","그러한즉","그런 까닭에","그런데","그런즉","그럼","그럼에도 불구하고","그렇게 함으로써","그렇지","그렇지 않다면","그렇지 않으면","그렇지만","그렇지않으면","그리고","그리하여","그만이다","그에 따르는","그위에","그저","그중에서","그치지 않다","근거로","근거하여","기대여","기점으로","기준으로","기타","까닭으로","까악","까지","까지 미치다","까지도","꽈당","끙끙","끼익","나","나머지는","남들","남짓","너","너희","너희들","네","넷","년","논하지 않다","놀라다","누가 알겠는가","누구","다른","다른 방면으로","다만","다섯","다소","다수","다시 말하자면","다시말하면","다음","다음에","다음으로","단지","답다","당신","당장","대로 하다","대하면","대하여","대해 말하자면","대해서","댕그","더구나","더군다나","더라도","더불어","더욱더","더욱이는","도달하다","도착하다","동시에","동안","된바에야","된이상","두번째로","둘","둥둥","뒤따라","뒤이어","든간에","들","등","등등","딩동","따라","따라서","따위","따지지 않다","딱","때","때가 되어","때문에","또","또한","뚝뚝","라 해도","령","로","로 인하여","로부터","로써","륙","를","마음대로","마저","마저도","마치","막론하고","만 못하다","만약","만약에","만은 아니다","만이 아니다","만일","만큼","말하자면","말할것도 없고","매","매번","메쓰겁다","몇","모","모두","무렵","무릎쓰고","무슨","무엇","무엇때문에","물론","및","바꾸어말하면","바꾸어말하자면","바꾸어서 말하면","바꾸어서 한다면","바꿔 말하면","바로","바와같이","밖에 안된다","반대로","반대로 말하자면","반드시","버금","보는데서","보다더","보드득","본대로","봐","봐라","부류의 사람들","부터","불구하고","불문하고","붕붕","비걱거리다","비교적","비길수 없다","비로소","비록","비슷하다","비추어 보아","비하면","뿐만 아니라","뿐만아니라","뿐이다","삐걱","삐걱거리다","사","삼","상대적으로 말하자면","생각한대로","설령","설마","설사","셋","소생","소인","솨","쉿","습니까","습니다","시각","시간","시작하여","시초에","시키다","실로","심지어","아","아니","아니나다를가","아니라면","아니면","아니었다면","아래윗","아무거나","아무도","아야","아울러","아이","아이고","아이구","아이야","아이쿠","아하","아홉","안 그러면","않기 위하여","않기 위해서","알 수 있다","알았어","앗","앞에서","앞의것","야","약간","양자","어","어기여차","어느","어느 년도","어느것","어느곳","어느때","어느쪽","어느해","어디","어때","어떠한","어떤","어떤것","어떤것들","어떻게","어떻해","어이","어째서","어쨋든","어쩔수 없다","어찌","어찌됏든","어찌됏어","어찌하든지","어찌하여","언제","언젠가","얼마","얼마 안 되는 것","얼마간","얼마나","얼마든지","얼마만큼","얼마큼","엉엉","에","에 가서","에 달려 있다","에 대해","에 있다","에 한하다","에게","에서","여","여기","여덟","여러분","여보시오","여부","여섯","여전히","여차","연관되다","연이서","영","영차","옆사람","예","예를 들면","예를 들자면","예컨대","예하면","오","오로지","오르다","오자마자","오직","오호","오히려","와","와 같은 사람들","와르르","와아","왜","왜냐하면","외에도","요만큼","요만한 것","요만한걸","요컨대","우르르","우리","우리들","우선","우에 종합한것과같이","운운","월","위에서 서술한바와같이","위하여","위해서","윙윙","육","으로","으로 인하여","으로서","으로써","을","응","응당","의","의거하여","의지하여","의해","의해되다","의해서","이","이 되다","이 때문에","이 밖에","이 외에","이 정도의","이것","이곳","이때","이라면","이래","이러이러하다","이러한","이런","이럴정도로","이렇게 많은 것","이렇게되면","이렇게말하자면","이렇구나","이로 인하여","이르기까지","이리하여","이만큼","이번","이봐","이상","이어서","이었다","이와 같다","이와 같은","이와 반대로","이와같다면","이외에도","이용하여","이유만으로","이젠","이지만","이쪽","이천구","이천육","이천칠","이천팔","인 듯하다","인젠","일","일것이다","일곱","일단","일때","일반적으로","일지라도","임에 틀림없다","입각하여","입장에서","잇따라","있다","자","자기","자기집","자마자","자신","잠깐","잠시","저","저것","저것만큼","저기","저쪽","저희","전부","전자","전후","점에서 보아","정도에 이르다","제","제각기","제외하고","조금","조차","조차도","졸졸","좀","좋아","좍좍","주룩주룩","주저하지 않고","줄은 몰랏다","줄은모른다","중에서","중의하나","즈음하여","즉","즉시","지든지","지만","지말고","진짜로","쪽으로","차라리","참","참나","첫번째로","쳇","총적으로","총적으로 말하면","총적으로 보면","칠","콸콸","쾅쾅","쿵","타다","타인","탕탕","토하다","통하여","툭","퉤","틈타","팍","팔","퍽","펄렁","하","하게될것이다","하게하다","하겠는가","하고 있다","하고있었다","하곤하였다","하구나","하기 때문에","하기 위하여","하기는한데","하기만 하면","하기보다는","하기에","하나","하느니","하는 김에","하는 편이 낫다","하는것도","하는것만 못하다","하는것이 낫다","하는바","하더라도","하도다","하도록시키다","하도록하다","하든지","하려고하다","하마터면","하면 할수록","하면된다","하면서","하물며","하여금","하여야","하자마자","하지 않는다면","하지 않도록","하지마","하지마라","하지만","하하","한 까닭에","한 이유는","한 후","한다면","한다면 몰라도","한데","한마디","한적이있다","한켠으로는","한항목","할 따름이다","할 생각이다","할 줄 안다","할 지경이다","할 힘이 있다","할때","할만하다","할망정","할뿐","할수있다","할수있어","할줄알다","할지라도","할지언정","함께","해도된다","해도좋다","해봐요","해서는 안된다","해야한다","해요","했어요","향하다","향하여","향해서","허","허걱","허허","헉","헉헉","헐떡헐떡","형식으로 쓰여","혹시","혹은","혼자","훨씬","휘익","휴","흐흐","흥","힘입어","︿","!","#","$","%","&","(",")","*","+",",","0","1","2","3","4","5","6","7","8","9",":",";","<",">","?","@","[","]","{","|","}","~","¥"]
|
|
includes/ext/stopwords-json/dist/la.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","ab","ac","ad","at","atque","aut","autem","cum","de","dum","e","erant","erat","est","et","etiam","ex","haec","hic","hoc","in","ita","me","nec","neque","non","per","qua","quae","quam","qui","quibus","quidem","quo","quod","re","rebus","rem","res","sed","si","sic","sunt","tamen","tandem","te","ut","vel"]
|
|
includes/ext/stopwords-json/dist/lv.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["aiz","ap","apakš","apakšpus","ar","arī","augšpus","bet","bez","bija","biji","biju","bijām","bijāt","būs","būsi","būsiet","būsim","būt","būšu","caur","diemžēl","diezin","droši","dēļ","esam","esat","esi","esmu","gan","gar","iekam","iekams","iekām","iekāms","iekš","iekšpus","ik","ir","it","itin","iz","ja","jau","jeb","jebšu","jel","jo","jā","ka","kamēr","kaut","kolīdz","kopš","kā","kļuva","kļuvi","kļuvu","kļuvām","kļuvāt","kļūs","kļūsi","kļūsiet","kļūsim","kļūst","kļūstam","kļūstat","kļūsti","kļūstu","kļūt","kļūšu","labad","lai","lejpus","līdz","līdzko","ne","nebūt","nedz","nekā","nevis","nezin","no","nu","nē","otrpus","pa","par","pat","pie","pirms","pret","priekš","pār","pēc","starp","tad","tak","tapi","taps","tapsi","tapsiet","tapsim","tapt","tapāt","tapšu","taču","te","tiec","tiek","tiekam","tiekat","tieku","tik","tika","tikai","tiki","tikko","tiklab","tiklīdz","tiks","tiksiet","tiksim","tikt","tiku","tikvien","tikām","tikāt","tikšu","tomēr","topat","turpretim","turpretī","tā","tādēļ","tālab","tāpēc","un","uz","vai","var","varat","varēja","varēji","varēju","varējām","varējāt","varēs","varēsi","varēsiet","varēsim","varēt","varēšu","vien","virs","virspus","vis","viņpus","zem","ārpus","šaipus"]
|
|
includes/ext/stopwords-json/dist/mr.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["अधिक","अनेक","अशी","असलयाचे","असलेल्या","असा","असून","असे","आज","आणि","आता","आपल्या","आला","आली","आले","आहे","आहेत","एक","एका","कमी","करणयात","करून","का","काम","काय","काही","किवा","की","केला","केली","केले","कोटी","गेल्या","घेऊन","जात","झाला","झाली","झाले","झालेल्या","टा","डॉ","तर","तरी","तसेच","ता","ती","तीन","ते","तो","त्या","त्याचा","त्याची","त्याच्या","त्याना","त्यानी","त्यामुळे","त्री","दिली","दोन","न","नाही","निर्ण्य","पण","पम","परयतन","पाटील","म","मात्र","माहिती","मी","मुबी","म्हणजे","म्हणाले","म्हणून","या","याचा","याची","याच्या","याना","यानी","येणार","येत","येथील","येथे","लाख","व","व्यकत","सर्व","सागित्ले","सुरू","हजार","हा","ही","हे","होणार","होत","होता","होती","होते"]
|
|
includes/ext/stopwords-json/dist/nl.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["aan","achte","achter","af","al","alle","alleen","alles","als","ander","anders","beetje","behalve","beide","beiden","ben","beneden","bent","bij","bijna","bijv","blijkbaar","blijken","boven","bv","daar","daardoor","daarin","daarna","daarom","daaruit","dan","dat","de","deden","deed","derde","derhalve","dertig","deze","dhr","die","dit","doe","doen","doet","door","drie","duizend","echter","een","eens","eerst","eerste","eigen","eigenlijk","elk","elke","en","enige","er","erg","ergens","etc","etcetera","even","geen","genoeg","geweest","haar","haarzelf","had","hadden","heb","hebben","hebt","hedden","heeft","heel","hem","hemzelf","hen","het","hetzelfde","hier","hierin","hierna","hierom","hij","hijzelf","hoe","honderd","hun","ieder","iedere","iedereen","iemand","iets","ik","in","inderdaad","intussen","is","ja","je","jij","jijzelf","jou","jouw","jullie","kan","kon","konden","kun","kunnen","kunt","laatst","later","lijken","lijkt","maak","maakt","maakte","maakten","maar","mag","maken","me","meer","meest","meestal","men","met","mevr","mij","mijn","minder","miss","misschien","missen","mits","mocht","mochten","moest","moesten","moet","moeten","mogen","mr","mrs","mw","na","naar","nam","namelijk","nee","neem","negen","nemen","nergens","niemand","niet","niets","niks","noch","nochtans","nog","nooit","nu","nv","of","om","omdat","ondanks","onder","ondertussen","ons","onze","onzeker","ooit","ook","op","over","overal","overige","paar","per","recent","redelijk","samen","sinds","steeds","te","tegen","tegenover","thans","tien","tiende","tijdens","tja","toch","toe","tot","totdat","tussen","twee","tweede","u","uit","uw","vaak","van","vanaf","veel","veertig","verder","verscheidene","verschillende","via","vier","vierde","vijf","vijfde","vijftig","volgend","volgens","voor","voordat","voorts","waar","waarom","waarschijnlijk","wanneer","waren","was","wat","we","wederom","weer","weinig","wel","welk","welke","werd","werden","werder","whatever","wie","wij","wijzelf","wil","wilden","willen","word","worden","wordt","zal","ze","zei","zeker","zelf","zelfde","zes","zeven","zich","zij","zijn","zijzelf","zo","zoals","zodat","zou","zouden","zulk","zullen"]
|
|
includes/ext/stopwords-json/dist/no.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["alle","at","av","bare","begge","ble","blei","bli","blir","blitt","både","båe","da","de","deg","dei","deim","deira","deires","dem","den","denne","der","dere","deres","det","dette","di","din","disse","ditt","du","dykk","dykkar","då","eg","ein","eit","eitt","eller","elles","en","enn","er","et","ett","etter","for","fordi","fra","før","ha","hadde","han","hans","har","hennar","henne","hennes","her","hjå","ho","hoe","honom","hoss","hossen","hun","hva","hvem","hver","hvilke","hvilken","hvis","hvor","hvordan","hvorfor","i","ikke","ikkje","ingen","ingi","inkje","inn","inni","ja","jeg","kan","kom","korleis","korso","kun","kunne","kva","kvar","kvarhelst","kven","kvi","kvifor","man","mange","me","med","medan","meg","meget","mellom","men","mi","min","mine","mitt","mot","mykje","ned","no","noe","noen","noka","noko","nokon","nokor","nokre","nå","når","og","også","om","opp","oss","over","på","samme","seg","selv","si","sia","sidan","siden","sin","sine","sitt","sjøl","skal","skulle","slik","so","som","somme","somt","så","sånn","til","um","upp","ut","uten","var","vart","varte","ved","vere","verte","vi","vil","ville","vore","vors","vort","vår","være","vært","å"]
|
|
includes/ext/stopwords-json/dist/pl.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["aby","ach","aj","albo","ale","ani","aż","bardzo","bez","bo","bowiem","by","byli","bym","być","był","była","było","były","będzie","będą","chce","choć","ci","ciebie","cię","co","coraz","coś","czy","czyli","często","daleko","dla","dlaczego","dlatego","do","dobrze","dokąd","dość","dr","dużo","dwa","dwaj","dwie","dwoje","dzisiaj","dziś","gdy","gdyby","gdyż","gdzie","go","godz","hab","i","ich","ii","iii","ile","im","inne","inny","inż","iv","ix","iż","ja","jak","jakby","jaki","jakie","jako","je","jeden","jedna","jednak","jedno","jednym","jedynie","jego","jej","jemu","jest","jestem","jeszcze","jeśli","jeżeli","już","ją","każdy","kiedy","kierunku","kilku","kto","która","które","którego","której","który","których","którym","którzy","ku","lat","lecz","lub","ma","mają","mam","mamy","mgr","mi","miał","mimo","mnie","mną","mogą","moi","moja","moje","może","można","mu","musi","my","mój","na","nad","nam","nami","nas","nasi","nasz","nasza","nasze","natychmiast","nawet","nic","nich","nie","niego","niej","niemu","nigdy","nim","nimi","nią","niż","no","nowe","np","nr","o","o.o.","obok","od","ok","około","on","ona","one","oni","ono","oraz","owszem","pan","pl","po","pod","ponad","ponieważ","poza","prof","przed","przede","przedtem","przez","przy","raz","razie","roku","również","sam","sama","się","skąd","sobie","sposób","swoje","są","ta","tak","taki","takich","takie","także","tam","te","tego","tej","tel","temu","ten","teraz","też","to","tobie","tobą","trzeba","tu","tutaj","twoi","twoja","twoje","twój","ty","tych","tylko","tym","tys","tzw","tę","u","ul","vi","vii","viii","vol","w","wam","wami","was","wasi","wasz","wasza","wasze","we","wie","więc","wszystko","wtedy","www","wy","właśnie","wśród","xi","xii","xiii","xiv","xv","z","za","zawsze","zaś","ze","zł","żaden","że","żeby"]
|
|
includes/ext/stopwords-json/dist/pt.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","acerca","adeus","agora","ainda","algmas","algo","algumas","alguns","ali","além","ambos","ano","anos","antes","ao","aos","apenas","apoio","apontar","após","aquela","aquelas","aquele","aqueles","aqui","aquilo","as","assim","através","atrás","até","aí","baixo","bastante","bem","bom","breve","cada","caminho","catorze","cedo","cento","certamente","certeza","cima","cinco","coisa","com","como","comprido","conhecido","conselho","contra","corrente","custa","cá","da","daquela","daquele","dar","das","de","debaixo","demais","dentro","depois","desde","desligado","dessa","desse","desta","deste","deve","devem","deverá","dez","dezanove","dezasseis","dezassete","dezoito","dia","diante","direita","diz","dizem","dizer","do","dois","dos","doze","duas","dá","dão","dúvida","e","ela","elas","ele","eles","em","embora","enquanto","entre","então","era","essa","essas","esse","esses","esta","estado","estar","estará","estas","estava","este","estes","esteve","estive","estivemos","estiveram","estiveste","estivestes","estou","está","estás","estão","eu","exemplo","falta","fará","favor","faz","fazeis","fazem","fazemos","fazer","fazes","fazia","faço","fez","fim","final","foi","fomos","for","fora","foram","forma","foste","fostes","fui","geral","grande","grandes","grupo","hoje","horas","há","iniciar","inicio","ir","irá","isso","ista","iste","isto","já","lado","ligado","local","logo","longe","lugar","lá","maior","maioria","maiorias","mais","mal","mas","me","meio","menor","menos","meses","mesmo","meu","meus","mil","minha","minhas","momento","muito","muitos","máximo","mês","na","nada","naquela","naquele","nas","nem","nenhuma","nessa","nesse","nesta","neste","no","noite","nome","nos","nossa","nossas","nosso","nossos","nova","nove","novo","novos","num","numa","nunca","não","nível","nós","número","o","obra","obrigada","obrigado","oitava","oitavo","oito","onde","ontem","onze","os","ou","outra","outras","outro","outros","para","parece","parte","partir","pegar","pela","pelas","pelo","pelos","perto","pessoas","pode","podem","poder","poderá","podia","ponto","pontos","por","porque","porquê","posição","possivelmente","posso","possível","pouca","pouco","povo","primeira","primeiro","promeiro","próprio","próximo","puderam","pôde","põe","põem","qual","qualquer","quando","quanto","quarta","quarto","quatro","que","quem","quer","quero","questão","quieto","quinta","quinto","quinze","quê","relação","sabe","saber","se","segunda","segundo","sei","seis","sem","sempre","ser","seria","sete","seu","seus","sexta","sexto","sim","sistema","sob","sobre","sois","somente","somos","sou","sua","suas","são","sétima","sétimo","tal","talvez","também","tanto","tarde","te","tem","temos","tempo","tendes","tenho","tens","tentar","tentaram","tente","tentei","ter","terceira","terceiro","teu","teus","teve","tipo","tive","tivemos","tiveram","tiveste","tivestes","toda","todas","todo","todos","trabalhar","trabalho","treze","três","tu","tua","tuas","tudo","tão","têm","um","uma","umas","uns","usa","usar","vai","vais","valor","veja","vem","vens","ver","verdade","verdadeiro","vez","vezes","viagem","vindo","vinte","você","vocês","vos","vossa","vossas","vosso","vossos","vários","vão","vêm","vós","zero","à","às","área","é","és","último"]
|
|
includes/ext/stopwords-json/dist/ro.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["acea","aceasta","această","aceea","acei","aceia","acel","acela","acele","acelea","acest","acesta","aceste","acestea","aceşti","aceştia","acolo","acord","acum","ai","aia","aibă","aici","al","ale","alea","altceva","altcineva","am","ar","are","asemenea","asta","astea","astăzi","asupra","au","avea","avem","aveţi","azi","aş","aşadar","aţi","bine","bucur","bună","ca","care","caut","ce","cel","ceva","chiar","cinci","cine","cineva","contra","cu","cum","cumva","curând","curînd","când","cât","câte","câtva","câţi","cînd","cît","cîte","cîtva","cîţi","că","căci","cărei","căror","cărui","către","da","dacă","dar","datorită","dată","dau","de","deci","deja","deoarece","departe","deşi","din","dinaintea","dintr-","dintre","doi","doilea","două","drept","după","dă","ea","ei","el","ele","eram","este","eu","eşti","face","fata","fi","fie","fiecare","fii","fim","fiu","fiţi","frumos","fără","graţie","halbă","iar","ieri","la","le","li","lor","lui","lângă","lîngă","mai","mea","mei","mele","mereu","meu","mi","mie","mine","mult","multă","mulţi","mulţumesc","mâine","mîine","mă","ne","nevoie","nici","nicăieri","nimeni","nimeri","nimic","nişte","noastre","noastră","noi","noroc","nostru","nouă","noştri","nu","opt","ori","oricare","orice","oricine","oricum","oricând","oricât","oricînd","oricît","oriunde","patra","patru","patrulea","pe","pentru","peste","pic","poate","pot","prea","prima","primul","prin","printr-","puţin","puţina","puţină","până","pînă","rog","sa","sale","sau","se","spate","spre","sub","sunt","suntem","sunteţi","sută","sînt","sîntem","sînteţi","să","săi","său","ta","tale","te","timp","tine","toate","toată","tot","totuşi","toţi","trei","treia","treilea","tu","tăi","tău","un","una","unde","undeva","unei","uneia","unele","uneori","unii","unor","unora","unu","unui","unuia","unul","vi","voastre","voastră","voi","vostru","vouă","voştri","vreme","vreo","vreun","vă","zece","zero","zi","zice","îi","îl","îmi","împotriva","în","înainte","înaintea","încotro","încât","încît","între","întrucât","întrucît","îţi","ăla","ălea","ăsta","ăstea","ăştia","şapte","şase","şi","ştiu","ţi","ţie"]
|
|
includes/ext/stopwords-json/dist/ru.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["а","алло","без","белый","близко","более","больше","большой","будем","будет","будете","будешь","будто","буду","будут","будь","бы","бывает","бывь","был","была","были","было","быть","в","важная","важное","важные","важный","вам","вами","вас","ваш","ваша","ваше","ваши","вверх","вдали","вдруг","ведь","везде","вернуться","весь","вечер","взгляд","взять","вид","видеть","вместе","вниз","внизу","во","вода","война","вокруг","вон","вообще","вопрос","восемнадцатый","восемнадцать","восемь","восьмой","вот","впрочем","времени","время","все","всегда","всего","всем","всеми","всему","всех","всею","всю","всюду","вся","всё","второй","вы","выйти","г","где","главный","глаз","говорил","говорит","говорить","год","года","году","голова","голос","город","да","давать","давно","даже","далекий","далеко","дальше","даром","дать","два","двадцатый","двадцать","две","двенадцатый","двенадцать","дверь","двух","девятнадцатый","девятнадцать","девятый","девять","действительно","дел","делать","дело","день","деньги","десятый","десять","для","до","довольно","долго","должно","должный","дом","дорога","друг","другая","другие","других","друго","другое","другой","думать","душа","е","его","ее","ей","ему","если","есть","еще","ещё","ею","её","ж","ждать","же","жена","женщина","жизнь","жить","за","занят","занята","занято","заняты","затем","зато","зачем","здесь","земля","знать","значит","значить","и","идти","из","или","им","именно","иметь","ими","имя","иногда","их","к","каждая","каждое","каждые","каждый","кажется","казаться","как","какая","какой","кем","книга","когда","кого","ком","комната","кому","конец","конечно","которая","которого","которой","которые","который","которых","кроме","кругом","кто","куда","лежать","лет","ли","лицо","лишь","лучше","любить","люди","м","маленький","мало","мать","машина","между","меля","менее","меньше","меня","место","миллионов","мимо","минута","мир","мира","мне","много","многочисленная","многочисленное","многочисленные","многочисленный","мной","мною","мог","могут","мож","может","можно","можхо","мои","мой","мор","москва","мочь","моя","моё","мы","на","наверху","над","надо","назад","наиболее","найти","наконец","нам","нами","народ","нас","начала","начать","наш","наша","наше","наши","не","него","недавно","недалеко","нее","ней","некоторый","нельзя","нем","немного","нему","непрерывно","нередко","несколько","нет","нею","неё","ни","нибудь","ниже","низко","никакой","никогда","никто","никуда","ними","них","ничего","ничто","но","новый","нога","ночь","ну","нужно","нужный","нх","о","об","оба","обычно","один","одиннадцатый","одиннадцать","однажды","однако","одного","одной","оказаться","окно","около","он","она","они","оно","опять","особенно","остаться","от","ответить","отец","отовсюду","отсюда","очень","первый","перед","писать","плечо","по","под","подумать","пожалуйста","позже","пойти","пока","пол","получить","помнить","понимать","понять","пор","пора","после","последний","посмотреть","посреди","потом","потому","почему","почти","правда","прекрасно","при","про","просто","против","процентов","пятнадцатый","пятнадцать","пятый","пять","работа","работать","раз","разве","рано","раньше","ребенок","решить","россия","рука","русский","ряд","рядом","с","сам","сама","сами","самим","самими","самих","само","самого","самой","самом","самому","саму","самый","свет","свое","своего","своей","свои","своих","свой","свою","сделать","сеаой","себе","себя","сегодня","седьмой","сейчас","семнадцатый","семнадцать","семь","сидеть","сила","сих","сказал","сказала","сказать","сколько","слишком","слово","случай","смотреть","сначала","снова","со","собой","собою","советский","совсем","спасибо","спросить","сразу","стал","старый","стать","стол","сторона","стоять","страна","суть","считать","т","та","так","такая","также","таки","такие","такое","такой","там","твой","твоя","твоё","те","тебе","тебя","тем","теми","теперь","тех","то","тобой","тобою","товарищ","тогда","того","тоже","только","том","тому","тот","тою","третий","три","тринадцатый","тринадцать","ту","туда","тут","ты","тысяч","у","увидеть","уж","уже","улица","уметь","утро","хороший","хорошо","хотеть","хоть","хотя","хочешь","час","часто","часть","чаще","чего","человек","чем","чему","через","четвертый","четыре","четырнадцатый","четырнадцать","что","чтоб","чтобы","чуть","шестнадцатый","шестнадцать","шестой","шесть","эта","эти","этим","этими","этих","это","этого","этой","этом","этому","этот","эту","я"]
|
|
includes/ext/stopwords-json/dist/sk.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","aby","aj","ako","aký","ale","alebo","ani","avšak","ba","bez","buï","cez","do","ho","hoci","i","ich","im","ja","jeho","jej","jemu","ju","k","kam","kde","kedže","keï","kto","ktorý","ku","lebo","ma","mi","mne","mnou","mu","my","mòa","môj","na","nad","nami","neho","nej","nemu","nich","nielen","nim","no","nám","nás","náš","ním","o","od","on","ona","oni","ono","ony","po","pod","pre","pred","pri","s","sa","seba","sem","so","svoj","taký","tam","teba","tebe","tebou","tej","ten","ti","tie","to","toho","tomu","tou","tvoj","ty","tá","tým","v","vami","veï","vo","vy","vám","vás","váš","však","z","za","zo","a","èi","èo","èí","òom","òou","òu","že"]
|
|
includes/ext/stopwords-json/dist/sl.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","ali","april","avgust","b","bi","bil","bila","bile","bili","bilo","biti","blizu","bo","bodo","bojo","bolj","bom","bomo","boste","bova","boš","brez","c","cel","cela","celi","celo","d","da","daleč","dan","danes","datum","december","deset","deseta","deseti","deseto","devet","deveta","deveti","deveto","do","dober","dobra","dobri","dobro","dokler","dol","dolg","dolga","dolgi","dovolj","drug","druga","drugi","drugo","dva","dve","e","eden","en","ena","ene","eni","enkrat","eno","etc.","f","februar","g","g.","ga","ga.","gor","gospa","gospod","h","halo","i","idr.","ii","iii","in","iv","ix","iz","j","januar","jaz","je","ji","jih","jim","jo","julij","junij","jutri","k","kadarkoli","kaj","kajti","kako","kakor","kamor","kamorkoli","kar","karkoli","katerikoli","kdaj","kdo","kdorkoli","ker","ki","kje","kjer","kjerkoli","ko","koder","koderkoli","koga","komu","kot","kratek","kratka","kratke","kratki","l","lahka","lahke","lahki","lahko","le","lep","lepa","lepe","lepi","lepo","leto","m","maj","majhen","majhna","majhni","malce","malo","manj","marec","me","med","medtem","mene","mesec","mi","midva","midve","mnogo","moj","moja","moje","mora","morajo","moram","moramo","morate","moraš","morem","mu","n","na","nad","naj","najina","najino","najmanj","naju","največ","nam","narobe","nas","nato","nazaj","naš","naša","naše","ne","nedavno","nedelja","nek","neka","nekaj","nekatere","nekateri","nekatero","nekdo","neke","nekega","neki","nekje","neko","nekoga","nekoč","ni","nikamor","nikdar","nikjer","nikoli","nič","nje","njega","njegov","njegova","njegovo","njej","njemu","njen","njena","njeno","nji","njih","njihov","njihova","njihovo","njiju","njim","njo","njun","njuna","njuno","no","nocoj","november","npr.","o","ob","oba","obe","oboje","od","odprt","odprta","odprti","okoli","oktober","on","onadva","one","oni","onidve","osem","osma","osmi","osmo","oz.","p","pa","pet","peta","petek","peti","peto","po","pod","pogosto","poleg","poln","polna","polni","polno","ponavadi","ponedeljek","ponovno","potem","povsod","pozdravljen","pozdravljeni","prav","prava","prave","pravi","pravo","prazen","prazna","prazno","prbl.","precej","pred","prej","preko","pri","pribl.","približno","primer","pripravljen","pripravljena","pripravljeni","proti","prva","prvi","prvo","r","ravno","redko","res","reč","s","saj","sam","sama","same","sami","samo","se","sebe","sebi","sedaj","sedem","sedma","sedmi","sedmo","sem","september","seveda","si","sicer","skoraj","skozi","slab","smo","so","sobota","spet","sreda","srednja","srednji","sta","ste","stran","stvar","sva","t","ta","tak","taka","take","taki","tako","takoj","tam","te","tebe","tebi","tega","težak","težka","težki","težko","ti","tista","tiste","tisti","tisto","tj.","tja","to","toda","torek","tretja","tretje","tretji","tri","tu","tudi","tukaj","tvoj","tvoja","tvoje","u","v","vaju","vam","vas","vaš","vaša","vaše","ve","vedno","velik","velika","veliki","veliko","vendar","ves","več","vi","vidva","vii","viii","visok","visoka","visoke","visoki","vsa","vsaj","vsak","vsaka","vsakdo","vsake","vsaki","vsakomur","vse","vsega","vsi","vso","včasih","včeraj","x","z","za","zadaj","zadnji","zakaj","zaprta","zaprti","zaprto","zdaj","zelo","zunaj","č","če","često","četrta","četrtek","četrti","četrto","čez","čigav","š","šest","šesta","šesti","šesto","štiri","ž","že"]
|
|
includes/ext/stopwords-json/dist/so.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["aad","albaabkii","atabo","ay","ayaa","ayee","ayuu","dhan","hadana","in","inuu","isku","jiray","jirtay","ka","kale","kasoo","ku","kuu","lakin","markii","oo","si","soo","uga","ugu","uu","waa","waxa","waxuu"]
|
|
includes/ext/stopwords-json/dist/st.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","ba","bane","bona","e","ea","eaba","empa","ena","ha","hae","hape","ho","hore","ka","ke","la","le","li","me","mo","moo","ne","o","oa","re","sa","se","tloha","tsa","tse"]
|
|
includes/ext/stopwords-json/dist/sv.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["aderton","adertonde","adjö","aldrig","alla","allas","allt","alltid","alltså","andra","andras","annan","annat","artonde","artonn","att","av","bakom","bara","behöva","behövas","behövde","behövt","beslut","beslutat","beslutit","bland","blev","bli","blir","blivit","bort","borta","bra","bäst","bättre","båda","bådas","dag","dagar","dagarna","dagen","de","del","delen","dem","den","denna","deras","dess","dessa","det","detta","dig","din","dina","dit","ditt","dock","du","där","därför","då","efter","eftersom","ej","elfte","eller","elva","en","enkel","enkelt","enkla","enligt","er","era","ert","ett","ettusen","fanns","fem","femte","femtio","femtionde","femton","femtonde","fick","fin","finnas","finns","fjorton","fjortonde","fjärde","fler","flera","flesta","fram","framför","från","fyra","fyrtio","fyrtionde","få","får","fått","följande","för","före","förlåt","förra","första","genast","genom","gick","gjorde","gjort","god","goda","godare","godast","gott","gälla","gäller","gällt","gärna","gå","går","gått","gör","göra","ha","hade","haft","han","hans","har","heller","hellre","helst","helt","henne","hennes","hit","hon","honom","hundra","hundraen","hundraett","hur","här","hög","höger","högre","högst","i","ibland","icke","idag","igen","igår","imorgon","in","inför","inga","ingen","ingenting","inget","innan","inne","inom","inte","inuti","ja","jag","ju","jämfört","kan","kanske","knappast","kom","komma","kommer","kommit","kr","kunde","kunna","kunnat","kvar","legat","ligga","ligger","lika","likställd","likställda","lilla","lite","liten","litet","länge","längre","längst","lätt","lättare","lättast","långsam","långsammare","långsammast","långsamt","långt","man","med","mellan","men","mer","mera","mest","mig","min","mina","mindre","minst","mitt","mittemot","mot","mycket","många","måste","möjlig","möjligen","möjligt","möjligtvis","ned","nederst","nedersta","nedre","nej","ner","ni","nio","nionde","nittio","nittionde","nitton","nittonde","nog","noll","nr","nu","nummer","när","nästa","någon","någonting","något","några","nödvändig","nödvändiga","nödvändigt","nödvändigtvis","och","också","ofta","oftast","olika","olikt","om","oss","på","rakt","redan","rätt","sade","sagt","samma","sedan","senare","senast","sent","sex","sextio","sextionde","sexton","sextonde","sig","sin","sina","sist","sista","siste","sitt","sitta","sju","sjunde","sjuttio","sjuttionde","sjutton","sjuttonde","själv","sjätte","ska","skall","skulle","slutligen","små","smått","snart","som","stor","stora","stort","större","störst","säga","säger","sämre","sämst","så","sådan","sådana","sådant","tack","tidig","tidigare","tidigast","tidigt","till","tills","tillsammans","tio","tionde","tjugo","tjugoen","tjugoett","tjugonde","tjugotre","tjugotvå","tjungo","tolfte","tolv","tre","tredje","trettio","trettionde","tretton","trettonde","två","tvåhundra","under","upp","ur","ursäkt","ut","utan","utanför","ute","vad","var","vara","varför","varifrån","varit","varje","varken","vars","varsågod","vart","vem","vems","verkligen","vi","vid","vidare","viktig","viktigare","viktigast","viktigt","vilka","vilkas","vilken","vilket","vill","vänster","vänstra","värre","vår","våra","vårt","än","ännu","är","även","åt","åtminstone","åtta","åttio","åttionde","åttonde","över","övermorgon","överst","övre"]
|
|
includes/ext/stopwords-json/dist/sw.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["akasema","alikuwa","alisema","baada","basi","bila","cha","chini","hadi","hapo","hata","hivyo","hiyo","huku","huo","ili","ilikuwa","juu","kama","karibu","katika","kila","kima","kisha","kubwa","kutoka","kuwa","kwa","kwamba","kwenda","kwenye","la","lakini","mara","mdogo","mimi","mkubwa","mmoja","moja","muda","mwenye","na","naye","ndani","ng","ni","nini","nonkungu","pamoja","pia","sana","sasa","sauti","tafadhali","tena","tu","vile","wa","wakati","wake","walikuwa","wao","watu","wengine","wote","ya","yake","yangu","yao","yeye","yule","za","zaidi","zake"]
|
|
includes/ext/stopwords-json/dist/th.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["กล่าว","กว่า","กัน","กับ","การ","ก็","ก่อน","ขณะ","ขอ","ของ","ขึ้น","คง","ครั้ง","ความ","คือ","จะ","จัด","จาก","จึง","ช่วง","ซึ่ง","ดัง","ด้วย","ด้าน","ตั้ง","ตั้งแต่","ตาม","ต่อ","ต่าง","ต่างๆ","ต้อง","ถึง","ถูก","ถ้า","ทั้ง","ทั้งนี้","ทาง","ที่","ที่สุด","ทุก","ทํา","ทําให้","นอกจาก","นัก","นั้น","นี้","น่า","นํา","บาง","ผล","ผ่าน","พบ","พร้อม","มา","มาก","มี","ยัง","รวม","ระหว่าง","รับ","ราย","ร่วม","ลง","วัน","ว่า","สุด","ส่ง","ส่วน","สําหรับ","หนึ่ง","หรือ","หลัง","หลังจาก","หลาย","หาก","อยาก","อยู่","อย่าง","ออก","อะไร","อาจ","อีก","เขา","เข้า","เคย","เฉพาะ","เช่น","เดียว","เดียวกัน","เนื่องจาก","เปิด","เปิดเผย","เป็น","เป็นการ","เพราะ","เพื่อ","เมื่อ","เรา","เริ่ม","เลย","เห็น","เอง","แต่","แบบ","แรก","และ","แล้ว","แห่ง","โดย","ใน","ให้","ได้","ไป","ไม่","ไว้"]
|
|
includes/ext/stopwords-json/dist/tr.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["acaba","acep","adeta","altmýþ","altmış","altý","altı","ama","ancak","arada","artýk","aslında","aynen","ayrıca","az","bana","bari","bazen","bazý","bazı","baţka","belki","ben","benden","beni","benim","beri","beþ","beş","beţ","bile","bin","bir","biraz","biri","birkaç","birkez","birçok","birþey","birþeyi","birşey","birşeyi","birţey","biz","bizden","bize","bizi","bizim","bu","buna","bunda","bundan","bunlar","bunları","bunların","bunu","bunun","burada","böyle","böylece","bütün","da","daha","dahi","dahil","daima","dair","dayanarak","de","defa","deđil","değil","diye","diđer","diğer","doksan","dokuz","dolayı","dolayısıyla","dört","edecek","eden","ederek","edilecek","ediliyor","edilmesi","ediyor","elli","en","etmesi","etti","ettiği","ettiğini","eđer","eğer","fakat","gibi","göre","halbuki","halen","hangi","hani","hariç","hatta","hele","hem","henüz","hep","hepsi","her","herhangi","herkes","herkesin","hiç","hiçbir","iken","iki","ila","ile","ilgili","ilk","illa","ise","itibaren","itibariyle","iyi","iyice","için","işte","iţte","kadar","kanýmca","karşın","katrilyon","kendi","kendilerine","kendini","kendisi","kendisine","kendisini","kere","kez","keţke","ki","kim","kimden","kime","kimi","kimse","kýrk","kýsaca","kırk","lakin","madem","međer","milyar","milyon","mu","mü","mý","mı","nasýl","nasıl","ne","neden","nedenle","nerde","nere","nerede","nereye","nitekim","niye","niçin","o","olan","olarak","oldu","olduklarını","olduğu","olduğunu","olmadı","olmadığı","olmak","olması","olmayan","olmaz","olsa","olsun","olup","olur","olursa","oluyor","on","ona","ondan","onlar","onlardan","onlari","onlarýn","onları","onların","onu","onun","otuz","oysa","pek","rağmen","sadece","sanki","sekiz","seksen","sen","senden","seni","senin","siz","sizden","sizi","sizin","sonra","tarafından","trilyon","tüm","var","vardı","ve","veya","veyahut","ya","yahut","yani","yapacak","yapmak","yaptı","yaptıkları","yaptığı","yaptığını","yapılan","yapılması","yapıyor","yedi","yerine","yetmiþ","yetmiş","yetmiţ","yine","yirmi","yoksa","yüz","zaten","çok","çünkü","öyle","üzere","üç","þey","þeyden","þeyi","þeyler","þu","þuna","þunda","þundan","þunu","şey","şeyden","şeyi","şeyler","şu","şuna","şunda","şundan","şunları","şunu","şöyle","ţayet","ţimdi","ţu","ţöyle"]
|
|
includes/ext/stopwords-json/dist/yo.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["a","an","bá","bí","bẹ̀rẹ̀","fún","fẹ́","gbogbo","inú","jù","jẹ","jẹ́","kan","kì","kí","kò","láti","lè","lọ","mi","mo","máa","mọ̀","ni","náà","ní","nígbà","nítorí","nǹkan","o","padà","pé","púpọ̀","pẹ̀lú","rẹ̀","sì","sí","sínú","ṣ","ti","tí","wà","wá","wọn","wọ́n","yìí","àti","àwọn","é","í","òun","ó","ń","ńlá","ṣe","ṣé","ṣùgbọ́n","ẹmọ́","ọjọ́","ọ̀pọ̀lọpọ̀"]
|
|
includes/ext/stopwords-json/dist/zh.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["、","。","〈","〉","《","》","一","一切","一则","一方面","一旦","一来","一样","一般","七","万一","三","上下","不仅","不但","不光","不单","不只","不如","不怕","不惟","不成","不拘","不比","不然","不特","不独","不管","不论","不过","不问","与","与其","与否","与此同时","且","两者","个","临","为","为了","为什么","为何","为着","乃","乃至","么","之","之一","之所以","之类","乌乎","乎","乘","九","也","也好","也罢","了","二","于","于是","于是乎","云云","五","人家","什么","什么样","从","从而","他","他人","他们","以","以便","以免","以及","以至","以至于","以致","们","任","任何","任凭","似的","但","但是","何","何况","何处","何时","作为","你","你们","使得","例如","依","依照","俺","俺们","倘","倘使","倘或","倘然","倘若","借","假使","假如","假若","像","八","六","兮","关于","其","其一","其中","其二","其他","其余","其它","其次","具体地说","具体说来","再者","再说","冒","冲","况且","几","几时","凭","凭借","则","别","别的","别说","到","前后","前者","加之","即","即令","即使","即便","即或","即若","又","及","及其","及至","反之","反过来","反过来说","另","另一方面","另外","只是","只有","只要","只限","叫","叮咚","可","可以","可是","可见","各","各个","各位","各种","各自","同","同时","向","向着","吓","吗","否则","吧","吧哒","吱","呀","呃","呕","呗","呜","呜呼","呢","呵","呸","呼哧","咋","和","咚","咦","咱","咱们","咳","哇","哈","哈哈","哉","哎","哎呀","哎哟","哗","哟","哦","哩","哪","哪个","哪些","哪儿","哪天","哪年","哪怕","哪样","哪边","哪里","哼","哼唷","唉","啊","啐","啥","啦","啪达","喂","喏","喔唷","嗡嗡","嗬","嗯","嗳","嘎","嘎登","嘘","嘛","嘻","嘿","四","因","因为","因此","因而","固然","在","在下","地","多","多少","她","她们","如","如上所述","如何","如其","如果","如此","如若","宁","宁可","宁愿","宁肯","它","它们","对","对于","将","尔后","尚且","就","就是","就是说","尽","尽管","岂但","己","并","并且","开外","开始","归","当","当着","彼","彼此","往","待","得","怎","怎么","怎么办","怎么样","怎样","总之","总的来看","总的来说","总的说来","总而言之","恰恰相反","您","慢说","我","我们","或","或是","或者","所","所以","打","把","抑或","拿","按","按照","换句话说","换言之","据","接着","故","故此","旁人","无宁","无论","既","既是","既然","时候","是","是的","替","有","有些","有关","有的","望","朝","朝着","本","本着","来","来着","极了","果然","果真","某","某个","某些","根据","正如","此","此外","此间","毋宁","每","每当","比","比如","比方","沿","沿着","漫说","焉","然则","然后","然而","照","照着","甚么","甚而","甚至","用","由","由于","由此可见","的","的话","相对而言","省得","着","着呢","矣","离","第","等","等等","管","紧接着","纵","纵令","纵使","纵然","经","经过","结果","给","继而","综上所述","罢了","者","而","而且","而况","而外","而已","而是","而言","能","腾","自","自个儿","自从","自各儿","自家","自己","自身","至","至于","若","若是","若非","莫若","虽","虽则","虽然","虽说","被","要","要不","要不是","要不然","要么","要是","让","论","设使","设若","该","诸位","谁","谁知","赶","起","起见","趁","趁着","越是","跟","较","较之","边","过","还是","还有","这","这个","这么","这么些","这么样","这么点儿","这些","这会儿","这儿","这就是说","这时","这样","这边","这里","进而","连","连同","通过","遵照","那","那个","那么","那么些","那么样","那些","那会儿","那儿","那时","那样","那边","那里","鄙人","鉴于","阿","除","除了","除此之外","除非","随","随着","零","非但","非徒","靠","顺","顺着","首先","︿","!","#","$","%","&","(",")","*","+",",","0","1","2","3","4","5","6","7","8","9",":",";","<",">","?","@","[","]","{","|","}","~","¥"]
|
|
includes/ext/stopwords-json/dist/zu.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
["futhi","kahle","kakhulu","kanye","khona","kodwa","kungani","kusho","la","lakhe","lapho","mina","ngesikhathi","nje","phansi","phezulu","u","ukuba","ukuthi","ukuze","uma","wahamba","wakhe","wami","wase","wathi","yakhe","zakhe","zonke"]
|
|
includes/views/permalink-manager-pro-addons.php
DELETED
@@ -1,285 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Display the page where the slugs could be regenerated or replaced
|
5 |
-
*/
|
6 |
-
class Permalink_Manager_Pro_Addons extends Permalink_Manager_Class {
|
7 |
-
|
8 |
-
public function __construct() {
|
9 |
-
add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 2 );
|
10 |
-
add_filter( 'permalink-manager-permastructs-fields', array($this, 'filter_permastructure_fields'), 9 );
|
11 |
-
add_filter( 'permalink-manager-tools-fields', array($this, 'filter_tools_fields'), 9, 2 );
|
12 |
-
add_filter( 'permalink-manager-settings-fields', array($this, 'filter_settings_fields'), 9 );
|
13 |
-
|
14 |
-
// Stop Words
|
15 |
-
add_action( 'admin_init', array($this, 'save_stop_words'), 9 );
|
16 |
-
}
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Permastructures tab
|
20 |
-
*/
|
21 |
-
public function filter_permastructure_fields($fields) {
|
22 |
-
global $permalink_manager_permastructs;
|
23 |
-
|
24 |
-
$taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array('full');
|
25 |
-
|
26 |
-
foreach($taxonomies as $taxonomy) {
|
27 |
-
$taxonomy_name = $taxonomy['name'];
|
28 |
-
|
29 |
-
// Check if taxonomy exists
|
30 |
-
if(!taxonomy_exists($taxonomy_name)) { continue; }
|
31 |
-
|
32 |
-
$default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($taxonomy_name, true);
|
33 |
-
$current_permastruct = isset($permalink_manager_permastructs['taxonomies'][$taxonomy_name]) ? $permalink_manager_permastructs['taxonomies'][$taxonomy_name] : $default_permastruct;
|
34 |
-
|
35 |
-
$fields["taxonomies"]["fields"][$taxonomy_name] = array(
|
36 |
-
'label' => $taxonomy['label'],
|
37 |
-
'container' => 'row',
|
38 |
-
'input_class' => 'permastruct-field',
|
39 |
-
'after_description' => Permalink_Manager_Permastructs::restore_default_row($default_permastruct),
|
40 |
-
'extra_atts' => "data-default=\"{$default_permastruct}\"",
|
41 |
-
'value' => $current_permastruct,
|
42 |
-
'placeholder' => $default_permastruct,
|
43 |
-
'type' => 'permastruct'
|
44 |
-
);
|
45 |
-
}
|
46 |
-
|
47 |
-
// Separate WooCommerce CPT & custom taxonomies
|
48 |
-
if(class_exists('WooCommerce')) {
|
49 |
-
$woocommerce_fields = array('product' => 'post_types', 'product_tag' => 'taxonomies', 'product_cat' => 'taxonomies');
|
50 |
-
|
51 |
-
foreach($woocommerce_fields as $field => $field_type) {
|
52 |
-
$fields["woocommerce"]["fields"][$field] = $fields[$field_type]["fields"][$field];
|
53 |
-
$fields["woocommerce"]["fields"][$field]["name"] = "{$field_type}[{$field}]";
|
54 |
-
unset($fields[$field_type]["fields"][$field]);
|
55 |
-
}
|
56 |
-
}
|
57 |
-
|
58 |
-
// Remove alert from "Permalink Manager Lite" version
|
59 |
-
unset($fields["taxonomies"]['append_content']);
|
60 |
-
unset($fields["woocommerce"]['append_content']);
|
61 |
-
|
62 |
-
return $fields;
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Tools tab
|
67 |
-
*/
|
68 |
-
public function filter_tools_fields($fields, $subsection) {
|
69 |
-
unset($fields['content_type']['disabled']);
|
70 |
-
unset($fields['content_type']['pro']);
|
71 |
-
unset($fields['taxonomies']['pro']);
|
72 |
-
unset($fields['ids']['disabled']);
|
73 |
-
unset($fields['ids']['pro']);
|
74 |
-
|
75 |
-
return $fields;
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Tax Editor & Import support
|
80 |
-
*/
|
81 |
-
public function add_admin_section($admin_sections) {
|
82 |
-
// Add "Stop words" subsectio for "Tools"
|
83 |
-
$admin_sections['tools']['subsections']['stop_words']['function'] = array('class' => 'Permalink_Manager_Pro_Addons', 'method' => 'stop_words_output');
|
84 |
-
|
85 |
-
// Display Permalinks for all selected taxonomies
|
86 |
-
if(!empty($admin_sections['uri_editor']['subsections'])) {
|
87 |
-
foreach($admin_sections['uri_editor']['subsections'] as &$subsection) {
|
88 |
-
if(isset($subsection['pro'])) {
|
89 |
-
$subsection['function'] = array('class' => 'Permalink_Manager_Tax_Uri_Editor_Table', 'method' => 'display_admin_section');
|
90 |
-
unset($subsection['html']);
|
91 |
-
}
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
// Add "Support" section
|
96 |
-
$admin_sections['support'] = array(
|
97 |
-
'name' => __('Support', 'permalink-manager'),
|
98 |
-
'function' => array('class' => 'Permalink_Manager_Pro_Addons', 'method' => 'support_output')
|
99 |
-
);
|
100 |
-
|
101 |
-
// Import support
|
102 |
-
$admin_sections['tools']['subsections']['import']['function'] = array('class' => 'Permalink_Manager_Pro_Addons', 'method' => 'import_output');
|
103 |
-
|
104 |
-
return $admin_sections;
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Settings tab
|
109 |
-
*/
|
110 |
-
public function filter_settings_fields($fields) {
|
111 |
-
$all_taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array();
|
112 |
-
|
113 |
-
// 1. license key
|
114 |
-
$fields['licence'] = array(
|
115 |
-
'section_name' => __('Licence', 'permalink-manager'),
|
116 |
-
'container' => 'row',
|
117 |
-
'fields' => array(
|
118 |
-
'licence_key' => array(
|
119 |
-
'type' => 'text',
|
120 |
-
'label' => __('License key', 'permalink-manager'),
|
121 |
-
'description' => __('The licence key allows you to access all the plugin updates & priority support.', 'permalink-manager')
|
122 |
-
)
|
123 |
-
)
|
124 |
-
);
|
125 |
-
|
126 |
-
// 2. Unblock some fields
|
127 |
-
unset($fields['general']['fields']['case_insensitive_permalinks']['pro']);
|
128 |
-
unset($fields['general']['fields']['case_insensitive_permalinks']['disabled']);
|
129 |
-
unset($fields['advanced']['fields']['extension_suffix']['pro']);
|
130 |
-
unset($fields['advanced']['fields']['extension_suffix']['disabled']);
|
131 |
-
unset($fields['advanced']['fields']['setup_redirects']['pro']);
|
132 |
-
unset($fields['advanced']['fields']['setup_redirects']['disabled']);
|
133 |
-
|
134 |
-
return $fields;
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* "Stop words" subsection
|
139 |
-
*/
|
140 |
-
public function stop_words_output() {
|
141 |
-
global $permalink_manager_options;
|
142 |
-
|
143 |
-
// Fix the escaped quotes
|
144 |
-
$words_list = (!empty($permalink_manager_options['stop-words']['stop-words-list'])) ? stripslashes($permalink_manager_options['stop-words']['stop-words-list']) : "";
|
145 |
-
|
146 |
-
// Get stop-words languages
|
147 |
-
$languages = array_merge(array('' => __('-- Use predefined words list --', 'permalink_manager')), Permalink_Manager_Pro_Functions::load_stop_words_languages());
|
148 |
-
|
149 |
-
$buttons = "<table class=\"stop-words-buttons\"><tr>";
|
150 |
-
$buttons .= sprintf("<td><a href=\"#\" class=\"clear_all_words button button-small\">%s</a></td>", __("Remove all words", "permalink-manager"));
|
151 |
-
$buttons .= sprintf("<td>%s<td>", Permalink_Manager_Admin_Functions::generate_option_field("load_stop_words", array("type" => "select", "input_class" => "widefat small-select load_stop_words", "choices" => $languages)));
|
152 |
-
$buttons .= sprintf("<td>%s</td>", get_submit_button(__('Add the words from the list', 'permalink-manager'), 'button-small button-primary', 'load_stop_words_button', false));
|
153 |
-
$buttons .= "</tr></table>";
|
154 |
-
|
155 |
-
$fields = apply_filters('permalink-manager-tools-fields', array(
|
156 |
-
'stop-words' => array(
|
157 |
-
'container' => 'row',
|
158 |
-
'fields' => array(
|
159 |
-
'stop-words-enable' => array(
|
160 |
-
'label' => __( 'Enable "stop words"', 'permalink-manager' ),
|
161 |
-
'type' => 'single_checkbox',
|
162 |
-
'container' => 'row',
|
163 |
-
'input_class' => 'enable_stop_words'
|
164 |
-
),
|
165 |
-
'stop-words-list' => array(
|
166 |
-
'label' => __( '"Stop words" list', 'permalink-manager' ),
|
167 |
-
'type' => 'textarea',
|
168 |
-
'container' => 'row',
|
169 |
-
'value' => $words_list,
|
170 |
-
'description' => __('The words should be comma-separated.', 'permalink-manager'),
|
171 |
-
'input_class' => 'widefat stop_words',
|
172 |
-
'after_description' => $buttons
|
173 |
-
)
|
174 |
-
)
|
175 |
-
)
|
176 |
-
), 'stop_words');
|
177 |
-
|
178 |
-
$sidebar = '<h3>' . __('Instructions', 'permalink-manager') . '</h3>';
|
179 |
-
$sidebar .= wpautop(__('If enabled, all selected "stop words" will be automatically removed from default URIs.', 'bis'));
|
180 |
-
$sidebar .= wpautop(__('Each of the words can be removed and any new words can be added to the list. You can also use a predefined list (available in 21 languages).', 'bis'));
|
181 |
-
|
182 |
-
return Permalink_Manager_Admin_Functions::get_the_form($fields, '', array('text' => __('Save', 'permalink-manager'), 'class' => 'primary margin-top'), $sidebar, array('action' => 'permalink-manager', 'name' => 'save_stop_words'), true);
|
183 |
-
}
|
184 |
-
|
185 |
-
public function save_stop_words() {
|
186 |
-
if(isset($_POST['stop-words']) && wp_verify_nonce($_POST['save_stop_words'], 'permalink-manager')) {
|
187 |
-
Permalink_Manager_Actions::save_settings('stop-words', $_POST['stop-words']);
|
188 |
-
}
|
189 |
-
}
|
190 |
-
|
191 |
-
/**
|
192 |
-
* "Import" subsection
|
193 |
-
*/
|
194 |
-
public function import_output() {
|
195 |
-
global $permalink_manager_options;
|
196 |
-
|
197 |
-
// Count custom permalinks URIs
|
198 |
-
$count_custom_permalinks = count(Permalink_Manager_Third_Parties::custom_permalinks_uris());
|
199 |
-
|
200 |
-
$fields = apply_filters('permalink-manager-tools-fields', array(
|
201 |
-
'disable_custom_permalinks' => array(
|
202 |
-
'label' => __( 'Custom Permalinks', 'permalink-manager' ),
|
203 |
-
'checkbox_label' => __( 'Deactivate after import', 'permalink-manager' ),
|
204 |
-
'type' => 'single_checkbox',
|
205 |
-
'container' => 'row',
|
206 |
-
'description' => __('If selected, "Custom Permalinks" plugin will be deactivated after its custom URIs are imported.', 'permalink-manager'),
|
207 |
-
'input_class' => ''
|
208 |
-
)
|
209 |
-
), 'regenerate');
|
210 |
-
|
211 |
-
$sidebar = '<h3>' . __('Instructions', 'permalink-manager') . '</h3>';
|
212 |
-
$sidebar .= wpautop(__('Please note that "Custom Permalinks" (if activated) may break the behavior of this plugin.', 'bis'));
|
213 |
-
$sidebar .= wpautop(__('Therefore, it is recommended to disable "Custom Permalink" and import old permalinks before using Permalink Manager Pro.', 'bis'));
|
214 |
-
|
215 |
-
// Show some additional info data
|
216 |
-
if($count_custom_permalinks > 0) {
|
217 |
-
$button = array(
|
218 |
-
'text' => sprintf(__('Import %d URIs', 'permalink-manager'), $count_custom_permalinks),
|
219 |
-
'class' => 'primary margin-top'
|
220 |
-
);
|
221 |
-
} else {
|
222 |
-
$button = array(
|
223 |
-
'text' => __('No custom URIs to import', 'permalink-manager'),
|
224 |
-
'class' => 'secondary margin-top',
|
225 |
-
'attributes' => array('disabled' => 'disabled')
|
226 |
-
);
|
227 |
-
}
|
228 |
-
|
229 |
-
return Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', $button, $sidebar, array('action' => 'permalink-manager', 'name' => 'import'), true);
|
230 |
-
}
|
231 |
-
|
232 |
-
/**
|
233 |
-
* "Support" section
|
234 |
-
*/
|
235 |
-
public function support_output() {
|
236 |
-
$output = sprintf("<h3>%s</h3>", __("Technical support", "permalink-manager"));
|
237 |
-
|
238 |
-
$output .= wpautop(__('Please send us your question or a detailed description of your problem/issue to <a href="mailto:support@permalinkmanager.pro">support@permalinkmanager.pro</a>.', 'permalink-manager'));
|
239 |
-
$output .= wpautop(__('To reduce response time, please attach your licence key, URL address and screenshots if possible.', 'permalink-manager'));
|
240 |
-
|
241 |
-
$output .= sprintf("<h3>%s</h3>", __("Suggestions/feedback", "permalink-manager"));
|
242 |
-
$output .= wpautop(__('If you would like to suggest a new functionality or leave us feedback, we are open to all new ideas and would be grateful for all your comments!', 'permalink-manager'));
|
243 |
-
$output .= wpautop(__(' Please send your remarks to <a href="mailto:contact@permalinkmanager.pro">contact@permalinkmanager.pro</a>.', 'permalink-manager'));
|
244 |
-
|
245 |
-
return $output;
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Custom Redirects Panel
|
250 |
-
*/
|
251 |
-
public static function display_redirect_form($element_id) {
|
252 |
-
global $permalink_manager_redirects;
|
253 |
-
|
254 |
-
$html = "<table>";
|
255 |
-
// 1. Sample row
|
256 |
-
$html .= sprintf("<tr class=\"sample-row\"><td>%s</td><td>%s</td></tr>",
|
257 |
-
Permalink_Manager_Admin_Functions::generate_option_field("permalink-manager-redirects", array("input_class" => "widefat", "value" => "", 'extra_atts' => "data-index=\"\"")),
|
258 |
-
"<a href=\"#\" class=\"remove-redirect\"><span class=\"dashicons dashicons-no\"></span></a>"
|
259 |
-
);
|
260 |
-
|
261 |
-
// 2. Rows with redirects
|
262 |
-
if(!empty($permalink_manager_redirects[$element_id]) && is_array($permalink_manager_redirects[$element_id])) {
|
263 |
-
foreach($permalink_manager_redirects[$element_id] as $index => $redirect) {
|
264 |
-
$html .= sprintf("<tr><td>%s</td><td>%s</td></tr>",
|
265 |
-
Permalink_Manager_Admin_Functions::generate_option_field("permalink-manager-redirects[{$index}]", array("input_class" => "widefat", "value" => $redirect, 'extra_atts' => "data-index=\"{$index}\"")),
|
266 |
-
"<a href=\"#\" class=\"remove-redirect\"><span class=\"dashicons dashicons-no\"></span></a>"
|
267 |
-
);
|
268 |
-
}
|
269 |
-
}
|
270 |
-
$html .= "</table>";
|
271 |
-
|
272 |
-
// 3. Description
|
273 |
-
$html .= "<div class=\"redirects-panel-description\">";
|
274 |
-
$html .= wpautop(sprintf(__("<strong>Please use URIs only!</strong><br />For instance, to set-up a redirect for <code>%s/old-uri</code> please use <code>old-uri</code>.", "permalink-manager"), get_option('home')));
|
275 |
-
$html .= "</div>";
|
276 |
-
|
277 |
-
// 4. Add new redirect button
|
278 |
-
$html .= sprintf("<button type=\"button\" class=\"button button-small hide-if-no-js\" id=\"permalink-manager-new-redirect\">%s</button>",
|
279 |
-
__("Add new redirect", "permalink-manager")
|
280 |
-
);
|
281 |
-
|
282 |
-
return $html;
|
283 |
-
}
|
284 |
-
|
285 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/views/permalink-manager-settings.php
CHANGED
@@ -63,7 +63,7 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
|
|
63 |
'type' => 'single_checkbox',
|
64 |
'label' => __('Attachment redirect support', 'permalink-manager'),
|
65 |
'input_class' => '',
|
66 |
-
'description' => __('
|
67 |
),
|
68 |
'canonical_redirect' => array(
|
69 |
'type' => 'single_checkbox',
|
@@ -111,11 +111,6 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
|
|
111 |
'choices' => $content_types,
|
112 |
'description' => __('The slugs will not be automatically apended to the end of permastructure in the default permalinks for selected post types & taxonomies.<br />Works correctly only if <strong>"Force custom slugs" is disabled!</strong>', 'permalink-manager')
|
113 |
),
|
114 |
-
'deep_detect' => array(
|
115 |
-
'type' => 'single_checkbox',
|
116 |
-
'label' => __('Enable "Deep detect"', 'permalink-manager'),
|
117 |
-
'description' => __('Please keep it enabled if your custom URIs end with numerals, e.g. <strong>example.com/projects/20171025</strong>.', 'permalink-manager')
|
118 |
-
),
|
119 |
'decode_uris' => array(
|
120 |
'type' => 'single_checkbox',
|
121 |
'label' => __('Decode URIs', 'permalink-manager'),
|
63 |
'type' => 'single_checkbox',
|
64 |
'label' => __('Attachment redirect support', 'permalink-manager'),
|
65 |
'input_class' => '',
|
66 |
+
'description' => __('Support for redirect attachment URLs to parent post URL. Works only when "Yoast SEO Premium" plugin is enabled.', 'permalink-manager')
|
67 |
),
|
68 |
'canonical_redirect' => array(
|
69 |
'type' => 'single_checkbox',
|
111 |
'choices' => $content_types,
|
112 |
'description' => __('The slugs will not be automatically apended to the end of permastructure in the default permalinks for selected post types & taxonomies.<br />Works correctly only if <strong>"Force custom slugs" is disabled!</strong>', 'permalink-manager')
|
113 |
),
|
|
|
|
|
|
|
|
|
|
|
114 |
'decode_uris' => array(
|
115 |
'type' => 'single_checkbox',
|
116 |
'label' => __('Decode URIs', 'permalink-manager'),
|
includes/views/permalink-manager-uri-editor-tax.php
DELETED
@@ -1,188 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Permalink Manager Pro: Custom class for Permalink Editor for Terms
|
4 |
-
*/
|
5 |
-
class Permalink_Manager_Tax_Uri_Editor_Table extends WP_List_Table {
|
6 |
-
|
7 |
-
public function __construct() {
|
8 |
-
global $status, $page;
|
9 |
-
|
10 |
-
parent::__construct(array(
|
11 |
-
'singular' => 'slug',
|
12 |
-
'plural' => 'slugs'
|
13 |
-
));
|
14 |
-
}
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Get the HTML output with the WP_List_Table
|
18 |
-
*/
|
19 |
-
public function display_admin_section() {
|
20 |
-
global $wpdb;
|
21 |
-
|
22 |
-
$output = "<form id=\"permalinks-post-types-table\" class=\"slugs-table\" method=\"post\">";
|
23 |
-
$output .= wp_nonce_field('permalink-manager', 'uri_editor', true, true);
|
24 |
-
$output .= Permalink_Manager_Admin_Functions::section_type_field('taxonomies');
|
25 |
-
|
26 |
-
// Bypass
|
27 |
-
ob_start();
|
28 |
-
|
29 |
-
$this->prepare_items();
|
30 |
-
$this->display();
|
31 |
-
$output .= ob_get_contents();
|
32 |
-
|
33 |
-
ob_end_clean();
|
34 |
-
|
35 |
-
$output .= "</form>";
|
36 |
-
|
37 |
-
return $output;
|
38 |
-
}
|
39 |
-
|
40 |
-
function get_table_classes() {
|
41 |
-
return array( 'widefat', 'striped', $this->_args['plural'] );
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Override the parent columns method. Defines the columns to use in your listing table
|
46 |
-
*/
|
47 |
-
public function get_columns() {
|
48 |
-
return apply_filters('permalink-manager-uri-editor-columns', array(
|
49 |
-
//'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
|
50 |
-
'item_title' => __('Term title', 'permalink-manager'),
|
51 |
-
'item_uri' => __('Full URI & Permalink', 'permalink-manager'),
|
52 |
-
'count' => __('Count', 'permalink-manager'),
|
53 |
-
));
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Hidden columns
|
58 |
-
*/
|
59 |
-
public function get_hidden_columns() {
|
60 |
-
return array('post_date_gmt');
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Sortable columns
|
65 |
-
*/
|
66 |
-
public function get_sortable_columns() {
|
67 |
-
return array(
|
68 |
-
'item_title' => array('name', false)
|
69 |
-
);
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Data inside the columns
|
74 |
-
*/
|
75 |
-
public function column_default($item, $column_name) {
|
76 |
-
global $permalink_manager_options;
|
77 |
-
|
78 |
-
$uri = Permalink_Manager_URI_Functions_Tax::get_term_uri($item['term_id'], true);
|
79 |
-
$uri = (!empty($permalink_manager_options['general']['decode_uris'])) ? urldecode($uri) : $uri;
|
80 |
-
|
81 |
-
$field_args_base = array('type' => 'text', 'value' => $uri, 'without_label' => true, 'input_class' => '');
|
82 |
-
$term = get_term($item['term_id']);
|
83 |
-
$permalink = get_term_link(intval($item['term_id']), $item['taxonomy']);
|
84 |
-
$all_terms_link = admin_url("edit.php?{$term->taxonomy}={$term->slug}");
|
85 |
-
|
86 |
-
$output = apply_filters('permalink-manager-uri-editor-column-content', '', $column_name, $term);
|
87 |
-
if(!empty($output)) { return $output; }
|
88 |
-
|
89 |
-
switch($column_name) {
|
90 |
-
|
91 |
-
case 'item_title':
|
92 |
-
$output = $item[ 'name' ];
|
93 |
-
$output .= '<div class="extra-info small">';
|
94 |
-
$output .= sprintf("<span><strong>%s:</strong> %s</span>", __("Slug", "permalink-manager"), urldecode($item['slug']));
|
95 |
-
$output .= apply_filters('permalink-manager-uri-editor-extra-info', '', $column_name, $term);
|
96 |
-
$output .= '</div>';
|
97 |
-
|
98 |
-
$output .= '<div class="row-actions">';
|
99 |
-
$output .= sprintf("<span class=\"edit\"><a href=\"%s\" title=\"%s\">%s</a> | </span>", esc_url(get_edit_tag_link($item['term_id'], $item['taxonomy'])), __('Edit', 'permalink-manager'), __('Edit', 'permalink-manager'));
|
100 |
-
$output .= '<span class="view"><a target="_blank" href="' . $permalink . '" title="' . __('View', 'permalink-manager') . ' ' . $item[ 'name' ] . '" rel="permalink">' . __('View', 'permalink-manager') . '</a> | </span>';
|
101 |
-
$output .= '<span class="id">#' . $item[ 'term_id' ] . '</span>';
|
102 |
-
$output .= '</div>';
|
103 |
-
return $output;
|
104 |
-
|
105 |
-
case 'item_uri':
|
106 |
-
$output = Permalink_Manager_Admin_Functions::generate_option_field("uri[tax-{$item['term_id']}]", $field_args_base);
|
107 |
-
$output .= sprintf("<a class=\"small post_permalink\" href=\"%s\" target=\"_blank\"><span class=\"dashicons dashicons-admin-links\"></span> %s</a>", $permalink, urldecode($permalink));
|
108 |
-
return $output;;
|
109 |
-
|
110 |
-
case 'count':
|
111 |
-
return "<a href=\"{$all_terms_link}\">{$term->count}</a>";
|
112 |
-
|
113 |
-
default:
|
114 |
-
return $item[$column_name];
|
115 |
-
}
|
116 |
-
}
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Sort the data
|
120 |
-
*/
|
121 |
-
private function sort_data($a, $b) {
|
122 |
-
// Set defaults
|
123 |
-
$orderby = (!empty($_GET['orderby'])) ? $_GET['orderby'] : 'name';
|
124 |
-
$order = (!empty($_GET['order'])) ? $_GET['order'] : 'asc';
|
125 |
-
$result = strnatcasecmp( $a[$orderby], $b[$orderby] );
|
126 |
-
|
127 |
-
return ($order === 'asc') ? $result : -$result;
|
128 |
-
}
|
129 |
-
|
130 |
-
/**
|
131 |
-
* The button that allows to save updated slugs
|
132 |
-
*/
|
133 |
-
function extra_tablenav($which) {
|
134 |
-
$button_top = __( 'Update all the URIs below', 'permalink-manager' );
|
135 |
-
$button_bottom = __( 'Update all the URIs above', 'permalink-manager' );
|
136 |
-
|
137 |
-
echo '<div class="alignleft actions">';
|
138 |
-
submit_button( ${"button_$which"}, 'primary', "update_all_slugs[{$which}]", false, array( 'id' => 'doaction', 'value' => 'update_all_slugs' ) );
|
139 |
-
echo '</div>';
|
140 |
-
}
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Prepare the items for the table to process
|
144 |
-
*/
|
145 |
-
public function prepare_items() {
|
146 |
-
global $wpdb, $permalink_manager_options, $active_subsection, $current_admin_tax;
|
147 |
-
|
148 |
-
$columns = $this->get_columns();
|
149 |
-
$hidden = $this->get_hidden_columns();
|
150 |
-
$sortable = $this->get_sortable_columns();
|
151 |
-
$current_page = $this->get_pagenum();
|
152 |
-
|
153 |
-
// Get query variables
|
154 |
-
$per_page = $permalink_manager_options['screen-options']['per_page'];
|
155 |
-
$taxonomies_array = Permalink_Manager_Helper_Functions::get_taxonomies_array();
|
156 |
-
$taxonomies = ($active_subsection && $active_subsection == 'all_taxs') ? "'" . implode("', '", $taxonomies_array) . "'" : "'{$current_admin_tax}'";
|
157 |
-
|
158 |
-
// SQL query parameters
|
159 |
-
$order = (isset($_REQUEST['order']) && in_array($_REQUEST['order'], array('asc', 'desc'))) ? $_REQUEST['order'] : 'desc';
|
160 |
-
$orderby = (isset($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'term_id';
|
161 |
-
$offset = ($current_page - 1) * $per_page;
|
162 |
-
|
163 |
-
// Grab terms from database
|
164 |
-
$sql_query = "SELECT t.*, tt.taxonomy FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON (tt.term_id = t.term_id) WHERE tt.taxonomy IN ($taxonomies) ORDER BY {$orderby} {$order};";
|
165 |
-
$all_data = $wpdb->get_results($sql_query, ARRAY_A);
|
166 |
-
|
167 |
-
// How many items?
|
168 |
-
$total_items = $wpdb->num_rows;
|
169 |
-
|
170 |
-
// Sort posts and count all posts
|
171 |
-
usort( $all_data, array( &$this, 'sort_data' ) );
|
172 |
-
|
173 |
-
$data = array_slice($all_data, $offset, $per_page);
|
174 |
-
|
175 |
-
// Debug SQL query
|
176 |
-
$debug_txt = "<textarea style=\"width:100%;height:300px\">{$sql_query} \n\nOffset: {$offset} \nPage: {$current_page}\nPer page: {$per_page} \nTotal: {$total_items}</textarea>";
|
177 |
-
if(isset($_REQUEST['debug_editor_sql'])) { wp_die($debug_txt); }
|
178 |
-
|
179 |
-
$this->set_pagination_args( array(
|
180 |
-
'total_items' => $total_items,
|
181 |
-
'per_page' => $per_page
|
182 |
-
));
|
183 |
-
|
184 |
-
$this->_column_headers = array($columns, $hidden, $sortable);
|
185 |
-
$this->items = $data;
|
186 |
-
}
|
187 |
-
|
188 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
permalink-manager.php
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
-
* Plugin Name: Permalink Manager
|
5 |
* Plugin URI: https://permalinkmanager.pro?utm_source=plugin
|
6 |
* Description: Most advanced Permalink utility for Wordpress. It allows to bulk edit the permalinks & permastructures and regenerate/reset all the URIs in your Wordpress instance.
|
7 |
-
* Version: 2.0.
|
8 |
* Author: Maciej Bis
|
9 |
* Author URI: http://maciejbis.net/
|
10 |
* License: GPL-2.0+
|
@@ -21,7 +21,7 @@ if (!defined('WPINC')) {
|
|
21 |
// Define the directories used to load plugin files.
|
22 |
define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
|
23 |
define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
|
24 |
-
define( 'PERMALINK_MANAGER_VERSION', '2.0.
|
25 |
define( 'PERMALINK_MANAGER_FILE', __FILE__ );
|
26 |
define( 'PERMALINK_MANAGER_DIR', untrailingslashit( dirname( __FILE__ ) ) );
|
27 |
define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__) );
|
@@ -158,8 +158,7 @@ class Permalink_Manager_Class {
|
|
158 |
'trailing_slashes' => 0,
|
159 |
'setup_redirects' => 0,
|
160 |
'auto_remove_duplicates' => 0,
|
161 |
-
'disable_slug_appendix' => array()
|
162 |
-
'deep_detect' => 1
|
163 |
),
|
164 |
'licence' => array()
|
165 |
));
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
+
* Plugin Name: Permalink Manager Lite
|
5 |
* Plugin URI: https://permalinkmanager.pro?utm_source=plugin
|
6 |
* Description: Most advanced Permalink utility for Wordpress. It allows to bulk edit the permalinks & permastructures and regenerate/reset all the URIs in your Wordpress instance.
|
7 |
+
* Version: 2.0.3
|
8 |
* Author: Maciej Bis
|
9 |
* Author URI: http://maciejbis.net/
|
10 |
* License: GPL-2.0+
|
21 |
// Define the directories used to load plugin files.
|
22 |
define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
|
23 |
define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
|
24 |
+
define( 'PERMALINK_MANAGER_VERSION', '2.0.3' );
|
25 |
define( 'PERMALINK_MANAGER_FILE', __FILE__ );
|
26 |
define( 'PERMALINK_MANAGER_DIR', untrailingslashit( dirname( __FILE__ ) ) );
|
27 |
define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__) );
|
158 |
'trailing_slashes' => 0,
|
159 |
'setup_redirects' => 0,
|
160 |
'auto_remove_duplicates' => 0,
|
161 |
+
'disable_slug_appendix' => array()
|
|
|
162 |
),
|
163 |
'licence' => array()
|
164 |
));
|