Version Description
Release Date: February 11th, 2016
- First and tested released until WordPress 4.4.2
- Tested code from WordPress 3.4 version.
=
Download this release
Release Info
Developer | seedplugins |
Plugin | WP Broken Link Status Checker |
Version | 1.0 |
Comparing to | |
See all releases |
Version 1.0
- admin/admin.php +481 -0
- admin/extensions.php +41 -0
- admin/scans-submit.php +275 -0
- admin/scans.php +936 -0
- admin/settings.php +82 -0
- assets/css/admin.css +562 -0
- assets/images/advanced-anchor.png +0 -0
- assets/images/advanced-close.png +0 -0
- assets/images/advanced-extended.png +0 -0
- assets/images/advanced-filters.png +0 -0
- assets/images/advanced-reset.png +0 -0
- assets/images/advanced-url.png +0 -0
- assets/images/button-close-hover.png +0 -0
- assets/images/button-close.png +0 -0
- assets/images/close.png +0 -0
- assets/images/extensions/pro-banner.jpg +0 -0
- assets/images/extensions/wpls-web-crawler-edit.png +0 -0
- assets/images/extensions/wpls-web-crawler-results-actions.png +0 -0
- assets/images/extensions/wpls-web-crawler-results-advanced.png +0 -0
- assets/images/extensions/wpls-web-crawler-url-tools-results.png +0 -0
- assets/images/extensions/wpls-web-crawler-url-tools.png +0 -0
- assets/images/loading.gif +0 -0
- assets/images/scan-clock.png +0 -0
- assets/images/scan-launch.png +0 -0
- assets/images/scan-link.png +0 -0
- assets/images/scan-warning.png +0 -0
- assets/images/search.png +0 -0
- assets/images/yes.png +0 -0
- assets/js/admin-edit.js +277 -0
- assets/js/admin.js +138 -0
- assets/js/lightboxed/LICENSE +11 -0
- assets/js/lightboxed/jquery.lightboxed.js +273 -0
- assets/js/lightboxed/jquery.lightboxed.min.js +1 -0
- core/alive.php +531 -0
- core/boot.php +21 -0
- core/crawler.php +2249 -0
- core/curl.php +115 -0
- core/module.php +195 -0
- core/nonce/nonce.php +310 -0
- core/notify.php +123 -0
- core/plugin.php +118 -0
- core/register.php +71 -0
- core/requests/class-json.php +960 -0
- core/requests/http.php +417 -0
- core/scans.php +1918 -0
- core/scheme.php +288 -0
- core/settings.php +173 -0
- core/status.php +212 -0
- core/text.php +105 -0
- core/types-curl.php +127 -0
- core/types.php +752 -0
- core/url.php +364 -0
- core/util-math.php +36 -0
- core/util-string.php +49 -0
- core/util.php +114 -0
- languages/wp-link-status.pot +2821 -0
- readme.txt +79 -0
- views/extensions.php +77 -0
- views/scans-edit.php +559 -0
- views/scans-results.php +1186 -0
- views/scans.php +552 -0
- views/settings.php +154 -0
- views/views.php +78 -0
- wp-link-status.php +56 -0
admin/admin.php
ADDED
@@ -0,0 +1,481 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Load dependencies
|
4 |
+
require_once(dirname(dirname(__FILE__)).'/core/module.php');
|
5 |
+
|
6 |
+
/**
|
7 |
+
* WP Link Status Admin class
|
8 |
+
*
|
9 |
+
* @package WP Link Status
|
10 |
+
* @subpackage WP Link Status Admin
|
11 |
+
*/
|
12 |
+
class WPLNST_Admin extends WPLNST_Core_Module {
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
// Properties
|
17 |
+
// ---------------------------------------------------------------------------------------------------
|
18 |
+
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Handle submitted scan object
|
23 |
+
*/
|
24 |
+
public $scan_submit;
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Version for external calls
|
30 |
+
*/
|
31 |
+
protected $script_version;
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
// Initialization
|
36 |
+
// ---------------------------------------------------------------------------------------------------
|
37 |
+
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Creates a singleton object
|
42 |
+
*/
|
43 |
+
public static function instantiate($args = null) {
|
44 |
+
return self::get_instance(get_class(), $args);
|
45 |
+
}
|
46 |
+
|
47 |
+
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Custom constructor
|
51 |
+
*/
|
52 |
+
protected function on_construct($args = null) {
|
53 |
+
|
54 |
+
// Dependencies
|
55 |
+
wplnst_require('core', 'text');
|
56 |
+
|
57 |
+
// Load translations
|
58 |
+
add_action('plugins_loaded', array('WPLNST_Core_Plugin', 'load_plugin_textdomain'));
|
59 |
+
|
60 |
+
// Check AJAX Mode
|
61 |
+
if (defined('DOING_AJAX') && DOING_AJAX) {
|
62 |
+
|
63 |
+
// Check this plugin action
|
64 |
+
if (!empty($_POST['action']) && 0 === strpos($_POST['action'], 'wplnst_')) {
|
65 |
+
|
66 |
+
// Check suffix
|
67 |
+
$suffix = mb_substr($_POST['action'], 7);
|
68 |
+
if (!empty($suffix) && method_exists($this, 'ajax_'.$suffix)) {
|
69 |
+
|
70 |
+
// Set AJAX handler
|
71 |
+
add_action('wp_ajax_'.$_POST['action'], array(&$this, 'ajax_'.$suffix));
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
// Continue
|
76 |
+
} else {
|
77 |
+
|
78 |
+
// Check submit
|
79 |
+
$this->scans_edit_submit_check();
|
80 |
+
|
81 |
+
// Menu
|
82 |
+
add_action('admin_menu', array(&$this, 'admin_menu'));
|
83 |
+
|
84 |
+
// Enqueues
|
85 |
+
add_action('admin_enqueue_scripts', array(&$this, 'admin_enqueue'));
|
86 |
+
|
87 |
+
// Screen options
|
88 |
+
add_filter('set-screen-option', array(&$this, 'options_screen_set'), 11, 3);
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Enqueue scripts and styles
|
96 |
+
*/
|
97 |
+
public function admin_enqueue() {
|
98 |
+
|
99 |
+
// Check plugin context
|
100 |
+
if (!self::is_plugin_page())
|
101 |
+
return;
|
102 |
+
|
103 |
+
// Compose script version
|
104 |
+
$this->script_version = self::get_script_version();
|
105 |
+
|
106 |
+
// Commmon admin styles
|
107 |
+
wp_enqueue_style('wplnst-admin-css', plugins_url('assets/css/admin.css', WPLNST_FILE), array(), $this->script_version);
|
108 |
+
|
109 |
+
// jQuery Lightboxed plugin
|
110 |
+
wp_enqueue_script('wplnst-admin-lighboxed', plugins_url('assets/js/lightboxed/jquery.lightboxed.min.js', WPLNST_FILE), array('jquery'), $this->script_version, true);
|
111 |
+
|
112 |
+
// Common admin script
|
113 |
+
wp_enqueue_script('wplnst-admin-script', plugins_url('assets/js/admin.js', WPLNST_FILE), array('jquery'), $this->script_version, true);
|
114 |
+
|
115 |
+
// Edit scan script
|
116 |
+
if (WPLNST_Core_Plugin::slug.'-new-scan' == $_GET['page'] || (!empty($_GET['context']) && 'edit' == $_GET['context']))
|
117 |
+
wp_enqueue_script('wplnst-admin-script-edit', plugins_url('assets/js/admin-edit.js', WPLNST_FILE), array('jquery', 'json2'), $this->script_version, true);
|
118 |
+
|
119 |
+
// Enqueue version specific scripts
|
120 |
+
$this->admin_enqueue_version();
|
121 |
+
|
122 |
+
// Screen options
|
123 |
+
$this->options_screen_add();
|
124 |
+
}
|
125 |
+
|
126 |
+
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Enqueue specific versions scripts
|
130 |
+
*/
|
131 |
+
protected function admin_enqueue_version() {
|
132 |
+
// Need to override, but do nothing
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Admin menu hooks
|
139 |
+
*/
|
140 |
+
public function admin_menu() {
|
141 |
+
|
142 |
+
// Base 64 encoded SVG image
|
143 |
+
$icon_svg = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiICAgdmVyc2lvbj0iMS4xIiAgIHg9IjBweCIgICB5PSIwcHgiICAgdmlld0JveD0iMCAwIDEwMCAxMDAiICAgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMTAwIDEwMCIgICB4bWw6c3BhY2U9InByZXNlcnZlIiAgIGlkPSJzdmcyIiAgIGlua3NjYXBlOnZlcnNpb249IjAuNDguNCByOTkzOSIgICB3aWR0aD0iMTAwJSIgICBoZWlnaHQ9IjEwMCUiICAgc29kaXBvZGk6ZG9jbmFtZT0ibGluay1zdGF0dXMtNy5zdmciPjxtZXRhZGF0YSAgICAgaWQ9Im1ldGFkYXRhMTAiPjxyZGY6UkRGPjxjYzpXb3JrICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZGVmcyAgICAgaWQ9ImRlZnM4IiAvPjxzb2RpcG9kaTpuYW1lZHZpZXcgICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIgICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IiAgICAgYm9yZGVyb3BhY2l0eT0iMSIgICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiICAgICBncmlkdG9sZXJhbmNlPSIxMCIgICAgIGd1aWRldG9sZXJhbmNlPSIxMCIgICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIgICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTY4MCIgICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9Ijk3NCIgICAgIGlkPSJuYW1lZHZpZXc2IiAgICAgc2hvd2dyaWQ9ImZhbHNlIiAgICAgaW5rc2NhcGU6em9vbT0iMi4zNiIgICAgIGlua3NjYXBlOmN4PSItMjguNjAxNjk1IiAgICAgaW5rc2NhcGU6Y3k9IjUwIiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMjQiICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMiIgLz48cGF0aCAgICAgZD0iTTUwLDBDMjIuNCwwLDAsMjIuNCwwLDUwczIyLjQsNTAsNTAsNTBzNTAtMjIuNCw1MC01MFM3Ny42LDAsNTAsMHogTTU1LjgsNjUuM0w0NCw3N2MtMy4yLDMuMi03LjUsNS0xMS44LDVoMCAgYy0zLjksMC03LjUtMS41LTEwLjItNC4xYy01LjgtNS44LTUuOC0xNS4zLDAtMjEuMWwxNC4xLTE0LjFMMzYsNDQuOWMtMC4yLDIuNiwwLjEsNS4xLDAuOSw3LjRsMC4yLDAuNWwtOS41LDkuNSAgYy0xLjQsMS40LTIuMSwzLjItMi4xLDUuMWMwLDEuOSwwLjcsMy43LDIuMSw1LjFjMS4yLDEuMiwyLjksMS45LDQuNywxLjljMi4zLDAsNC42LTEsNi4zLTIuN2wxMS43LTExLjdjMy4zLTMuMywzLjctOC4yLDAuOS0xMSAgYy0wLjctMC43LTEtMS45LTAuOC0zLjFjMC4yLTEuMiwwLjgtMi4zLDEuNy0zLjJsMS41LTEuNWwwLjUsMC4zYzAuOSwwLjYsMS44LDEuMywyLjUsMmMwLjgsMC44LDEuNCwxLjYsMiwyLjYgIEM2Mi4zLDUxLjksNjEuMSw2MCw1NS44LDY1LjN6IE03Ny45LDQzLjJMNjMuOCw1Ny4zbDAuMi0yLjFjMC4yLTIuNi0wLjEtNS4xLTAuOS03LjRMNjMsNDcuMmw5LjUtOS41YzEuNC0xLjQsMi4xLTMuMiwyLjEtNS4xICBjMC0xLjktMC43LTMuNy0yLjEtNS4xYy0xLjItMS4yLTIuOS0xLjktNC43LTEuOWMtMi4zLDAtNC42LDEtNi4zLDIuN0w0OS43LDQwLjFjLTMuMywzLjMtMy43LDguMi0wLjksMTFjMC43LDAuNywxLDEuOSwwLjgsMy4xICBjLTAuMiwxLjItMC44LDIuMy0xLjcsMy4yTDQ2LjQsNTlsLTAuNS0wLjNjLTAuOS0wLjYtMS44LTEuMy0yLjUtMmMtMC44LTAuOC0xLjQtMS42LTItMi42Yy0zLjYtNS45LTIuNC0xNC4xLDIuOS0xOS40TDU2LDIzICBjMy4yLTMuMiw3LjUtNSwxMS44LTVjMy45LDAsNy41LDEuNSwxMC4yLDQuMWMyLjgsMi44LDQuNCw2LjYsNC40LDEwLjVDODIuMywzNi42LDgwLjcsNDAuNCw3Ny45LDQzLjJ6IiAgICAgaWQ9InBhdGg0IiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MSIgLz48L3N2Zz4=';
|
144 |
+
|
145 |
+
// Main menu
|
146 |
+
add_menu_page($this->get_plugin_title(), $this->get_menu_title(), WPLNST_Core_Plugin::capability, WPLNST_Core_Plugin::slug, array(&$this, 'admin_menu_scans'), $icon_svg, '99.20226');
|
147 |
+
|
148 |
+
// Scans
|
149 |
+
add_submenu_page(WPLNST_Core_Plugin::slug, self::get_text('scans'), self::get_text('scans'), WPLNST_Core_Plugin::capability, WPLNST_Core_Plugin::slug, array(&$this, 'admin_menu_scans'));
|
150 |
+
add_submenu_page(WPLNST_Core_Plugin::slug, self::get_text('scan_new'), self::get_text('scan_new'), WPLNST_Core_Plugin::capability, WPLNST_Core_Plugin::slug.'-new-scan', array(&$this, 'admin_menu_scans_new'));
|
151 |
+
|
152 |
+
// Utilities
|
153 |
+
$this->admin_menu_utilities();
|
154 |
+
|
155 |
+
// Settings
|
156 |
+
add_submenu_page(WPLNST_Core_Plugin::slug, self::get_text('settings'), self::get_text('settings'), WPLNST_Core_Plugin::capability, WPLNST_Core_Plugin::slug.'-settings', array(&$this, 'admin_menu_settings'));
|
157 |
+
|
158 |
+
// Addons
|
159 |
+
$this->admin_menu_addons();
|
160 |
+
}
|
161 |
+
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Admin menu utilities
|
166 |
+
*/
|
167 |
+
protected function admin_menu_utilities() {}
|
168 |
+
|
169 |
+
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Admin menu addons
|
173 |
+
*/
|
174 |
+
protected function admin_menu_addons() {
|
175 |
+
do_action('wplnst_admin_menu_addons');
|
176 |
+
add_submenu_page(WPLNST_Core_Plugin::slug, __('Extensions', 'wplnst'), '<span style="color:#f18500">'.__('Extensions', 'wplnst').'</span>', WPLNST_Core_Plugin::capability, WPLNST_Core_Plugin::slug.'-extensions', array(&$this, 'admin_menu_extensions'));
|
177 |
+
}
|
178 |
+
|
179 |
+
|
180 |
+
|
181 |
+
// Menu hooks
|
182 |
+
// ---------------------------------------------------------------------------------------------------
|
183 |
+
|
184 |
+
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Scans common page
|
188 |
+
*/
|
189 |
+
public function admin_menu_scans() {
|
190 |
+
wplnst_require('admin', 'scans');
|
191 |
+
new WPLNST_Admin_Scans($this, 'context');
|
192 |
+
}
|
193 |
+
|
194 |
+
|
195 |
+
|
196 |
+
/*
|
197 |
+
* New or edit scan page
|
198 |
+
*/
|
199 |
+
public function admin_menu_scans_new() {
|
200 |
+
wplnst_require('admin', 'scans');
|
201 |
+
new WPLNST_Admin_Scans($this, 'edit');
|
202 |
+
}
|
203 |
+
|
204 |
+
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Settings page
|
208 |
+
*/
|
209 |
+
public function admin_menu_settings() {
|
210 |
+
wplnst_require('admin', 'settings');
|
211 |
+
new WPLNST_Admin_Settings($this);
|
212 |
+
}
|
213 |
+
|
214 |
+
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Extensions page
|
218 |
+
*/
|
219 |
+
public function admin_menu_extensions() {
|
220 |
+
wplnst_require('admin', 'extensions');
|
221 |
+
new WPLNST_Admin_Extensions($this);
|
222 |
+
}
|
223 |
+
|
224 |
+
|
225 |
+
|
226 |
+
// New or edit scan submit handler
|
227 |
+
// ---------------------------------------------------------------------------------------------------
|
228 |
+
|
229 |
+
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Check a submit attempt
|
233 |
+
*/
|
234 |
+
private function scans_edit_submit_check() {
|
235 |
+
|
236 |
+
// Check plugin context
|
237 |
+
if (!self::is_plugin_page())
|
238 |
+
return;
|
239 |
+
|
240 |
+
// Edit scan form, early check because maybe do a redirection for new scans
|
241 |
+
if ((WPLNST_Core_Plugin::slug == $_GET['page'] && !empty($_GET['context']) && 'edit' == $_GET['context']) || WPLNST_Core_Plugin::slug.'-new-scan' == $_GET['page']) {
|
242 |
+
|
243 |
+
// Check id and nonce submit
|
244 |
+
if (isset($_POST['scan_id']) && isset($_POST['scan_edit_nonce']))
|
245 |
+
add_action('init', array(&$this, 'scans_edit_submit'));
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Check scan edit submit and save data
|
253 |
+
*/
|
254 |
+
public function scans_edit_submit() {
|
255 |
+
$this->load_scans_object();
|
256 |
+
wplnst_require('admin', 'scans-submit');
|
257 |
+
$this->scan_submit = new WPLNST_Admin_Scans_Submit($this->scans);
|
258 |
+
}
|
259 |
+
|
260 |
+
|
261 |
+
|
262 |
+
// Options screen
|
263 |
+
// ---------------------------------------------------------------------------------------------------
|
264 |
+
|
265 |
+
|
266 |
+
|
267 |
+
/**
|
268 |
+
* Add options to the admin screen
|
269 |
+
*/
|
270 |
+
private function options_screen_add() {
|
271 |
+
|
272 |
+
// Check scans context
|
273 |
+
if (WPLNST_Core_Plugin::slug == $_GET['page']) {
|
274 |
+
|
275 |
+
// Scans list
|
276 |
+
if (!isset($_GET['scan_id']) && empty($_GET['context'])) {
|
277 |
+
$option_default = WPLNST_Core_Types::scans_per_page;
|
278 |
+
$option_per_page = 'wplnst_scans_per_page';
|
279 |
+
$option_label = __('Scans per page', 'wplnst');
|
280 |
+
|
281 |
+
// Results list
|
282 |
+
} elseif (isset($_GET['context']) && 'results' == $_GET['context']) {
|
283 |
+
$option_default = WPLNST_Core_Types::scans_results_per_page;
|
284 |
+
$option_per_page = 'wplnst_scan_results_per_page';
|
285 |
+
$option_label = __('Crawler results per page', 'wplnst');
|
286 |
+
}
|
287 |
+
}
|
288 |
+
|
289 |
+
// Check option result
|
290 |
+
if (isset($option_label)) {
|
291 |
+
add_screen_option('per_page', array(
|
292 |
+
'default' => $option_default,
|
293 |
+
'label' => $option_label,
|
294 |
+
'option' => $option_per_page,
|
295 |
+
));
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
|
300 |
+
|
301 |
+
/**
|
302 |
+
* Set the screen options
|
303 |
+
*/
|
304 |
+
public function options_screen_set($status, $option, $value) {
|
305 |
+
|
306 |
+
// Options names
|
307 |
+
$allowed = array(
|
308 |
+
'scans_per_page',
|
309 |
+
'scan_results_per_page',
|
310 |
+
);
|
311 |
+
|
312 |
+
// Enum allowed
|
313 |
+
foreach ($allowed as $name) {
|
314 |
+
if ('wplnst_'.$name == $option)
|
315 |
+
return $value;
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
|
320 |
+
|
321 |
+
// Default view and exceptions
|
322 |
+
// ---------------------------------------------------------------------------------------------------
|
323 |
+
|
324 |
+
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Show default admin view
|
328 |
+
*/
|
329 |
+
public function screen_view($args) {
|
330 |
+
|
331 |
+
// Set plugin title
|
332 |
+
$args['plugin_title'] = $this->get_plugin_title();
|
333 |
+
|
334 |
+
// Before the screen output
|
335 |
+
$this->screen_view_before();
|
336 |
+
|
337 |
+
// And show it
|
338 |
+
self::screen_view_output($args);
|
339 |
+
}
|
340 |
+
|
341 |
+
|
342 |
+
|
343 |
+
/**
|
344 |
+
* Before the screen view output
|
345 |
+
*/
|
346 |
+
protected function screen_view_before() {
|
347 |
+
// Need to override, but do nothing
|
348 |
+
}
|
349 |
+
|
350 |
+
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Output the screen view
|
354 |
+
*/
|
355 |
+
private static function screen_view_output($args) {
|
356 |
+
|
357 |
+
// Vars
|
358 |
+
extract($args);
|
359 |
+
|
360 |
+
?><div class="wrap wplnst-wrap">
|
361 |
+
|
362 |
+
<h2 id="wplnst-title"><?php echo empty($title)? '' : $title.' - '; echo $plugin_title; if (!empty($add_item_text) && !empty($add_item_url)) : ?> <a class="add-new-h2" href="<?php echo esc_url($add_item_url); ?>"><?php echo esc_html($add_item_text); ?></a><?php endif; ?></h2>
|
363 |
+
|
364 |
+
<?php if (!wplnst_is_curl_enabled()) : ?><div class="error notice"><p><?php _e('Not detected the required cURL module enabled. Please contact with your hosting provider in order to install cURL for PHP in this server.', 'wplnst'); ?></p></div><?php endif; ?>
|
365 |
+
|
366 |
+
<?php if (!empty($notice_error)) : ?><div class="error notice"><p><?php echo $notice_error; ?></p></div><?php endif; ?>
|
367 |
+
|
368 |
+
<?php if (!empty($notice_success)) : ?><div class="updated notice is-dismissible"><p><?php echo $notice_success; ?></p></div><?php endif; ?>
|
369 |
+
|
370 |
+
<?php if (!empty($notice_warning)) : ?><div class="notice notice-warning is-dismissible"><p><?php echo $notice_warning; ?></p></div><?php endif; ?>
|
371 |
+
|
372 |
+
<?php if (!empty($notice_crawler)) : ?><div class="updated notice is-dismissible"><p><?php echo $notice_crawler; ?></p></div><?php endif; ?>
|
373 |
+
|
374 |
+
<?php if (!empty($wp_action)) do_action($wp_action, $args); ?>
|
375 |
+
|
376 |
+
</div><?php
|
377 |
+
}
|
378 |
+
|
379 |
+
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Common scan not found
|
383 |
+
*/
|
384 |
+
public function screen_scan_not_found($title) {
|
385 |
+
$this->screen_view(array(
|
386 |
+
'title' => $title,
|
387 |
+
'notice_error' => self::get_text('scan_not_found'),
|
388 |
+
));
|
389 |
+
}
|
390 |
+
|
391 |
+
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Invalid data screen
|
395 |
+
*/
|
396 |
+
public function screen_invalid_data($title) {
|
397 |
+
$this->screen_view(array(
|
398 |
+
'title' => $title,
|
399 |
+
'notice_error' => self::get_text('invalid_data'),
|
400 |
+
));
|
401 |
+
}
|
402 |
+
|
403 |
+
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Invalid data screen
|
407 |
+
*/
|
408 |
+
public function screen_invalid_nonce($title) {
|
409 |
+
$this->screen_view(array(
|
410 |
+
'title' => $title,
|
411 |
+
'notice_error' => self::get_text('invalid_nonce'),
|
412 |
+
));
|
413 |
+
}
|
414 |
+
|
415 |
+
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Common scan not found
|
419 |
+
*/
|
420 |
+
public function screen_unknown_error($title) {
|
421 |
+
$this->screen_view(array(
|
422 |
+
'title' => $title,
|
423 |
+
'notice_error' => self::get_text('unknown_error'),
|
424 |
+
));
|
425 |
+
}
|
426 |
+
|
427 |
+
|
428 |
+
|
429 |
+
// Utilities
|
430 |
+
// ---------------------------------------------------------------------------------------------------
|
431 |
+
|
432 |
+
|
433 |
+
|
434 |
+
/**
|
435 |
+
* Wrapper of WPLNST_Core_Text class get_text method
|
436 |
+
*/
|
437 |
+
public static function get_text($name) {
|
438 |
+
return WPLNST_Core_Text::get_text($name);
|
439 |
+
}
|
440 |
+
|
441 |
+
|
442 |
+
|
443 |
+
/**
|
444 |
+
* Return suffixed version for external scripts
|
445 |
+
*/
|
446 |
+
protected function get_script_version() {
|
447 |
+
global $wp_version;
|
448 |
+
return (empty($wp_version)? '' : 'wp-'.str_replace('http://', '', esc_url($wp_version)).'-').'wplnst-'.WPLNST_VERSION;
|
449 |
+
}
|
450 |
+
|
451 |
+
|
452 |
+
|
453 |
+
/**
|
454 |
+
* Return plugin title in admin menu
|
455 |
+
*/
|
456 |
+
protected function get_menu_title() {
|
457 |
+
return WPLNST_Core_Plugin::title;
|
458 |
+
}
|
459 |
+
|
460 |
+
|
461 |
+
|
462 |
+
/**
|
463 |
+
* Return plugin title for default view
|
464 |
+
*/
|
465 |
+
protected function get_plugin_title() {
|
466 |
+
return WPLNST_Core_Plugin::title;
|
467 |
+
}
|
468 |
+
|
469 |
+
|
470 |
+
|
471 |
+
/**
|
472 |
+
* Check if we are on any page of this plugin
|
473 |
+
*/
|
474 |
+
private static function is_plugin_page() {
|
475 |
+
global $pagenow;
|
476 |
+
return !(empty($pagenow) || 'admin.php' != $pagenow || empty($_GET['page']) || 0 !== strpos($_GET['page'], WPLNST_Core_Plugin::slug));
|
477 |
+
}
|
478 |
+
|
479 |
+
|
480 |
+
|
481 |
+
}
|
admin/extensions.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Admin Extensions class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Admin
|
8 |
+
*/
|
9 |
+
class WPLNST_Admin_Extensions {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Constructor
|
15 |
+
*/
|
16 |
+
public function __construct(&$admin) {
|
17 |
+
|
18 |
+
// Custom action view
|
19 |
+
add_action('wplnst_view_extensions', array(&$this, 'view_extensions'));
|
20 |
+
|
21 |
+
// Show settings screen
|
22 |
+
$admin->screen_view(array(
|
23 |
+
'title' => __('Extensions', 'wplnst'),
|
24 |
+
'wp_action' => 'wplnst_view_extensions',
|
25 |
+
'action' => WPLNST_Core_Plugin::get_url_extensions(),
|
26 |
+
));
|
27 |
+
}
|
28 |
+
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Extension view for settings page
|
33 |
+
*/
|
34 |
+
public function view_extensions($args) {
|
35 |
+
wplnst_require('views', 'extensions');
|
36 |
+
WPLNST_Views_Extensions::view($args);
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
|
41 |
+
}
|
admin/scans-submit.php
ADDED
@@ -0,0 +1,275 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Admin Scans Submit class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Admin
|
8 |
+
*/
|
9 |
+
class WPLNST_Admin_Scans_Submit {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Notice updated and error
|
15 |
+
*/
|
16 |
+
public $notice_error = false;
|
17 |
+
public $notice_warning = false;
|
18 |
+
public $notice_success = false;
|
19 |
+
public $notice_crawler = false;
|
20 |
+
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Handle submit in the constructor
|
25 |
+
*/
|
26 |
+
public function __construct($scans) {
|
27 |
+
|
28 |
+
// Globals
|
29 |
+
global $wpdb;
|
30 |
+
|
31 |
+
// Check scan identifier
|
32 |
+
$scan_id = isset($_POST['scan_id'])? (int) $_POST['scan_id'] : false;
|
33 |
+
if (false === $scan_id || (isset($_GET['scan_id']) && $scan_id != (int) $_GET['scan_id'])) {
|
34 |
+
$this->notice_error = WPLNST_Admin::get_text('invalid_data');
|
35 |
+
return;
|
36 |
+
}
|
37 |
+
|
38 |
+
// Check existing scan
|
39 |
+
if ($scan_id > 0 && false === ($scan = $scans->get_scan_by_id($scan_id))) {
|
40 |
+
$this->notice_error = WPLNST_Admin::get_text('scan_not_found');
|
41 |
+
return;
|
42 |
+
}
|
43 |
+
|
44 |
+
// Check submitted nonce
|
45 |
+
$nonce = isset($_POST['scan_edit_nonce'])? $_POST['scan_edit_nonce'] : false;
|
46 |
+
if (false === $nonce || !wp_verify_nonce($nonce, 'scan-edit-'.(empty($scan)? '0' : $scan->hash))) {
|
47 |
+
$this->notice_error = WPLNST_Admin::get_text('invalid_nonce');
|
48 |
+
return;
|
49 |
+
}
|
50 |
+
|
51 |
+
// Collect data
|
52 |
+
$max_threads = isset($_POST['tx-threads'])? (int) $_POST['tx-threads'] : 0;
|
53 |
+
$connect_timeout = isset($_POST['tx-connect-timeout'])? (int) $_POST['tx-connect-timeout'] : 0;
|
54 |
+
$request_timeout = isset($_POST['tx-request-timeout'])? (int) $_POST['tx-request-timeout'] : 0;
|
55 |
+
|
56 |
+
// Update data array
|
57 |
+
$updates = array(
|
58 |
+
'modified_by' => get_current_user_id(),
|
59 |
+
'modified_at' => current_time('mysql', true),
|
60 |
+
'name' => isset($_POST['tx-name'])? substr(trim(stripslashes($_POST['tx-name'])), 0, 255) : '',
|
61 |
+
'max_threads' => $max_threads,
|
62 |
+
'connect_timeout' => $connect_timeout,
|
63 |
+
'request_timeout' => $request_timeout,
|
64 |
+
);
|
65 |
+
|
66 |
+
|
67 |
+
// Initialize
|
68 |
+
$config = array();
|
69 |
+
|
70 |
+
|
71 |
+
/* Notifications */
|
72 |
+
|
73 |
+
// Empty of not completed
|
74 |
+
if (empty($scan) || 'end' != $scan->status) {
|
75 |
+
$config['notify_default'] = WPLNST_Core_Types::check_post_value('ck-notify-default', 'on', false);
|
76 |
+
$config['notify_address'] = WPLNST_Core_Types::check_post_value('ck-notify-address', 'on', false);
|
77 |
+
$config['notify_address_email'] = isset($_POST['tx-notify-address-email'])? substr(trim(stripslashes($_POST['tx-notify-address-email'])), 0, 255) : '';
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
/* Editable scan */
|
82 |
+
|
83 |
+
// Editable fields
|
84 |
+
if (empty($scan) || 'wait' == $scan->status) {
|
85 |
+
|
86 |
+
// General tab
|
87 |
+
$config['destination_type'] = WPLNST_Core_Types::check_post_value('sl-destination-type', array_keys(WPLNST_Core_Types::get_destination_types()), 'all');
|
88 |
+
$config['time_scope'] = WPLNST_Core_Types::check_post_value('sl-time-scope', array_keys(WPLNST_Core_Types::get_time_scopes()), 'anytime');
|
89 |
+
$config['link_types'] = WPLNST_Core_Types::check_post_value('ck-link-type', array_keys(WPLNST_Core_Types::get_link_types()), array());
|
90 |
+
$config['crawl_order'] = WPLNST_Core_Types::check_post_value('sl-crawl-order', array_keys(WPLNST_Core_Types::get_crawl_order()), 'asc');
|
91 |
+
$config['redir_status'] = WPLNST_Core_Types::check_post_value('ck-redir-status', 'on', false);
|
92 |
+
$config['malformed'] = WPLNST_Core_Types::check_post_value('ck-malformed-links', 'on', false);
|
93 |
+
|
94 |
+
// Content options tab
|
95 |
+
$config['post_types'] = WPLNST_Core_Types::check_post_value('ck-post-type', array_keys(WPLNST_Core_Types::get_post_types()), array());
|
96 |
+
$config['post_status'] = WPLNST_Core_Types::check_post_value('ck-post-status', array_keys(WPLNST_Core_Types::get_post_status()), array());
|
97 |
+
$config['comment_types'] = WPLNST_Core_Types::check_post_value('ck-comment-type', array_keys(WPLNST_Core_Types::get_comment_types()), array());
|
98 |
+
$config['blogroll'] = WPLNST_Core_Types::check_post_value('ck-blogroll', 'on', false);
|
99 |
+
|
100 |
+
// Links status tab
|
101 |
+
$config['status_levels'] = WPLNST_Core_Types::check_post_value('ck-status-level', array_keys(WPLNST_Core_Types::get_status_levels()), array());
|
102 |
+
$config['status_codes'] = WPLNST_Core_Types::check_post_value('ck-status-code', array_keys(WPLNST_Core_Types::get_status_codes_raw()), array());
|
103 |
+
|
104 |
+
// Filters
|
105 |
+
$config['custom_fields'] = WPLNST_Core_Types::check_post_elist('scan_custom_fields');
|
106 |
+
$config['anchor_filters'] = WPLNST_Core_Types::check_post_elist('scan_anchor_filters');
|
107 |
+
$config['include_urls'] = WPLNST_Core_Types::check_post_elist('scan_include_urls');
|
108 |
+
$config['exclude_urls'] = WPLNST_Core_Types::check_post_elist('scan_exclude_urls');
|
109 |
+
$config['html_attributes'] = WPLNST_Core_Types::check_post_elist('scan_html_attributes');
|
110 |
+
$config['filtered_query'] = WPLNST_Core_Types::check_post_value('ck-filtered-query', 'on', false);
|
111 |
+
}
|
112 |
+
|
113 |
+
// Add to update
|
114 |
+
if (!empty($config))
|
115 |
+
$updates['config'] = @json_encode($config);
|
116 |
+
|
117 |
+
|
118 |
+
/* Save and run */
|
119 |
+
|
120 |
+
// Check run attempt
|
121 |
+
$do_play = (isset($_POST['scan_run']) && 1 == (int) $_POST['scan_run']);
|
122 |
+
|
123 |
+
// Abort when cURL is not enabled
|
124 |
+
if ($do_play && !wplnst_is_curl_enabled())
|
125 |
+
$do_play = false;
|
126 |
+
|
127 |
+
// Check new scan
|
128 |
+
if (empty($scan_id)) {
|
129 |
+
|
130 |
+
// Create unique random hash associated with the scan
|
131 |
+
$hash = md5(rand(0, 9999).microtime().rand(0, 9999));
|
132 |
+
|
133 |
+
// Add scan and redirect
|
134 |
+
$wpdb->insert($wpdb->prefix.'wplnst_scans', array_merge($updates, array('status' => 'wait', 'hash' => $hash, 'created_at' => current_time('mysql', true))));
|
135 |
+
|
136 |
+
// New identifier
|
137 |
+
$insert_id = (int) $wpdb->insert_id;
|
138 |
+
|
139 |
+
// Check error
|
140 |
+
if (empty($insert_id)) {
|
141 |
+
|
142 |
+
// Message error
|
143 |
+
$this->notice_error = __('Something went wrong adding the new scan. Please <a href="javascript:history.back();">go back</a> and attempt again to submit form.');
|
144 |
+
|
145 |
+
// Scan added
|
146 |
+
} else {
|
147 |
+
|
148 |
+
// Run scan
|
149 |
+
if ($do_play) {
|
150 |
+
|
151 |
+
// Check max scans running
|
152 |
+
if (!$scans->can_play_more_scans()) {
|
153 |
+
|
154 |
+
// Maximum reached
|
155 |
+
$started = 'max_scans';
|
156 |
+
|
157 |
+
// Queue scan
|
158 |
+
$scans->queue_scan($insert_id);
|
159 |
+
|
160 |
+
// Retrieve scan
|
161 |
+
} elseif (false === ($scan = $scans->get_scan_by_id($insert_id))) {
|
162 |
+
|
163 |
+
// Can`t start scan
|
164 |
+
$started = 'error';
|
165 |
+
|
166 |
+
// Check ready
|
167 |
+
} elseif (true === $scans->is_scan_ready($scan)) {
|
168 |
+
|
169 |
+
// Update scan ready
|
170 |
+
$scans->update_scan_ready($scan->id, true);
|
171 |
+
|
172 |
+
// Attempt to run scan
|
173 |
+
if (false === $scans->play_scan($scan->id)) {
|
174 |
+
|
175 |
+
// Can`t start scan
|
176 |
+
$started = 'error';
|
177 |
+
|
178 |
+
// Running
|
179 |
+
} else {
|
180 |
+
|
181 |
+
// Done
|
182 |
+
$started = 'on';
|
183 |
+
|
184 |
+
// Save default threads values
|
185 |
+
$scans->set_scan_final_threads_options($scan->id, array(
|
186 |
+
'max_threads' => $max_threads,
|
187 |
+
'connect_timeout' => $connect_timeout,
|
188 |
+
'request_timeout' => $request_timeout,
|
189 |
+
));
|
190 |
+
|
191 |
+
// Attemp to run scan
|
192 |
+
WPLNST_Core_Alive::run($scan->id, $hash);
|
193 |
+
}
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
// Redirect to scan edit permalink
|
198 |
+
wp_redirect(WPLNST_Core_Plugin::get_url_scans_edit($insert_id, true, $do_play? $started : false));
|
199 |
+
|
200 |
+
// End
|
201 |
+
die;
|
202 |
+
}
|
203 |
+
|
204 |
+
// Update scan
|
205 |
+
} else {
|
206 |
+
|
207 |
+
// Update threads values if scan is in play mode
|
208 |
+
if ('play' == $scan->status) {
|
209 |
+
$updates['max_threads'] = wplnst_get_nsetting('max_threads', $max_threads);
|
210 |
+
$updates['connect_timeout'] = wplnst_get_nsetting('connect_timeout', $connect_timeout);
|
211 |
+
$updates['request_timeout'] = wplnst_get_nsetting('request_timeout', $request_timeout);
|
212 |
+
}
|
213 |
+
|
214 |
+
// Update scan data
|
215 |
+
$rows = $wpdb->update($wpdb->prefix.'wplnst_scans', $updates, array('scan_id' => $scan->id));
|
216 |
+
if (empty($rows) || false === ($scan = $scans->get_scan_by_id($scan->id))) {
|
217 |
+
|
218 |
+
// Message error
|
219 |
+
$this->notice_error = __('Something went wrong updating the scan data. Please <a href="javascript:history.back();">go back</a> and attempt again to save data.', 'wplnst');
|
220 |
+
|
221 |
+
// Done
|
222 |
+
} else {
|
223 |
+
|
224 |
+
// Update message
|
225 |
+
$this->notice_success = __('Scan updated successfully.', 'wplnst');
|
226 |
+
|
227 |
+
// Check if run the crawler, only for waiting scans
|
228 |
+
if ($do_play && 'wait' == $scan->status) {
|
229 |
+
|
230 |
+
// Check max scans running
|
231 |
+
if (!$scans->can_play_more_scans()) {
|
232 |
+
|
233 |
+
// Maximum reached
|
234 |
+
$this->notice_warning = WPLNST_Admin::get_text('max_scans');
|
235 |
+
|
236 |
+
// Queue scan
|
237 |
+
$scans->queue_scan($scan->id);
|
238 |
+
|
239 |
+
// Set to play
|
240 |
+
} elseif (false === $scans->play_scan($scan->id)) {
|
241 |
+
|
242 |
+
// Crawler not started
|
243 |
+
$this->notice_warning = sprintf(__('Something went wrong trying to start the crawler.'));
|
244 |
+
|
245 |
+
// Done
|
246 |
+
} else {
|
247 |
+
|
248 |
+
// Save default threads values
|
249 |
+
$scans->set_scan_final_threads_options($scan->id, array(
|
250 |
+
'max_threads' => $max_threads,
|
251 |
+
'connect_timeout' => $connect_timeout,
|
252 |
+
'request_timeout' => $request_timeout,
|
253 |
+
));
|
254 |
+
|
255 |
+
// Run scan
|
256 |
+
WPLNST_Core_Alive::run($scan->id, $scan->hash);
|
257 |
+
|
258 |
+
// Update message
|
259 |
+
$this->notice_crawler = sprintf(__('The crawler for this scan is running. You can see its data in the <a href="%s">crawler results page</a>.', 'wplnst'), esc_url(WPLNST_Core_Plugin::get_url_scans_results($scan->id)));
|
260 |
+
}
|
261 |
+
|
262 |
+
// Not play
|
263 |
+
} elseif ('wait' == $scan->status && $scans->can_play_more_scans() && true === $scans->is_scan_ready($scan)) {
|
264 |
+
|
265 |
+
// Start crawler reminder
|
266 |
+
$start_url = esc_url(WPLNST_Core_Plugin::get_url_scans_crawler($scan->id, 'on', $scan->hash));
|
267 |
+
$this->notice_success .= ' '.sprintf(__('The crawler for this scan is <strong>not started</strong>, you can <a href="%s">start the crawler</a> now.', 'wplnst'), $start_url);
|
268 |
+
}
|
269 |
+
}
|
270 |
+
}
|
271 |
+
}
|
272 |
+
|
273 |
+
|
274 |
+
|
275 |
+
}
|
admin/scans.php
ADDED
@@ -0,0 +1,936 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Admin Scans class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Admin
|
8 |
+
*/
|
9 |
+
class WPLNST_Admin_Scans {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
// Properties
|
14 |
+
// ---------------------------------------------------------------------------------------------------
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Parent object
|
20 |
+
*/
|
21 |
+
private $admin;
|
22 |
+
|
23 |
+
|
24 |
+
|
25 |
+
// Initialization
|
26 |
+
// ---------------------------------------------------------------------------------------------------
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Constructor
|
32 |
+
*/
|
33 |
+
public function __construct(&$admin, $menu) {
|
34 |
+
|
35 |
+
// Copy parent
|
36 |
+
$this->admin = &$admin;
|
37 |
+
|
38 |
+
// Scans menu
|
39 |
+
if ('context' == $menu) {
|
40 |
+
$this->scans_context();
|
41 |
+
|
42 |
+
// Check edit scan menu
|
43 |
+
} elseif ('edit' == $menu) {
|
44 |
+
$this->scans_edit();
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Scans menu
|
52 |
+
*/
|
53 |
+
private function scans_context() {
|
54 |
+
|
55 |
+
// Check context
|
56 |
+
$context = empty($_GET['context'])? false : $_GET['context'];
|
57 |
+
|
58 |
+
// Check scan id parameter
|
59 |
+
$scan_id = empty($_GET['scan_id'])? 0 : (int) $_GET['scan_id'];
|
60 |
+
|
61 |
+
// Results context
|
62 |
+
if ('results' == $context) {
|
63 |
+
|
64 |
+
// Crawl results
|
65 |
+
$this->scans_results($scan_id);
|
66 |
+
|
67 |
+
// Crawling order
|
68 |
+
} elseif ('crawler' == $context) {
|
69 |
+
|
70 |
+
// Crawl check
|
71 |
+
$this->scans_crawler($scan_id);
|
72 |
+
|
73 |
+
// Delete context
|
74 |
+
} elseif ('delete' == $context) {
|
75 |
+
|
76 |
+
// Delete confirm
|
77 |
+
$this->scans_delete($scan_id);
|
78 |
+
|
79 |
+
// Edit
|
80 |
+
} elseif ('edit' == $context) {
|
81 |
+
|
82 |
+
// Show edit view
|
83 |
+
$this->scans_edit($scan_id);
|
84 |
+
|
85 |
+
// Default
|
86 |
+
} else {
|
87 |
+
|
88 |
+
// List of scans
|
89 |
+
$this->scans_list();
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
+
|
95 |
+
// Scans list
|
96 |
+
// ---------------------------------------------------------------------------------------------------
|
97 |
+
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Prepare the list of scans
|
102 |
+
*/
|
103 |
+
private function scans_list() {
|
104 |
+
|
105 |
+
// Retrieve scans
|
106 |
+
$scans = $this->admin->get_scans(array(
|
107 |
+
'setup_names' => true,
|
108 |
+
'order_by' => 'FIELD(status, "play", "wait", "queued", "stop", "end"), started_at DESC, enqueued_at ASC, created_at DESC',
|
109 |
+
'paged' => empty($_GET['paged'])? 0 : (int) $_GET['paged'],
|
110 |
+
));
|
111 |
+
|
112 |
+
// No isolated mode
|
113 |
+
$scans->isolated = false;
|
114 |
+
|
115 |
+
// Custom action view
|
116 |
+
add_action('wplnst_scans_list_view', array(&$this, 'scans_list_view'));
|
117 |
+
|
118 |
+
// Show admin screen
|
119 |
+
$this->admin->screen_view(array(
|
120 |
+
'scans' => $scans,
|
121 |
+
'wp_action' => 'wplnst_scans_list_view',
|
122 |
+
'add_item_text' => WPLNST_Admin::get_text('scan_new_add'),
|
123 |
+
'add_item_url' => WPLNST_Core_Plugin::get_url_scans_add(),
|
124 |
+
));
|
125 |
+
}
|
126 |
+
|
127 |
+
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Extension view to display the scans list
|
131 |
+
*/
|
132 |
+
public function scans_list_view($args) {
|
133 |
+
|
134 |
+
// Dependencies
|
135 |
+
wplnst_require('views', 'scans');
|
136 |
+
|
137 |
+
// Display table
|
138 |
+
$list = new WPLNST_Views_Scans($args['scans']);
|
139 |
+
$list->prepare_items();
|
140 |
+
$list->display();
|
141 |
+
}
|
142 |
+
|
143 |
+
|
144 |
+
|
145 |
+
// Scan results
|
146 |
+
// ---------------------------------------------------------------------------------------------------
|
147 |
+
|
148 |
+
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Prepare and display crawling results
|
152 |
+
*/
|
153 |
+
private function scans_results($scan_id) {
|
154 |
+
|
155 |
+
// Atempt to load scan
|
156 |
+
if (false === ($scan = $this->admin->get_scan_by_id($scan_id, true)))
|
157 |
+
return $this->admin->screen_scan_not_found(WPLNST_Admin::get_text('crawler_results'));
|
158 |
+
|
159 |
+
// Prepare scans data
|
160 |
+
$scans = (object) array(
|
161 |
+
'isolated' => true,
|
162 |
+
'rows' => array($scan),
|
163 |
+
);
|
164 |
+
|
165 |
+
// Check status param
|
166 |
+
$status_code = $status_level = false;
|
167 |
+
$status_test = isset($_GET['status'])? $_GET['status'] : false;
|
168 |
+
if (false !== $status_test) {
|
169 |
+
if (1 == strlen($status_test)) {
|
170 |
+
if ('0' == $status_test || in_array($status_test, $scan->status_levels))
|
171 |
+
$status_level = $status_test;
|
172 |
+
} elseif (3 == strlen($status_test)) {
|
173 |
+
$status_code = $status_test;
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
// Check object type param
|
178 |
+
$object_post_type = false;
|
179 |
+
$object_type = isset($_GET['otype'])? $_GET['otype'] : false;
|
180 |
+
if (false !== $object_type) {
|
181 |
+
if (!in_array($object_type, array_keys(WPLNST_Core_Types::get_objects_types()))) {
|
182 |
+
if (0 === strpos($object_type, 'posts_') && strlen($object_type) > 6) {
|
183 |
+
$object_post_type_test = mb_substr($object_type, 6);
|
184 |
+
if (in_array($object_post_type_test, $scan->post_types))
|
185 |
+
$object_post_type = $object_post_type_test;
|
186 |
+
}
|
187 |
+
$object_type = false;
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
// Check link type param
|
192 |
+
$link_type = isset($_GET['ltype'])? $_GET['ltype'] : false;
|
193 |
+
if (false !== $link_type && !in_array($link_type, array_keys(WPLNST_Core_Types::get_link_types())))
|
194 |
+
$link_type = false;
|
195 |
+
|
196 |
+
// Check ignored or not
|
197 |
+
$ignored_type = isset($_GET['ig'])? $_GET['ig'] : false;
|
198 |
+
if (false !== $ignored_type && !in_array($ignored_type, array_keys(WPLNST_Core_Types::get_ignored_types())))
|
199 |
+
$ignored_type = false;
|
200 |
+
|
201 |
+
// Check SEO links
|
202 |
+
$seo_link_type = isset($_GET['slt'])? $_GET['slt'] : false;
|
203 |
+
if (false !== $seo_link_type && !in_array($seo_link_type, array_keys(WPLNST_Core_Types::get_seo_link_types())))
|
204 |
+
$seo_link_type = false;
|
205 |
+
|
206 |
+
// Check protocol
|
207 |
+
$protocol_type = isset($_GET['pt'])? $_GET['pt'] : false;
|
208 |
+
if (false !== $protocol_type && !in_array($protocol_type, array_keys(WPLNST_Core_Types::get_protocol_types())))
|
209 |
+
$protocol_type = false;
|
210 |
+
|
211 |
+
// Check special
|
212 |
+
$special_type = isset($_GET['sp'])? $_GET['sp'] : false;
|
213 |
+
if (false !== $special_type && !in_array($special_type, array_keys(WPLNST_Core_Types::get_special_types())))
|
214 |
+
$special_type = false;
|
215 |
+
|
216 |
+
// Check action
|
217 |
+
$action_type = isset($_GET['ac'])? $_GET['ac'] : false;
|
218 |
+
if (false !== $action_type && !in_array($action_type, array_keys(WPLNST_Core_Types::get_action_types())))
|
219 |
+
$action_type = false;
|
220 |
+
|
221 |
+
// Check destination
|
222 |
+
$dest_type = isset($_GET['dtype'])? $_GET['dtype'] : false;
|
223 |
+
if (false !== $dest_type && !in_array($dest_type, array_keys(WPLNST_Core_Types::get_destination_types())))
|
224 |
+
$dest_type = false;
|
225 |
+
|
226 |
+
// Check order
|
227 |
+
$order_type = isset($_GET['or'])? $_GET['or'] : false;
|
228 |
+
if (false !== $order_type && !in_array($order_type, array_keys(WPLNST_Core_Types::get_crawl_order())) && !in_array($order_type, array_keys(WPLNST_Core_Types::get_order_types())))
|
229 |
+
$order_type = false;
|
230 |
+
|
231 |
+
// Check search URL
|
232 |
+
$search_url = $search_url_type = false;
|
233 |
+
$search_url_test = isset($_GET['surl'])? trim(stripslashes($_GET['surl'])) : false;
|
234 |
+
if (false !== $search_url_test && '' !== $search_url_test) {
|
235 |
+
$search_url = $search_url_test;
|
236 |
+
$search_url_type = isset($_GET['surlt'])? $_GET['surlt'] : false;
|
237 |
+
if (false !== $search_url_type && !in_array($search_url_type, array_keys(WPLNST_Core_Types::get_url_search_filters())))
|
238 |
+
$search_url_type = false;
|
239 |
+
}
|
240 |
+
|
241 |
+
// Check search anchor
|
242 |
+
$search_anchor = $search_anchor_type = false;
|
243 |
+
$search_anchor_test = isset($_GET['sanc'])? trim(stripslashes($_GET['sanc'])) : false;
|
244 |
+
if (false !== $search_anchor_test && '' !== $search_anchor_test) {
|
245 |
+
$search_anchor = $search_anchor_test;
|
246 |
+
$search_anchor_type = isset($_GET['sanct'])? $_GET['sanct'] : false;
|
247 |
+
if (false !== $search_anchor_type && !in_array($search_anchor_type, array_keys(WPLNST_Core_Types::get_anchor_search_filters())))
|
248 |
+
$search_anchor_type = false;
|
249 |
+
}
|
250 |
+
|
251 |
+
// Access scan data
|
252 |
+
$results = $this->admin->scans->get_scan_results(array(
|
253 |
+
'scan_id' => $scan->id,
|
254 |
+
'status_code' => $status_code,
|
255 |
+
'status_level' => $status_level,
|
256 |
+
'object_type' => $object_type,
|
257 |
+
'object_post_type' => $object_post_type,
|
258 |
+
'link_type' => $link_type,
|
259 |
+
'ignored_type' => $ignored_type,
|
260 |
+
'seo_link_type' => $seo_link_type,
|
261 |
+
'protocol_type' => $protocol_type,
|
262 |
+
'special_type' => $special_type,
|
263 |
+
'action_type' => $action_type,
|
264 |
+
'dest_type' => $dest_type,
|
265 |
+
'order_type' => $order_type,
|
266 |
+
'search_url' => $search_url,
|
267 |
+
'search_url_type' => $search_url_type,
|
268 |
+
'search_anchor' => $search_anchor,
|
269 |
+
'search_anchor_type' => $search_anchor_type,
|
270 |
+
'order_date' => $scan->crawl_order,
|
271 |
+
'paged' => empty($_GET['paged'])? 0 : (int) $_GET['paged'],
|
272 |
+
));
|
273 |
+
|
274 |
+
// Unknown error
|
275 |
+
if (false === $results)
|
276 |
+
return $this->admin->screen_unknown_error(WPLNST_Admin::get_text('crawler_results'));
|
277 |
+
|
278 |
+
// Define all results
|
279 |
+
$results->is_search = (false !== $object_type) || (false !== $object_post_type) || (false !== $link_type) || (false !== $ignored_type) || (false !== $seo_link_type) || (false !== $protocol_type) || (false !== $special_type) || (false !== $action_type) || (false !== $dest_type) || (false !== $search_url) || (false !== $search_anchor);
|
280 |
+
$results->is_all_results = (false === $status_code) && (false === $status_level) && !$results->is_search;
|
281 |
+
|
282 |
+
// Check total data
|
283 |
+
if ($results->total_rows > 0 && $results->is_all_results && (!isset($scan->summary['status_total']) || $scan->summary['status_total'] != $results->total_rows)) {
|
284 |
+
|
285 |
+
// Update total
|
286 |
+
$scan->summary['status_total'] = $results->total_rows;
|
287 |
+
$this->admin->scans->update_scan_summary($scan->id, array('status_total' => $scan->summary['status_total']));
|
288 |
+
}
|
289 |
+
|
290 |
+
// Results properties
|
291 |
+
$results->scan = $scan;
|
292 |
+
$results->isolated = false;
|
293 |
+
|
294 |
+
// Results filters
|
295 |
+
$results->status_code = $status_code;
|
296 |
+
$results->status_level = $status_level;
|
297 |
+
$results->object_type = $object_type;
|
298 |
+
$results->object_post_type = $object_post_type;
|
299 |
+
$results->link_type = $link_type;
|
300 |
+
$results->ignored_type = $ignored_type;
|
301 |
+
$results->seo_link_type = $seo_link_type;
|
302 |
+
$results->protocol_type = $protocol_type;
|
303 |
+
$results->special_type = $special_type;
|
304 |
+
$results->action_type = $action_type;
|
305 |
+
$results->destination_type = $dest_type;
|
306 |
+
$results->order_type = $order_type;
|
307 |
+
$results->search_url = $search_url;
|
308 |
+
$results->search_url_type = $search_url_type;
|
309 |
+
$results->search_anchor = $search_anchor;
|
310 |
+
$results->search_anchor_type = $search_anchor_type;
|
311 |
+
|
312 |
+
// Custom action view
|
313 |
+
add_action('wplnst_scans_results_view', array(&$this, 'scans_results_view'));
|
314 |
+
|
315 |
+
// Show admin screen
|
316 |
+
$this->admin->screen_view(array(
|
317 |
+
'scans' => $scans,
|
318 |
+
'results' => $results,
|
319 |
+
'wp_action' => 'wplnst_scans_results_view',
|
320 |
+
'title' => WPLNST_Admin::get_text('crawler_results'),
|
321 |
+
'add_item_text' => WPLNST_Admin::get_text('scan_new_add'),
|
322 |
+
'add_item_url' => WPLNST_Core_Plugin::get_url_scans_add(),
|
323 |
+
));
|
324 |
+
}
|
325 |
+
|
326 |
+
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Extension view to display the scans results list
|
330 |
+
*/
|
331 |
+
public function scans_results_view($args) {
|
332 |
+
|
333 |
+
// Scan results row actions
|
334 |
+
add_filter('wplnst_results_actions_url', array(&$this, 'scans_results_actions_url'), 10, 2);
|
335 |
+
add_filter('wplnst_results_actions_status', array(&$this, 'scans_results_actions_status'), 10, 2);
|
336 |
+
add_filter('wplnst_results_actions_anchor', array(&$this, 'scans_results_actions_anchor'), 10, 2);
|
337 |
+
|
338 |
+
// Display an isolated scan
|
339 |
+
if (isset($args['scans']))
|
340 |
+
$this->scans_list_view(array('scans' => $args['scans']));
|
341 |
+
|
342 |
+
// Handle the results view callback
|
343 |
+
add_action('wplnst_scans_results_view_display', array(&$this, 'scans_results_view_display'));
|
344 |
+
|
345 |
+
// Results list table
|
346 |
+
$this->scans_results_views_table($args);
|
347 |
+
}
|
348 |
+
|
349 |
+
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Show a list table for scan results
|
353 |
+
*/
|
354 |
+
protected function scans_results_views_table($args) {
|
355 |
+
wplnst_require('views', 'scans-results');
|
356 |
+
$list = new WPLNST_Views_Scans_Results($args['results']);
|
357 |
+
$list->prepare_items();
|
358 |
+
$list->display();
|
359 |
+
}
|
360 |
+
|
361 |
+
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Reserved for extra element before display results table
|
365 |
+
*/
|
366 |
+
public function scans_results_view_display() {}
|
367 |
+
|
368 |
+
|
369 |
+
|
370 |
+
/**
|
371 |
+
* Define column URL row actions
|
372 |
+
*/
|
373 |
+
public function scans_results_actions_url($actions, $item) {
|
374 |
+
|
375 |
+
// Check unlinked
|
376 |
+
if ($item['unlinked'])
|
377 |
+
return false;
|
378 |
+
|
379 |
+
// Check actions var
|
380 |
+
if (!isset($actions) || !is_array($actions))
|
381 |
+
$actions = array();
|
382 |
+
|
383 |
+
// More actions
|
384 |
+
$actions = apply_filters('wplnst_results_actions_url_extended', $actions, $item);
|
385 |
+
|
386 |
+
// Visit URL
|
387 |
+
$actions['wplnst-action-url-visit'] = '<a href="'.esc_url($item['url']).'" target="_blank">'.__('Visit', 'wplnst').'</a>';
|
388 |
+
|
389 |
+
// Done
|
390 |
+
return $actions;
|
391 |
+
}
|
392 |
+
|
393 |
+
|
394 |
+
|
395 |
+
/**
|
396 |
+
* Define column Status row actions
|
397 |
+
*/
|
398 |
+
public function scans_results_actions_status($actions, $item) {
|
399 |
+
|
400 |
+
// Check unlinked
|
401 |
+
if ($item['unlinked'])
|
402 |
+
return false;
|
403 |
+
|
404 |
+
// Check actions var
|
405 |
+
if (!isset($actions) || !is_array($actions))
|
406 |
+
$actions = array();
|
407 |
+
|
408 |
+
// More actions
|
409 |
+
$actions = apply_filters('wplnst_results_actions_status_extended', $actions, $item);
|
410 |
+
|
411 |
+
// Done
|
412 |
+
return $actions;
|
413 |
+
}
|
414 |
+
|
415 |
+
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Define column Anchor row actions
|
419 |
+
*/
|
420 |
+
public function scans_results_actions_anchor($actions, $item) {
|
421 |
+
|
422 |
+
// Check unlinked
|
423 |
+
if ($item['unlinked'])
|
424 |
+
return false;
|
425 |
+
|
426 |
+
// Check actions var
|
427 |
+
if (!isset($actions) || !is_array($actions))
|
428 |
+
$actions = array();
|
429 |
+
|
430 |
+
// More actions
|
431 |
+
$actions = apply_filters('wplnst_results_actions_anchor_extended', $actions, $item);
|
432 |
+
|
433 |
+
// Done
|
434 |
+
return $actions;
|
435 |
+
}
|
436 |
+
|
437 |
+
|
438 |
+
|
439 |
+
// Scan crawler
|
440 |
+
// ---------------------------------------------------------------------------------------------------
|
441 |
+
|
442 |
+
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Attemp to start or stop a crawler
|
446 |
+
*/
|
447 |
+
private function scans_crawler($scan_id) {
|
448 |
+
|
449 |
+
// Atempt to load scan
|
450 |
+
if (false === ($scan = $this->admin->get_scan_by_id($scan_id, true)))
|
451 |
+
return $this->admin->screen_scan_not_found(WPLNST_Admin::get_text('crawler_action'));
|
452 |
+
|
453 |
+
// Check valid operation
|
454 |
+
$operation = empty($_GET['operation'])? false : (in_array($_GET['operation'], array('on', 'off'))? $_GET['operation'] : false);
|
455 |
+
if (false === $operation)
|
456 |
+
return $this->admin->screen_invalid_data(WPLNST_Admin::get_text('crawler_action'));
|
457 |
+
|
458 |
+
// Initialize
|
459 |
+
$notice_error = false;
|
460 |
+
$notice_warning = false;
|
461 |
+
$notice_success = false;
|
462 |
+
|
463 |
+
// Check nonce
|
464 |
+
if (empty($_GET['nonce']) || !wp_verify_nonce($_GET['nonce'], 'scan-crawler-'.$scan->hash)) {
|
465 |
+
|
466 |
+
// Not valid data
|
467 |
+
return $this->admin->screen_invalid_nonce(WPLNST_Admin::get_text('crawler_action'));
|
468 |
+
|
469 |
+
// Check if is playing right now
|
470 |
+
} elseif ('on' == $operation && 'play' == $scan->status) {
|
471 |
+
|
472 |
+
// Already started
|
473 |
+
$notice_warning = __('The crawling process for this scan is already started.', 'wplnst');
|
474 |
+
|
475 |
+
// Check if is stopped right now
|
476 |
+
} elseif ('off' == $operation && in_array($scan->status, array('stop', 'wait'))) {
|
477 |
+
|
478 |
+
// Already started
|
479 |
+
$notice_warning = __('The crawling process for this scan is already stopped.', 'wplnst');
|
480 |
+
|
481 |
+
// Avoid ended scans
|
482 |
+
} elseif ('end' == $scan->status) {
|
483 |
+
|
484 |
+
// Not available scan
|
485 |
+
$notice_warning = __('This scan was completed and it is not possible to start again.', 'wplnst');
|
486 |
+
|
487 |
+
// Check submit form
|
488 |
+
} else {
|
489 |
+
|
490 |
+
// Stop current scan
|
491 |
+
if ('off' == $operation) {
|
492 |
+
|
493 |
+
// Remove queued flag if never started
|
494 |
+
if ('queued' == $scan->status && (empty($scan->row->started_at) || '0000-00-00 00:00:00' == $scan->row->started_at)) {
|
495 |
+
|
496 |
+
// Start current scan
|
497 |
+
if (!$this->admin->scans->unqueue_scan($scan->id)) {
|
498 |
+
|
499 |
+
// Something failed
|
500 |
+
$notice_error = __('Something went wrong and the unqueue process was failed.', 'wplnst');
|
501 |
+
|
502 |
+
// Done
|
503 |
+
} else {
|
504 |
+
|
505 |
+
// Updated
|
506 |
+
$notice_success = __('The crawler for this scan is back to the wait mode.', 'wplnst');
|
507 |
+
}
|
508 |
+
|
509 |
+
// Normal mode
|
510 |
+
} else {
|
511 |
+
|
512 |
+
// Start current scan
|
513 |
+
if (!$this->admin->scans->stop_scan($scan->id)) {
|
514 |
+
|
515 |
+
// Something failed
|
516 |
+
$notice_error = __('Something went wront and the crawler stop was failed.', 'wplnst');
|
517 |
+
|
518 |
+
// Done
|
519 |
+
} else {
|
520 |
+
|
521 |
+
// Updated
|
522 |
+
$notice_success = sprintf(__('The crawler for this scan is stopped. You can see its collected data in the <a href="%s">crawler results page</a>.', 'wplnst'), esc_url(WPLNST_Core_Plugin::get_url_scans_results($scan_id)));
|
523 |
+
}
|
524 |
+
}
|
525 |
+
|
526 |
+
// Run when cURL enabled
|
527 |
+
} elseif (wplnst_is_curl_enabled()) {
|
528 |
+
|
529 |
+
// Check max scans running
|
530 |
+
if (!$this->admin->scans->can_play_more_scans()) {
|
531 |
+
|
532 |
+
// Max scans allowed
|
533 |
+
$notice_error = WPLNST_Admin::get_text('max_scans');
|
534 |
+
|
535 |
+
// Queue scan
|
536 |
+
$this->admin->scans->queue_scan($scan->id);
|
537 |
+
|
538 |
+
// Check scan ready
|
539 |
+
} elseif (!$scan->ready) {
|
540 |
+
|
541 |
+
// Something failed
|
542 |
+
$notice_error = sprintf(__('You need to complete some critical values before start the crawler, please <a href="%s">edit this scan</a>.', 'wplnst'), WPLNST_Core_Plugin::get_url_scans_edit($scan->id));
|
543 |
+
|
544 |
+
// Start attempt
|
545 |
+
} else {
|
546 |
+
|
547 |
+
// Not continued
|
548 |
+
$continued = false;
|
549 |
+
|
550 |
+
// Register stopped time
|
551 |
+
if ('stop' == $scan->status || 'queued' == $scan->status) {
|
552 |
+
|
553 |
+
// Needed to be started before
|
554 |
+
if (empty($scan->row->started_at) || '0000-00-00 00:00:00' == $scan->row->started_at) {
|
555 |
+
|
556 |
+
// Remove stopped time
|
557 |
+
$this->admin->scans->remove_stopped_time($scan->id);
|
558 |
+
$this->admin->scans->update_scan_summary($scan->id, array('time_stopped' => 0));
|
559 |
+
|
560 |
+
// Check stopped time
|
561 |
+
} elseif (!empty($scan->row->stopped_at) && '0000-00-00 00:00:00' != $scan->row->stopped_at) {
|
562 |
+
|
563 |
+
// Continued
|
564 |
+
$continued = true;
|
565 |
+
|
566 |
+
// Calculate stopped time
|
567 |
+
$time_stopped = time() - strtotime($scan->row->stopped_at.' UTC');
|
568 |
+
$summary = $this->admin->scans->get_scan_summary($scan->id);
|
569 |
+
$time_stopped += isset($summary['time_stopped'])? (int) $summary['time_stopped'] : 0;
|
570 |
+
}
|
571 |
+
}
|
572 |
+
|
573 |
+
// Start current scan
|
574 |
+
if (!$this->admin->scans->play_scan($scan->id, $continued)) {
|
575 |
+
|
576 |
+
// Something failed
|
577 |
+
$notice_error = __('Something went wront and the crawler start was failed.', 'wplnst');
|
578 |
+
|
579 |
+
// Done
|
580 |
+
} else {
|
581 |
+
|
582 |
+
// Check salt file
|
583 |
+
if (empty($notice_warning) && !WPLNST_Core_Nonce::check_salt_file())
|
584 |
+
$notice_warning = WPLNST_Admin::get_text('no_salt');
|
585 |
+
|
586 |
+
// Update stopped time
|
587 |
+
if (isset($time_stopped))
|
588 |
+
$this->admin->scans->update_scan_summary($scan->id, array('time_stopped' => $time_stopped));
|
589 |
+
|
590 |
+
// Save default threads values
|
591 |
+
$this->admin->scans->set_scan_final_threads_options($scan->id, array(
|
592 |
+
'max_threads' => $scan->threads->max,
|
593 |
+
'connect_timeout' => $scan->threads->connect_timeout,
|
594 |
+
'request_timeout' => $scan->threads->request_timeout,
|
595 |
+
));
|
596 |
+
|
597 |
+
// Start process now if are not running scans
|
598 |
+
$this->scans_crawler_run($scan->id, $scan->hash);
|
599 |
+
|
600 |
+
// Updated
|
601 |
+
$notice_success = sprintf(__('The crawler is running, you can see its data in the <a href="%s">crawler results page</a>.', 'wplnst'), esc_url(WPLNST_Core_Plugin::get_url_scans_results($scan_id)));
|
602 |
+
}
|
603 |
+
}
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
// Reload scan
|
608 |
+
if (false === ($scan = $this->admin->get_scan_by_id($scan_id, true, true)))
|
609 |
+
return $this->admin->screen_scan_not_found(WPLNST_Admin::get_text('crawler_action'));
|
610 |
+
|
611 |
+
// Prepare scans data
|
612 |
+
$scans = (object) array(
|
613 |
+
'isolated' => true,
|
614 |
+
'rows' => array($scan),
|
615 |
+
);
|
616 |
+
|
617 |
+
// Custom action view
|
618 |
+
add_action('wplnst_scans_crawler_view', array(&$this, 'scans_list_view'));
|
619 |
+
|
620 |
+
// Screen showing the start crawling process
|
621 |
+
$this->admin->screen_view(array(
|
622 |
+
'scans' => $scans,
|
623 |
+
'title' => WPLNST_Admin::get_text('crawler_action'),
|
624 |
+
'notice_error' => $notice_error,
|
625 |
+
'notice_warning' => $notice_warning,
|
626 |
+
'notice_success' => $notice_success,
|
627 |
+
'wp_action' => 'wplnst_scans_crawler_view',
|
628 |
+
'add_item_text' => WPLNST_Admin::get_text('scan_new_add'),
|
629 |
+
'add_item_url' => WPLNST_Core_Plugin::get_url_scans_add(),
|
630 |
+
));
|
631 |
+
|
632 |
+
// Check for queued scans
|
633 |
+
WPLNST_Core_Alive::activity(true);
|
634 |
+
}
|
635 |
+
|
636 |
+
|
637 |
+
|
638 |
+
/**
|
639 |
+
* Wrapper function to run scan from Alive class
|
640 |
+
*/
|
641 |
+
protected function scans_crawler_run($scan_id, $hash) {
|
642 |
+
WPLNST_Core_Alive::run($scan_id, $hash);
|
643 |
+
}
|
644 |
+
|
645 |
+
|
646 |
+
|
647 |
+
// Scan delete
|
648 |
+
// ---------------------------------------------------------------------------------------------------
|
649 |
+
|
650 |
+
|
651 |
+
|
652 |
+
/**
|
653 |
+
* Attemp to remove a scan
|
654 |
+
*/
|
655 |
+
private function scans_delete($scan_id) {
|
656 |
+
|
657 |
+
// Initialize
|
658 |
+
$notice_success = false;
|
659 |
+
$notice_warning = false;
|
660 |
+
|
661 |
+
// Check multiple scans
|
662 |
+
if (isset($_GET['scan_id']) && '-' == mb_substr($_GET['scan_id'], 0, 1)) {
|
663 |
+
|
664 |
+
// Check nonce
|
665 |
+
if (empty($_GET['nonce']) || !wp_verify_nonce($_GET['nonce'], 'bulk-scans-delete'))
|
666 |
+
return $this->admin->screen_invalid_nonce(WPLNST_Admin::get_text('scan_delete'));
|
667 |
+
|
668 |
+
// Check confirmation
|
669 |
+
if (empty($_GET['confirm']) || 'on' != $_GET['confirm']) {
|
670 |
+
|
671 |
+
// Confirm message
|
672 |
+
$notice_warning = sprintf(__('Sorry, we need a confirmation action. Please click here to <a href="%s" class="wplnst-scan-delete" data-confirm="%s">delete scan</a>', 'wplnst'), esc_url(WPLNST_Core_Plugin::get_url_scans_delete($_GET['scan_id'], 'bulk-scans-delete')), esc_attr(WPLNST_Admin::get_text('scan_delete_confirm')));
|
673 |
+
|
674 |
+
// Done
|
675 |
+
} else {
|
676 |
+
|
677 |
+
// Timeouts
|
678 |
+
set_time_limit(0);
|
679 |
+
|
680 |
+
// Initialize
|
681 |
+
$scans = array();
|
682 |
+
|
683 |
+
// Extract identifiers
|
684 |
+
$ids = array_map('intval', explode('-', trim($_GET['scan_id'], '-')));
|
685 |
+
foreach ($ids as $scan_id) {
|
686 |
+
if (!empty($scan_id) && false !== ($scan = $this->admin->get_scan_by_id($scan_id)))
|
687 |
+
$scans[] = $scan_id;
|
688 |
+
}
|
689 |
+
|
690 |
+
// Check data
|
691 |
+
if (empty($scans))
|
692 |
+
return $this->admin->screen_invalid_data(WPLNST_Admin::get_text('scan_delete'));
|
693 |
+
|
694 |
+
// Enum and remove
|
695 |
+
foreach ($scans as $scan_id)
|
696 |
+
$this->admin->scans->delete_scan($scan_id);
|
697 |
+
|
698 |
+
// Success message
|
699 |
+
$notice_success = __('The scans have been removed.', 'wplnst');
|
700 |
+
}
|
701 |
+
|
702 |
+
// Single
|
703 |
+
} else {
|
704 |
+
|
705 |
+
// Atempt to load scan
|
706 |
+
if (false === ($scan = $this->admin->get_scan_by_id($scan_id)))
|
707 |
+
return $this->admin->screen_scan_not_found(WPLNST_Admin::get_text('scan_delete'));
|
708 |
+
|
709 |
+
// Check nonce
|
710 |
+
if (empty($_GET['nonce']) || !wp_verify_nonce($_GET['nonce'], $scan->hash))
|
711 |
+
return $this->admin->screen_invalid_nonce(WPLNST_Admin::get_text('scan_delete'));
|
712 |
+
|
713 |
+
// Check confirmation
|
714 |
+
if (empty($_GET['confirm']) || 'on' != $_GET['confirm']) {
|
715 |
+
|
716 |
+
// Confirm message
|
717 |
+
$notice_warning = sprintf(__('Sorry, we need a confirmation action. Please click here to <a href="%s" class="wplnst-scan-delete-isolated" data-confirm-delete="%s">delete scan</a>', 'wplnst'), esc_url(WPLNST_Core_Plugin::get_url_scans_delete($scan->id, $scan->hash)), esc_attr(WPLNST_Admin::get_text('scan_delete_confirm')));
|
718 |
+
|
719 |
+
// Done
|
720 |
+
} else {
|
721 |
+
|
722 |
+
// Remove scan
|
723 |
+
$this->admin->scans->delete_scan($scan_id);
|
724 |
+
|
725 |
+
// Success message
|
726 |
+
$notice_success = __('The scan has been removed.', 'wplnst');
|
727 |
+
}
|
728 |
+
}
|
729 |
+
|
730 |
+
// Custom action view
|
731 |
+
add_action('wplnst_scans_delete_view', array(&$this, 'scans_delete_view'));
|
732 |
+
|
733 |
+
// Show admin screen
|
734 |
+
$this->admin->screen_view(array(
|
735 |
+
'title' => WPLNST_Admin::get_text('scan_delete'),
|
736 |
+
'notice_success' => $notice_success,
|
737 |
+
'notice_warning' => $notice_warning,
|
738 |
+
'wp_action' => 'wplnst_scans_delete_view',
|
739 |
+
'add_item_text' => WPLNST_Admin::get_text('scan_new_add'),
|
740 |
+
'add_item_url' => WPLNST_Core_Plugin::get_url_scans_add(),
|
741 |
+
));
|
742 |
+
|
743 |
+
// Check for queued scans
|
744 |
+
WPLNST_Core_Alive::activity(true);
|
745 |
+
}
|
746 |
+
|
747 |
+
|
748 |
+
|
749 |
+
/**
|
750 |
+
* Extension view when scan deleted
|
751 |
+
*/
|
752 |
+
public function scans_delete_view($args) {
|
753 |
+
|
754 |
+
// Back to the scans screen
|
755 |
+
echo '<p> « <a href="'.WPLNST_Core_Plugin::get_url_scans().'">'.__('Back to the scans list', 'wplnst').'</a></p>';
|
756 |
+
}
|
757 |
+
|
758 |
+
|
759 |
+
|
760 |
+
// New scan or edit
|
761 |
+
// ---------------------------------------------------------------------------------------------------
|
762 |
+
|
763 |
+
|
764 |
+
|
765 |
+
/**
|
766 |
+
* New or edit scan
|
767 |
+
*/
|
768 |
+
private function scans_edit($scan_id = 0) {
|
769 |
+
|
770 |
+
// Scans library
|
771 |
+
$this->admin->load_scans_object();
|
772 |
+
|
773 |
+
// Notice initialization
|
774 |
+
$notice_error = isset($this->admin->scan_submit)? $this->admin->scan_submit->notice_error : false;
|
775 |
+
$notice_warning = isset($this->admin->scan_submit)? $this->admin->scan_submit->notice_warning : false;
|
776 |
+
$notice_success = isset($this->admin->scan_submit)? $this->admin->scan_submit->notice_success : false;
|
777 |
+
$notice_crawler = isset($this->admin->scan_submit)? $this->admin->scan_submit->notice_crawler : false;
|
778 |
+
|
779 |
+
// Check submit error
|
780 |
+
if ($notice_error) {
|
781 |
+
return $this->admin->screen_view(array(
|
782 |
+
'title' => WPLNST_Admin::get_text('scan_edit'),
|
783 |
+
'notice_error' => $notice_error,
|
784 |
+
));
|
785 |
+
}
|
786 |
+
|
787 |
+
// Check existing scan
|
788 |
+
if (!empty($scan_id)) {
|
789 |
+
|
790 |
+
// Atempt to load scan
|
791 |
+
if (false === ($scan = $this->admin->get_scan_by_id($scan_id, true)))
|
792 |
+
return $this->admin->screen_scan_not_found(WPLNST_Admin::get_text('scan_edit'));
|
793 |
+
|
794 |
+
// Check update
|
795 |
+
if (!$notice_success && !empty($_GET['updated']) && 'on' == $_GET['updated']) {
|
796 |
+
|
797 |
+
// New scan created
|
798 |
+
$notice_success = __('New scan added successfully.', 'wplnst');
|
799 |
+
|
800 |
+
// Check started argument
|
801 |
+
if (!empty($_GET['started'])) {
|
802 |
+
|
803 |
+
// Check max scans
|
804 |
+
if ('max_scans' == $_GET['started']) {
|
805 |
+
|
806 |
+
// Warning message
|
807 |
+
$notice_warning = WPLNST_Admin::get_text('max_scans');
|
808 |
+
|
809 |
+
// Check error
|
810 |
+
} elseif ('error' == $_GET['started']) {
|
811 |
+
|
812 |
+
// Warning message
|
813 |
+
$notice_warning = sprintf(__('Something went wrong trying to start the crawler for this new scan.'));
|
814 |
+
|
815 |
+
// Scan running
|
816 |
+
} elseif ('on' == $_GET['started']) {
|
817 |
+
|
818 |
+
// New crawler running
|
819 |
+
$notice_crawler = sprintf(__('The crawler for this new scan is running. You can see its data in the <a href="%s">crawler results page</a>.', 'wplnst'), esc_url(WPLNST_Core_Plugin::get_url_scans_results($scan_id)));
|
820 |
+
}
|
821 |
+
|
822 |
+
// Not started
|
823 |
+
} elseif ('wait' == $scan->status && $this->admin->scans->can_play_more_scans() && true === $this->admin->scans->is_scan_ready($scan)) {
|
824 |
+
|
825 |
+
// Invite to start the crawler
|
826 |
+
$start_url = esc_url(WPLNST_Core_Plugin::get_url_scans_crawler($scan->id, 'on', $scan->hash));
|
827 |
+
$notice_success .= ' '.sprintf(__('From now on you can <a href="%s">start the crawler</a>.', 'wplnst'), $start_url);
|
828 |
+
}
|
829 |
+
}
|
830 |
+
|
831 |
+
// Check salt file
|
832 |
+
if ('play' == $scan->status && empty($notice_warning) && !WPLNST_Core_Nonce::check_salt_file())
|
833 |
+
$notice_warning = WPLNST_Admin::get_text('no_salt');
|
834 |
+
}
|
835 |
+
|
836 |
+
// Default values
|
837 |
+
if (empty($scan)) {
|
838 |
+
|
839 |
+
// Prepare scan object
|
840 |
+
$scan = (object) array(
|
841 |
+
'id' => 0,
|
842 |
+
'name' => '',
|
843 |
+
'status' => 'wait',
|
844 |
+
'destination_type' => 'all',
|
845 |
+
'time_scope' => 'anytime',
|
846 |
+
'link_types' => array('links', 'images'),
|
847 |
+
'crawl_order' => 'desc',
|
848 |
+
'redir_status' => true,
|
849 |
+
'malformed' => true,
|
850 |
+
'notify_default' => true,
|
851 |
+
'notify_address' => false,
|
852 |
+
'notify_address_email' => '',
|
853 |
+
'post_types' => array('post', 'page'),
|
854 |
+
'post_status' => array('publish'),
|
855 |
+
'comment_types' => array(),
|
856 |
+
'check_comments' => false,
|
857 |
+
'check_blogroll' => false,
|
858 |
+
'status_levels' => array('2', '3', '4', '5'),
|
859 |
+
'status_codes' => array(),
|
860 |
+
'custom_fields' => array(),
|
861 |
+
'anchor_filters' => array(),
|
862 |
+
'include_urls' => array(),
|
863 |
+
'exclude_urls' => array(),
|
864 |
+
'html_attributes' => array(),
|
865 |
+
'filtered_query' => true,
|
866 |
+
'threads' => 0,
|
867 |
+
'connect_timeout' => 0,
|
868 |
+
'request_timeout' => 0,
|
869 |
+
);
|
870 |
+
|
871 |
+
// Check scan
|
872 |
+
} else {
|
873 |
+
|
874 |
+
// Analyze data
|
875 |
+
$ready = $this->admin->scans->is_scan_ready($scan);
|
876 |
+
$is_ready = (true === $ready);
|
877 |
+
|
878 |
+
// Prepare notifications
|
879 |
+
if (!$is_ready)
|
880 |
+
$notice_ready = $ready;
|
881 |
+
|
882 |
+
// Check ready update
|
883 |
+
if ($scan->ready != $is_ready)
|
884 |
+
$this->admin->scans->update_scan_ready($scan->id, $is_ready);
|
885 |
+
}
|
886 |
+
|
887 |
+
// Custom action view
|
888 |
+
add_action('wplnst_scans_edit_view', array(&$this, 'scans_edit_view'));
|
889 |
+
|
890 |
+
// Display page
|
891 |
+
$this->admin->screen_view(array(
|
892 |
+
'scan' => $scan,
|
893 |
+
'wp_action' => 'wplnst_scans_edit_view',
|
894 |
+
'destination_types' => WPLNST_Core_Types::get_destination_types(),
|
895 |
+
'time_scopes' => WPLNST_Core_Types::get_time_scopes(),
|
896 |
+
'link_types' => WPLNST_Core_Types::get_link_types(),
|
897 |
+
'crawl_order' => WPLNST_Core_Types::get_crawl_order(),
|
898 |
+
'custom_fields' => WPLNST_Core_Types::get_custom_fields(),
|
899 |
+
'anchor_filters' => WPLNST_Core_Types::get_anchor_filters(),
|
900 |
+
'url_filters' => WPLNST_Core_Types::get_url_filters(),
|
901 |
+
'html_attributes_having' => WPLNST_Core_Types::get_html_attributes_having(),
|
902 |
+
'html_attributes_operators' => WPLNST_Core_Types::get_html_attributes_operators(),
|
903 |
+
'post_types' => WPLNST_Core_Types::get_post_types(),
|
904 |
+
'post_status' => WPLNST_Core_Types::get_post_status(),
|
905 |
+
'comment_types' => WPLNST_Core_Types::get_comment_types(),
|
906 |
+
'status_levels' => WPLNST_Core_Types::get_status_levels(),
|
907 |
+
'status_codes' => WPLNST_Core_Types::get_status_codes(),
|
908 |
+
'nonce' => wp_create_nonce('scan-edit-'.(empty($scan->id)? '0' : $scan->hash)),
|
909 |
+
'action' => ($scan->id > 0)? WPLNST_Core_Plugin::get_url_scans_edit($scan->id) : WPLNST_Core_Plugin::get_url_scans_add(),
|
910 |
+
'title' => ($scan->id > 0)? WPLNST_Admin::get_text('scan_edit') : WPLNST_Admin::get_text('scan_new'),
|
911 |
+
'more_scans' => $this->admin->scans->can_play_more_scans(),
|
912 |
+
'notice_success' => $notice_success,
|
913 |
+
'notice_crawler' => $notice_crawler,
|
914 |
+
'notice_warning' => $notice_warning,
|
915 |
+
'notice_ready' => isset($notice_ready)? $notice_ready : false,
|
916 |
+
'default_max_threads' => wplnst_get_nsetting('max_threads'),
|
917 |
+
'default_connect_timeout' => wplnst_get_nsetting('connect_timeout'),
|
918 |
+
'default_request_timeout' => wplnst_get_nsetting('request_timeout'),
|
919 |
+
'add_item_text' => ($scan->id > 0 && 'wait' != $scan->status)? WPLNST_Admin::get_text('scan_new_add') : '',
|
920 |
+
'add_item_url' => ($scan->id > 0 && 'wait' != $scan->status)? WPLNST_Core_Plugin::get_url_scans_add() : '',
|
921 |
+
));
|
922 |
+
}
|
923 |
+
|
924 |
+
|
925 |
+
|
926 |
+
/**
|
927 |
+
* Extension view for the edit scan screen
|
928 |
+
*/
|
929 |
+
public function scans_edit_view($args) {
|
930 |
+
wplnst_require('views', 'scans-edit');
|
931 |
+
WPLNST_Views_Scans_Edit::view($args);
|
932 |
+
}
|
933 |
+
|
934 |
+
|
935 |
+
|
936 |
+
}
|
admin/settings.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Admin Settings class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Admin
|
8 |
+
*/
|
9 |
+
class WPLNST_Admin_Settings {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Constructor
|
15 |
+
*/
|
16 |
+
public function __construct(&$admin) {
|
17 |
+
|
18 |
+
// Initialize
|
19 |
+
$notice_success = $notice_error = false;
|
20 |
+
|
21 |
+
// Check submit
|
22 |
+
if (isset($_POST['settings_nonce'])) {
|
23 |
+
|
24 |
+
// Check nonce
|
25 |
+
if (!wp_verify_nonce($_POST['settings_nonce'], WPLNST_Core_Plugin::slug.'-settings'))
|
26 |
+
return $admin->screen_invalid_nonce(WPLNST_Admin::get_text('settings'));
|
27 |
+
|
28 |
+
// General update
|
29 |
+
update_option('wplnst_max_threads', (int) $_POST['tx-max-threads']);
|
30 |
+
update_option('wplnst_max_scans', (int) $_POST['tx-max-scans']);
|
31 |
+
update_option('wplnst_max_pack', (int) $_POST['tx-max-pack']);
|
32 |
+
update_option('wplnst_max_requests', (int) $_POST['tx-max-requests']);
|
33 |
+
update_option('wplnst_max_redirs', (int) $_POST['tx-max-redirs']);
|
34 |
+
update_option('wplnst_max_download', (int) $_POST['tx-max-download']);
|
35 |
+
update_option('wplnst_user_agent', stripslashes($_POST['tx-user-agent']));
|
36 |
+
|
37 |
+
// Timeouts update
|
38 |
+
update_option('wplnst_connect_timeout', (int) $_POST['tx-connect-timeout']);
|
39 |
+
update_option('wplnst_request_timeout', (int) $_POST['tx-request-timeout']);
|
40 |
+
update_option('wplnst_extra_timeout', (int) $_POST['tx-extra-timeout']);
|
41 |
+
update_option('wplnst_crawler_alive', (int) $_POST['tx-crawler-alive']);
|
42 |
+
update_option('wplnst_total_objects', (int) $_POST['tx-total-objects']);
|
43 |
+
update_option('wplnst_summary_status', (int) $_POST['tx-summary-status']);
|
44 |
+
update_option('wplnst_summary_phases', (int) $_POST['tx-summary-phases']);
|
45 |
+
update_option('wplnst_summary_objects', (int) $_POST['tx-summary-objects']);
|
46 |
+
|
47 |
+
// Advanced update
|
48 |
+
update_option('wplnst_recursion_limit', (int) $_POST['tx-recursion-limit']);
|
49 |
+
update_option('wplnst_mysql_calc_rows', empty($_POST['ck-mysql-calc-rows'])? 'off' : 'on');
|
50 |
+
update_option('wplnst_uninstall_data', empty($_POST['ck-uninstall-data'])? 'off' : 'on');
|
51 |
+
|
52 |
+
// Update notice
|
53 |
+
$notice_success = __('Settings updated', 'wplnst');
|
54 |
+
}
|
55 |
+
|
56 |
+
// Custom action view
|
57 |
+
add_action('wplnst_view_settings', array(&$this, 'view_settings'));
|
58 |
+
|
59 |
+
// Show settings screen
|
60 |
+
$admin->screen_view(array(
|
61 |
+
'title' => WPLNST_Admin::get_text('settings'),
|
62 |
+
'wp_action' => 'wplnst_view_settings',
|
63 |
+
'action' => WPLNST_Core_Plugin::get_url_settings(),
|
64 |
+
'nonce' => wp_create_nonce(WPLNST_Core_Plugin::slug.'-settings'),
|
65 |
+
'notice_success' => $notice_success,
|
66 |
+
'notice_error' => $notice_error,
|
67 |
+
));
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Extension view for settings page
|
74 |
+
*/
|
75 |
+
public function view_settings($args) {
|
76 |
+
wplnst_require('views', 'settings');
|
77 |
+
WPLNST_Views_Settings::view($args);
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
|
82 |
+
}
|
assets/css/admin.css
ADDED
@@ -0,0 +1,562 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
/* Tabs */
|
3 |
+
|
4 |
+
#wplnst-title {
|
5 |
+
margin-bottom: 5px;
|
6 |
+
}
|
7 |
+
|
8 |
+
#wplnst-tabs {
|
9 |
+
padding: 5px 0 0 15px;
|
10 |
+
}
|
11 |
+
|
12 |
+
.wplnst-tab {
|
13 |
+
display: none;
|
14 |
+
}
|
15 |
+
|
16 |
+
#wplnst-tabs.wplnst-tabs-scan-edit .wplnst-tab .form-table th {
|
17 |
+
width: 150px;
|
18 |
+
}
|
19 |
+
|
20 |
+
.wplnst-tab .form-table td {
|
21 |
+
vertical-align: top;
|
22 |
+
}
|
23 |
+
|
24 |
+
.wplnst-tab .form-table td.wplnst-list {
|
25 |
+
line-height: 1.9em;
|
26 |
+
}
|
27 |
+
|
28 |
+
.wplnst-tab .form-table td.wplnst-value {
|
29 |
+
padding-top: 20px;
|
30 |
+
line-height: 1.3em;
|
31 |
+
}
|
32 |
+
|
33 |
+
.wplnst-tab .form-table td.wplnst-value-list {
|
34 |
+
padding-top: 15px;
|
35 |
+
line-height: 1.9em;
|
36 |
+
}
|
37 |
+
|
38 |
+
.wplnst-tab-active {
|
39 |
+
display: block;
|
40 |
+
}
|
41 |
+
|
42 |
+
#wplnst-destination-type, #wplnst-time-scope, #wplnst-crawl-order {
|
43 |
+
width: 185px;
|
44 |
+
}
|
45 |
+
|
46 |
+
#wplnst-cf-new {
|
47 |
+
width: 215px;
|
48 |
+
}
|
49 |
+
|
50 |
+
a.wplnst-trash-editor, a.wplnst-trash-editor:hover {
|
51 |
+
color: #a00;
|
52 |
+
}
|
53 |
+
|
54 |
+
.wplnst-elist {
|
55 |
+
border: 0; display: none;
|
56 |
+
margin: 0 0 5px; padding: 0;
|
57 |
+
}
|
58 |
+
|
59 |
+
.wplnst-elist-visible { display: block; }
|
60 |
+
.wplnst-elist-readonly { margin: 0; }
|
61 |
+
|
62 |
+
.wplnst-elist tr {
|
63 |
+
margin-bottom: 10px;
|
64 |
+
}
|
65 |
+
|
66 |
+
.wplnst-elist tr td {
|
67 |
+
margin: 0; padding: 4px 5px;
|
68 |
+
}
|
69 |
+
|
70 |
+
.wplnst-elist tr td.wplnst-elist-val {
|
71 |
+
color: #5c5a5a;
|
72 |
+
background: #f9f9f9;
|
73 |
+
}
|
74 |
+
|
75 |
+
#wplnst-af-new { width: 361px; }
|
76 |
+
#wplnst-ius-new { width: 425px; }
|
77 |
+
#wplnst-eus-new { width: 425px; }
|
78 |
+
|
79 |
+
.wplnst-elist tr td.wplnst-cfs-val { width: 205px; }
|
80 |
+
.wplnst-elist tr td.wplnst-afs-val { width: 350px; }
|
81 |
+
.wplnst-elist tr td.wplnst-ius-val { width: 415px; }
|
82 |
+
.wplnst-elist tr td.wplnst-eus-val { width: 415px; }
|
83 |
+
|
84 |
+
.wplnst-elist tr td.wplnst-elist-type {
|
85 |
+
color: #6f6f6f;
|
86 |
+
}
|
87 |
+
|
88 |
+
.wplnst-elist tr td.wplnst-cfs-type { width: 53px; padding-left: 12px; }
|
89 |
+
.wplnst-elist tr td.wplnst-afs-type { width: 200px; padding-left: 0; }
|
90 |
+
.wplnst-elist tr td.wplnst-ius-type { width: 121px; padding-left: 14px; }
|
91 |
+
.wplnst-elist tr td.wplnst-eus-type { width: 121px; padding-left: 14px; }
|
92 |
+
|
93 |
+
.wplnst-elist tr td.wplnst-hes-ele { width: 55px; font-weight: bold; }
|
94 |
+
.wplnst-elist tr td.wplnst-hes-have { width: 87px; font-weight: bold; }
|
95 |
+
.wplnst-elist tr td.wplnst-hes-att { width: 125px; }
|
96 |
+
.wplnst-elist tr td.wplnst-hes-op { width: 112px; padding-left: 15px; font-weight: bold; }
|
97 |
+
.wplnst-elist tr td.wplnst-hes-val { width: 126px; }
|
98 |
+
|
99 |
+
.wplnst-elist tr td.wplnst-elist-close {
|
100 |
+
padding-left: 21px;
|
101 |
+
}
|
102 |
+
|
103 |
+
/* .wplnst-elist tr td.wplnst-afs-close { padding-left: 20px; } */
|
104 |
+
|
105 |
+
.wplnst-elist tr td.wplnst-elist-close .wplnst-elist-close-link {
|
106 |
+
display: block;
|
107 |
+
width: 16px; height: 16px;
|
108 |
+
outline: none; border: 0;
|
109 |
+
text-indent: -9999px;
|
110 |
+
background: url(../images/button-close.png) left top no-repeat;
|
111 |
+
}
|
112 |
+
|
113 |
+
.wplnst-elist tr td.wplnst-elist-close .wplnst-elist-close-link:hover {
|
114 |
+
background: url(../images/button-close-hover.png) left top no-repeat;
|
115 |
+
}
|
116 |
+
|
117 |
+
.wplnst-elist tr td.wplnst-elist-split {
|
118 |
+
height: 3px;
|
119 |
+
}
|
120 |
+
|
121 |
+
|
122 |
+
|
123 |
+
/* Scans */
|
124 |
+
|
125 |
+
strong.wplnst-scan-name {
|
126 |
+
display: block;
|
127 |
+
margin-bottom: 10px;
|
128 |
+
line-height: 1.7em;
|
129 |
+
}
|
130 |
+
|
131 |
+
strong.wplnst-scan-name img {
|
132 |
+
vertical-align: top;
|
133 |
+
}
|
134 |
+
|
135 |
+
.wplnst-scan-status {
|
136 |
+
font-size: x-small;
|
137 |
+
font-family: Arial;
|
138 |
+
font-weight: normal;
|
139 |
+
vertical-align: top;
|
140 |
+
text-transform: uppercase;
|
141 |
+
font-variant: small-caps;
|
142 |
+
margin: 0 2px 0 0; padding: 3px 4px 2px;
|
143 |
+
-moz-border-radius: 3px;
|
144 |
+
-webkit-border-radius: 3px;
|
145 |
+
border-radius: 3px;
|
146 |
+
-khtml-border-radius: 3px;
|
147 |
+
}
|
148 |
+
|
149 |
+
.wplnst-scan-status-play {
|
150 |
+
color: #fff;
|
151 |
+
background: #fa7900;
|
152 |
+
}
|
153 |
+
|
154 |
+
.wplnst-scan-status-queued {
|
155 |
+
color: #fff;
|
156 |
+
background: #7b7d7b;
|
157 |
+
}
|
158 |
+
|
159 |
+
.wplnst-scan-status-stop {
|
160 |
+
color: #fff;
|
161 |
+
background: #383838;
|
162 |
+
}
|
163 |
+
|
164 |
+
.wplnst-scan-status-wait {
|
165 |
+
color: #fff;
|
166 |
+
background: grey;
|
167 |
+
}
|
168 |
+
|
169 |
+
.wplnst-scan-status-end {
|
170 |
+
color: #fff;
|
171 |
+
background: #5e9b1c;
|
172 |
+
}
|
173 |
+
|
174 |
+
.wplnst-scan-status-line {
|
175 |
+
margin: 0 0 10px 1px;
|
176 |
+
}
|
177 |
+
|
178 |
+
.wplnst-scan-object-info {
|
179 |
+
color: #848585;
|
180 |
+
background: #e5e5e5;
|
181 |
+
margin: 0 4px 0 0;
|
182 |
+
padding: 3px 4px 3px 5px;
|
183 |
+
-moz-border-radius: 2px;
|
184 |
+
-webkit-border-radius: 2px;
|
185 |
+
border-radius: 2px;
|
186 |
+
-khtml-border-radius: 2px;
|
187 |
+
}
|
188 |
+
|
189 |
+
.wplnst-scan-object-running {
|
190 |
+
color: #56524e;
|
191 |
+
}
|
192 |
+
|
193 |
+
.wplnst-scan-object-wait {
|
194 |
+
background: #f2f2f2;
|
195 |
+
}
|
196 |
+
|
197 |
+
.wplnst-scan-object-completed {
|
198 |
+
color: #32373c;
|
199 |
+
}
|
200 |
+
|
201 |
+
.wplnst-scan-object-completed-end {
|
202 |
+
color: #5e6455;
|
203 |
+
}
|
204 |
+
|
205 |
+
.wplnst-scan-name-warning img {
|
206 |
+
padding-top: 2px;
|
207 |
+
}
|
208 |
+
|
209 |
+
.wplnst-scan-ready-info {
|
210 |
+
margin: 0 0 7px 1px;
|
211 |
+
padding: 0 0 0 23px;
|
212 |
+
background: url(../images/scan-launch.png) left 1px no-repeat;
|
213 |
+
}
|
214 |
+
|
215 |
+
.wplnst-scan-ready-info a {
|
216 |
+
font-weight: bold;
|
217 |
+
}
|
218 |
+
|
219 |
+
.wplnst-scan-time-info {
|
220 |
+
margin: 0 0 7px 1px;
|
221 |
+
padding: 0 0 0 23px;
|
222 |
+
background: url(../images/scan-clock.png) left 2px no-repeat;
|
223 |
+
}
|
224 |
+
|
225 |
+
.wplnst-scan-links-info {
|
226 |
+
margin: 0 0 7px 1px;
|
227 |
+
padding: 0 0 0 23px;
|
228 |
+
background: url(../images/scan-link.png) left 1px no-repeat;
|
229 |
+
}
|
230 |
+
|
231 |
+
.wplnst-scan-links-info strong {
|
232 |
+
color: #4b4b4b;
|
233 |
+
}
|
234 |
+
|
235 |
+
.wplnst-scan-time-info, .wplnst-scan-links-info {
|
236 |
+
color: #6f6f6f;
|
237 |
+
}
|
238 |
+
|
239 |
+
.wplnst-split-char {
|
240 |
+
color: #a5a5a5;
|
241 |
+
margin: 0 5px;
|
242 |
+
}
|
243 |
+
|
244 |
+
.wplnst-isolated-table {
|
245 |
+
margin-bottom: 8px;
|
246 |
+
}
|
247 |
+
|
248 |
+
.wplnst-col-input {
|
249 |
+
width: 40px;
|
250 |
+
}
|
251 |
+
|
252 |
+
.wplnst-col-info, .form-table td.wplnst-col-info {
|
253 |
+
padding: 17px 0 5px;
|
254 |
+
line-height: 1.7em;
|
255 |
+
}
|
256 |
+
|
257 |
+
|
258 |
+
|
259 |
+
/* Columns scan */
|
260 |
+
|
261 |
+
.column-wplnst-scans-name {
|
262 |
+
width: 40%;
|
263 |
+
}
|
264 |
+
|
265 |
+
.widefat td.column-wplnst-scans-name { padding-bottom: 15px; }
|
266 |
+
.widefat.wplnst-isolated-table td.column-wplnst-scans-name { padding-bottom: 6px; }
|
267 |
+
|
268 |
+
.column-wplnst-scans-configuration table, .widefat td.column-wplnst-scans-configuration table {
|
269 |
+
border-spacing: 0;
|
270 |
+
border-collapse: collapse;
|
271 |
+
margin: 0; padding: 0;
|
272 |
+
}
|
273 |
+
|
274 |
+
.column-wplnst-scans-configuration table td, .widefat td.column-wplnst-scans-configuration table td {
|
275 |
+
margin: 0; padding: 0 0 8px 0;
|
276 |
+
}
|
277 |
+
|
278 |
+
.column-wplnst-scans-configuration table td.wplnst-scans-configuration-row, .widefat td.column-wplnst-scans-configuration table td.wplnst-scans-configuration-row {
|
279 |
+
width: 100px;
|
280 |
+
}
|
281 |
+
|
282 |
+
.column-wplnst-scans-configuration table td strong, .widefat td.column-wplnst-scans-configuration table td strong {
|
283 |
+
color: #677476;
|
284 |
+
font-weight: bold;
|
285 |
+
}
|
286 |
+
|
287 |
+
|
288 |
+
|
289 |
+
/* Columns scan results */
|
290 |
+
|
291 |
+
.column-wplnst-url {
|
292 |
+
width: 33%;
|
293 |
+
}
|
294 |
+
|
295 |
+
.wplnst-row-url {
|
296 |
+
margin-bottom: 3px;
|
297 |
+
}
|
298 |
+
|
299 |
+
.wplnst-results-url-error-code {
|
300 |
+
color: #737373;
|
301 |
+
}
|
302 |
+
|
303 |
+
.wplnst-results-url-full {
|
304 |
+
color: #999;
|
305 |
+
}
|
306 |
+
|
307 |
+
.column-wplnst-status {
|
308 |
+
width: 21%;
|
309 |
+
}
|
310 |
+
|
311 |
+
.wplnst-url-status-code {
|
312 |
+
margin-bottom: 2px;
|
313 |
+
}
|
314 |
+
|
315 |
+
.wplnst-url-status-code-result {
|
316 |
+
font-weight: bold;
|
317 |
+
}
|
318 |
+
|
319 |
+
.wplnst-url-status-code-0 {
|
320 |
+
color: black;
|
321 |
+
}
|
322 |
+
|
323 |
+
.wplnst-url-status-code-2 {
|
324 |
+
color: green;
|
325 |
+
}
|
326 |
+
|
327 |
+
.wplnst-url-status-code-3 {
|
328 |
+
color: #ff8c00;
|
329 |
+
}
|
330 |
+
|
331 |
+
.wplnst-url-status-code-4 {
|
332 |
+
color: red;
|
333 |
+
}
|
334 |
+
|
335 |
+
.wplnst-url-status-code-redir {
|
336 |
+
font-weight: bold;
|
337 |
+
}
|
338 |
+
|
339 |
+
.wplnst-url-status-code-redir-arrow {
|
340 |
+
font-weight: normal;
|
341 |
+
}
|
342 |
+
|
343 |
+
.wplnst-url-status-info {
|
344 |
+
color: #7a7a7a;
|
345 |
+
margin-bottom: 2px;
|
346 |
+
}
|
347 |
+
|
348 |
+
.wplnst-url-status-info-split {
|
349 |
+
color: #ccc;
|
350 |
+
vertical-align: top;
|
351 |
+
}
|
352 |
+
|
353 |
+
.column-wplnst-anchor {
|
354 |
+
width: 24%;
|
355 |
+
}
|
356 |
+
|
357 |
+
.wplnst-anchor-image:before {
|
358 |
+
content: "\f128";
|
359 |
+
font-size: 1.1em;
|
360 |
+
}
|
361 |
+
|
362 |
+
.column-wplnst-content {
|
363 |
+
width: 22%;
|
364 |
+
}
|
365 |
+
|
366 |
+
.wplnst-row-dashicon {
|
367 |
+
margin-bottom: 5px;
|
368 |
+
}
|
369 |
+
|
370 |
+
.wplnst-row-dashicon span {
|
371 |
+
padding-left: 2px;
|
372 |
+
}
|
373 |
+
|
374 |
+
.wplnst-row-dashicon:before {
|
375 |
+
font-family: "dashicons";
|
376 |
+
padding-right: 3px;
|
377 |
+
vertical-align: middle;
|
378 |
+
color: #849699;
|
379 |
+
}
|
380 |
+
|
381 |
+
.wplnst-content-post:before {
|
382 |
+
content: "\f109";
|
383 |
+
}
|
384 |
+
|
385 |
+
.wplnst-content-comment:before {
|
386 |
+
content: "\f101";
|
387 |
+
}
|
388 |
+
|
389 |
+
.wplnst-content-bookmark:before {
|
390 |
+
content: "\f103";
|
391 |
+
}
|
392 |
+
|
393 |
+
|
394 |
+
|
395 |
+
/* Results mark */
|
396 |
+
|
397 |
+
.wplnst-results-mark {
|
398 |
+
font-size: xx-small;
|
399 |
+
font-family: Arial;
|
400 |
+
font-weight: normal !important;
|
401 |
+
vertical-align: top;
|
402 |
+
text-transform: uppercase;
|
403 |
+
font-variant: small-caps;
|
404 |
+
color: #fff;
|
405 |
+
margin: 0; padding: 1px 2px;
|
406 |
+
border: 1px solid #fff;
|
407 |
+
-webkit-border-radius: 3px;
|
408 |
+
-moz-border-radius: 3px;
|
409 |
+
border-radius: 3px;
|
410 |
+
-khtml-border-radius: 3px;
|
411 |
+
}
|
412 |
+
|
413 |
+
.wplnst-results-mark-rechecked {
|
414 |
+
padding: 0px 1px;
|
415 |
+
background: #aa98a9;
|
416 |
+
border-color: #aa98a9;
|
417 |
+
}
|
418 |
+
|
419 |
+
.wplnst-results-mark-unlinked {
|
420 |
+
margin-right: 5px;
|
421 |
+
padding: 2px 3px 1px;
|
422 |
+
background: #8f9779;
|
423 |
+
border-color: #8f9779;
|
424 |
+
}
|
425 |
+
|
426 |
+
.wplnst-results-mark-modified {
|
427 |
+
background: #dd855c;
|
428 |
+
border-color: #dd855c;
|
429 |
+
}
|
430 |
+
|
431 |
+
.wplnst-results-mark-nofollow {
|
432 |
+
background: #f96161;
|
433 |
+
border-color: #f96161;
|
434 |
+
}
|
435 |
+
|
436 |
+
.wplnst-results-mark-relative {
|
437 |
+
background: #ff99cc;
|
438 |
+
border-color: #ff99cc;
|
439 |
+
}
|
440 |
+
|
441 |
+
.wplnst-results-mark-absolute {
|
442 |
+
background: #ff77aa;
|
443 |
+
border-color: #ff77aa;
|
444 |
+
}
|
445 |
+
|
446 |
+
.wplnst-results-mark-spaced {
|
447 |
+
background: #e1c348;
|
448 |
+
border-color: #e1c348;
|
449 |
+
}
|
450 |
+
|
451 |
+
.wplnst-results-mark-malformed {
|
452 |
+
background: #fe0000;
|
453 |
+
border-color: #fe0000;
|
454 |
+
}
|
455 |
+
|
456 |
+
.wplnst-results-mark-https {
|
457 |
+
background: #b5bc67;
|
458 |
+
border-color: #b5bc67;
|
459 |
+
}
|
460 |
+
|
461 |
+
.wplnst-results-mark-protorel {
|
462 |
+
background: #662f44;
|
463 |
+
border-color: #662f44;
|
464 |
+
}
|
465 |
+
|
466 |
+
.wplnst-results-mark-ignored {
|
467 |
+
background: #afbec0;
|
468 |
+
border-color: #afbec0;
|
469 |
+
}
|
470 |
+
|
471 |
+
.wplnst-results-mark-redirs {
|
472 |
+
background: #69b2ac;
|
473 |
+
border-color: #69b2ac;
|
474 |
+
}
|
475 |
+
|
476 |
+
.wplnst-results-anchor-mod {
|
477 |
+
margin: 1px 0;
|
478 |
+
}
|
479 |
+
|
480 |
+
.wplnst-results-url-marks {
|
481 |
+
margin: 2px 0 0;
|
482 |
+
}
|
483 |
+
|
484 |
+
.wplnst-results-url-marks .wplnst-results-mark {
|
485 |
+
margin-right: 5px;
|
486 |
+
}
|
487 |
+
|
488 |
+
|
489 |
+
|
490 |
+
/* levels menu */
|
491 |
+
|
492 |
+
#wplnst-levels-menu {
|
493 |
+
background: #f9f9f9;
|
494 |
+
border: 1px solid #e5e5e5;
|
495 |
+
padding: 2px 5px; margin: 0 0 1px;
|
496 |
+
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
|
497 |
+
box-shadow: 0 1px 1px rgba(0,0,0,0.04);
|
498 |
+
}
|
499 |
+
|
500 |
+
#wplnst-levels-menu.wplnst-levels-menu-isolated {
|
501 |
+
margin-bottom: 7px;
|
502 |
+
}
|
503 |
+
|
504 |
+
#wplnst-levels-menu .subsubsub {
|
505 |
+
margin: 0; padding: 0;
|
506 |
+
}
|
507 |
+
|
508 |
+
.wplnst-aproximate-total {
|
509 |
+
color: #777;
|
510 |
+
padding-top: 4px;
|
511 |
+
}
|
512 |
+
|
513 |
+
|
514 |
+
|
515 |
+
/* Extensions */
|
516 |
+
|
517 |
+
#wplnst-extensions {
|
518 |
+
width: 800px;
|
519 |
+
}
|
520 |
+
|
521 |
+
.wplnst-extensions-section {
|
522 |
+
margin-bottom: 50px;
|
523 |
+
}
|
524 |
+
|
525 |
+
#wplnst-extensions h3 {
|
526 |
+
font-size: 1.4em;
|
527 |
+
letter-spacing: -1px;
|
528 |
+
}
|
529 |
+
|
530 |
+
#wplnst-extensions p {
|
531 |
+
font-size: 1.3em;
|
532 |
+
}
|
533 |
+
|
534 |
+
#wplnst-extensions img {
|
535 |
+
border: 1px solid #ccc;
|
536 |
+
}
|
537 |
+
|
538 |
+
|
539 |
+
|
540 |
+
/* common classes */
|
541 |
+
|
542 |
+
.wplnst-display-none {
|
543 |
+
display: none;
|
544 |
+
}
|
545 |
+
|
546 |
+
|
547 |
+
|
548 |
+
/* clearfix custom class */
|
549 |
+
|
550 |
+
.wplnst-clearfix:after {
|
551 |
+
visibility: hidden;
|
552 |
+
display: block;
|
553 |
+
font-size: 0;
|
554 |
+
content: " ";
|
555 |
+
clear: both;
|
556 |
+
height: 0;
|
557 |
+
}
|
558 |
+
.wplnst-clearfix { display: inline-block; }
|
559 |
+
/* start commented backslash hack \*/
|
560 |
+
* html .wplnst-clearfix { height: 1%; }
|
561 |
+
.wplnst-clearfix { display: block; }
|
562 |
+
/* close commented backslash hack */
|
assets/images/advanced-anchor.png
ADDED
Binary file
|
assets/images/advanced-close.png
ADDED
Binary file
|
assets/images/advanced-extended.png
ADDED
Binary file
|
assets/images/advanced-filters.png
ADDED
Binary file
|
assets/images/advanced-reset.png
ADDED
Binary file
|
assets/images/advanced-url.png
ADDED
Binary file
|
assets/images/button-close-hover.png
ADDED
Binary file
|
assets/images/button-close.png
ADDED
Binary file
|
assets/images/close.png
ADDED
Binary file
|
assets/images/extensions/pro-banner.jpg
ADDED
Binary file
|
assets/images/extensions/wpls-web-crawler-edit.png
ADDED
Binary file
|
assets/images/extensions/wpls-web-crawler-results-actions.png
ADDED
Binary file
|
assets/images/extensions/wpls-web-crawler-results-advanced.png
ADDED
Binary file
|
assets/images/extensions/wpls-web-crawler-url-tools-results.png
ADDED
Binary file
|
assets/images/extensions/wpls-web-crawler-url-tools.png
ADDED
Binary file
|
assets/images/loading.gif
ADDED
Binary file
|
assets/images/scan-clock.png
ADDED
Binary file
|
assets/images/scan-launch.png
ADDED
Binary file
|
assets/images/scan-link.png
ADDED
Binary file
|
assets/images/scan-warning.png
ADDED
Binary file
|
assets/images/search.png
ADDED
Binary file
|
assets/images/yes.png
ADDED
Binary file
|
assets/js/admin-edit.js
ADDED
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
;jQuery(document).ready(function($) {
|
2 |
+
|
3 |
+
|
4 |
+
|
5 |
+
var elist_index = {};
|
6 |
+
|
7 |
+
|
8 |
+
|
9 |
+
function elist_arrange(names) {
|
10 |
+
|
11 |
+
var rq = /\%quot\%/g;
|
12 |
+
var n, name, field, editable, f;
|
13 |
+
|
14 |
+
for (n in names) {
|
15 |
+
|
16 |
+
name = names[n];
|
17 |
+
field = $('#wplnst-scan-' + name).val();
|
18 |
+
field = ('' === field)? [] : JSON.parse(field);
|
19 |
+
if (!(field instanceof Array) || 0 == field.length)
|
20 |
+
continue;
|
21 |
+
|
22 |
+
elist_index[name] = field.length;
|
23 |
+
editable = ('true' == $('#wplnst-elist-' + name).attr('data-editable'));
|
24 |
+
|
25 |
+
if ('custom-fields' == name) {
|
26 |
+
for (f in field)
|
27 |
+
elist_add_row(name, elist_get_row(name, {'name' : field[f]['name'].esc_html().replace(rq, '"'), 'type' : field[f]['type'].esc_html().toUpperCase()}, editable), field[f]['index']);
|
28 |
+
|
29 |
+
} else if ('anchor-filters' == name) {
|
30 |
+
for (f in field)
|
31 |
+
elist_add_row(name, elist_get_row(name, {'value' : field[f]['value'].esc_html().replace(rq, '"'), 'type' : field[f]['type'].esc_html().replace('-', ' ')}, editable), field[f]['index']);
|
32 |
+
|
33 |
+
} else if ('include-urls' == name || 'exclude-urls' == name) {
|
34 |
+
for (f in field)
|
35 |
+
elist_add_row(name, elist_get_row(name, {'value' : field[f]['value'].esc_html().replace(rq, '"'), 'type' : field[f]['type'].esc_html().replace('-', ' ').replace('url ', 'URL ').replace(' url', ' URL').capitalize()}, editable), field[f]['index']);
|
36 |
+
|
37 |
+
} else if ('html-attributes' == name) {
|
38 |
+
for (f in field)
|
39 |
+
elist_add_row(name, elist_get_row('html-attributes', {'element' : field[f]['element'].esc_html(), 'having' : field[f]['having'].esc_html().replace('-', ' '), 'att' : field[f]['att'].esc_html().replace(rq, '"'), 'op' : field[f]['op'].esc_html().replace('-', ' '), 'value' : field[f]['value'].esc_html().replace(rq, '"')}, editable), field[f]['index']);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
|
46 |
+
function elist_add(name, value, inputs, row) {
|
47 |
+
|
48 |
+
var field = $('#wplnst-scan-' + name).val();
|
49 |
+
field = ('' === field)? [] : JSON.parse(field);
|
50 |
+
if (!(field instanceof Array) || field.length > 25)
|
51 |
+
return;
|
52 |
+
|
53 |
+
(name in elist_index)? elist_index[name]++ : elist_index[name] = 0;
|
54 |
+
value['index'] = elist_index[name];
|
55 |
+
field.push(value);
|
56 |
+
|
57 |
+
$('#wplnst-scan-' + name).val(JSON.stringify(field));
|
58 |
+
|
59 |
+
for (var i = 0; i < inputs.length; i++)
|
60 |
+
$('#' + inputs[i]).val('');
|
61 |
+
|
62 |
+
elist_add_row(name, row, value['index']);
|
63 |
+
}
|
64 |
+
|
65 |
+
|
66 |
+
|
67 |
+
function elist_add_row(name, row, index) {
|
68 |
+
row = row.replace(/\%class\-index\%/g, 'wplnst-' + name + '-' + index);
|
69 |
+
row = row.replace('%close%', '<a href="#" class="wplnst-elist-close-link" data-name = "' + name + '" data-index="' + index + '"> </a>');
|
70 |
+
$('#' + 'wplnst-elist-' + name).append(row);
|
71 |
+
$('#' + 'wplnst-elist-' + name).show();
|
72 |
+
}
|
73 |
+
|
74 |
+
|
75 |
+
|
76 |
+
function elist_get_row(name, args, editable) {
|
77 |
+
|
78 |
+
if ('custom-fields' == name)
|
79 |
+
return '<tr class="%class-index%"><td class="wplnst-elist-val wplnst-cfs-val">' + args['name'] + '</td><td class="wplnst-elist-type wplnst-cfs-type">' + args['type'] + '</td><td class="wplnst-elist-close">' + (editable? '%close%' : '') + '</td></tr><tr class="%class-index%"><td colspan="3" class="wplnst-elist-split"></td></tr>';
|
80 |
+
|
81 |
+
if ('anchor-filters' == name)
|
82 |
+
return '<tr class="%class-index%"><td class="wplnst-elist-type wplnst-afs-type">' + $('#wplnst-elist-anchor-filters').attr('data-label') + ' <strong>' + args['type'] + '</strong></td><td class="wplnst-elist-val wplnst-afs-val">' + args['value'] + '</td><td class="wplnst-elist-close wplnst-afs-close">' + (editable? '%close%' : '') + '</td></tr><tr class="%class-index%"><td colspan="3" class="wplnst-elist-split"></td></tr>';
|
83 |
+
|
84 |
+
if ('include-urls' == name)
|
85 |
+
return '<tr class="%class-index%"><td class="wplnst-elist-val wplnst-ius-val">' + args['value'] + '</td><td class="wplnst-elist-type wplnst-ius-type">' + args['type'] + '</td><td class="wplnst-elist-close">' + (editable? '%close%' : '') + '</td></tr><tr class="%class-index%"><td colspan="3" class="wplnst-elist-split"></td></tr>';
|
86 |
+
|
87 |
+
if ('exclude-urls' == name)
|
88 |
+
return '<tr class="%class-index%"><td class="wplnst-elist-val wplnst-eus-val">' + args['value'] + '</td><td class="wplnst-elist-type wplnst-eus-type">' + args['type'] + '</td><td class="wplnst-elist-close">' + (editable? '%close%' : '') + '</td></tr><tr class="%class-index%"><td colspan="3" class="wplnst-elist-split"></td></tr>';
|
89 |
+
|
90 |
+
if ('html-attributes' == name)
|
91 |
+
return '<tr class="%class-index%"><td class="wplnst-elist-type wplnst-hes-ele">' + args['element'] + '</td><td class="wplnst-elist-type wplnst-hes-have">' + args['having'] + '</td><td class="wplnst-elist-val wplnst-hes-att">' + args['att'] + '</td><td class="wplnst-elist-type wplnst-hes-op">' + args['op'] + '</td><td class="wplnst-elist-val wplnst-hes-val">' + args['value'] + '</td><td class="wplnst-elist-close">' + (editable? '%close%' : '') + '</td></tr><tr class="%class-index%"><td colspan="3" class="wplnst-elist-split"></td></tr>';
|
92 |
+
|
93 |
+
return false;
|
94 |
+
}
|
95 |
+
|
96 |
+
|
97 |
+
$('.wplnst-elist').on('click', '.wplnst-elist-close-link', function() {
|
98 |
+
|
99 |
+
var name = $(this).attr('data-name');
|
100 |
+
var index = $(this).attr('data-index');
|
101 |
+
|
102 |
+
var field = $('#wplnst-scan-' + name).val();
|
103 |
+
if ('' !== field) {
|
104 |
+
|
105 |
+
field = JSON.parse(field);
|
106 |
+
if (field instanceof Array) {
|
107 |
+
|
108 |
+
var field_new = [];
|
109 |
+
for (var i = 0; i < field.length; i++) {
|
110 |
+
if (index != field[i]['index'])
|
111 |
+
field_new.push(field[i]);
|
112 |
+
}
|
113 |
+
|
114 |
+
$('#wplnst-scan-' + name).val(JSON.stringify(field_new));
|
115 |
+
$('.wplnst-' + name + '-' + index).remove();
|
116 |
+
|
117 |
+
if (0 === field_new.length)
|
118 |
+
$('#' + 'wplnst-elist-' + name).hide();
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
122 |
+
return false;
|
123 |
+
});
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
$('.wplnst-status-level').click(function() {
|
128 |
+
var level = $(this).attr('id').replace('ck-status-level-', '');
|
129 |
+
$('.wplnst-code-level-' + level).prop('checked', false);
|
130 |
+
});
|
131 |
+
|
132 |
+
$('.wplnst-code-level').click(function() {
|
133 |
+
var level = $(this).attr('id').replace('ck-status-code-', '').charAt(0);
|
134 |
+
$('#ck-status-level-' + level).prop('checked', false);
|
135 |
+
});
|
136 |
+
|
137 |
+
|
138 |
+
|
139 |
+
$('#wplnst-save-and-run').click(function() {
|
140 |
+
$('#wplnst-scan-run').val('1');
|
141 |
+
$('#wplnst-form').submit();
|
142 |
+
});
|
143 |
+
|
144 |
+
|
145 |
+
|
146 |
+
$('#wplnst-cf-new-add').click(function() {
|
147 |
+
var name = $('#wplnst-cf-new').val().trim();
|
148 |
+
if ('' === name)
|
149 |
+
return;
|
150 |
+
elist_add('custom-fields', {'name' : name, 'type': $('#wplnst-cf-new-type').val()}, ['wplnst-cf-new'], elist_get_row('custom-fields', {'name' : name.esc_html(), 'type' : $('#wplnst-cf-new-type option:selected').text().esc_html()}, true));
|
151 |
+
});
|
152 |
+
|
153 |
+
$('#wplnst-cf-new').bind('keypress', function(e) {
|
154 |
+
if (e.keyCode == 13) {
|
155 |
+
$('#wplnst-cf-new-add').click();
|
156 |
+
return false;
|
157 |
+
}
|
158 |
+
});
|
159 |
+
|
160 |
+
|
161 |
+
|
162 |
+
$('#wplnst-af-new-add').click(function() {
|
163 |
+
var value = $('#wplnst-af-new').val().trim();
|
164 |
+
var type = $('#wplnst-af-new-type').val();
|
165 |
+
if ('' === value && 'empty' != type)
|
166 |
+
return;
|
167 |
+
elist_add('anchor-filters', {'value' : ('empty' != type)? value : '', 'type': type}, ['wplnst-af-new'], elist_get_row('anchor-filters', {'type' : $('#wplnst-af-new-type option:selected').text().esc_html().toLowerCase(), 'value' : ('empty' != type)? value.esc_html() : ''}, true));
|
168 |
+
});
|
169 |
+
|
170 |
+
$('#wplnst-af-new').bind('keypress', function(e) {
|
171 |
+
if (e.keyCode == 13) {
|
172 |
+
$('#wplnst-af-new-add').click();
|
173 |
+
return false;
|
174 |
+
}
|
175 |
+
});
|
176 |
+
|
177 |
+
$('#wplnst-af-new-type').change(function() {
|
178 |
+
var disabled = ('empty' == $(this).val());
|
179 |
+
$('#wplnst-af-new').attr('disabled', disabled);
|
180 |
+
});
|
181 |
+
|
182 |
+
|
183 |
+
|
184 |
+
$('#wplnst-ius-new-add').click(function() {
|
185 |
+
var value = $('#wplnst-ius-new').val().trim();
|
186 |
+
if ('' === value)
|
187 |
+
return;
|
188 |
+
elist_add('include-urls', {'value' : value, 'type': $('#wplnst-ius-new-type').val()}, ['wplnst-ius-new'], elist_get_row('include-urls', {'value' : value.esc_html(), 'type' : $('#wplnst-ius-new-type option:selected').text().esc_html()}, true));
|
189 |
+
});
|
190 |
+
|
191 |
+
$('#wplnst-ius-new').bind('keypress', function(e) {
|
192 |
+
if (e.keyCode == 13) {
|
193 |
+
$('#wplnst-ius-new-add').click();
|
194 |
+
return false;
|
195 |
+
}
|
196 |
+
});
|
197 |
+
|
198 |
+
|
199 |
+
|
200 |
+
$('#wplnst-eus-new-add').click(function() {
|
201 |
+
var value = $('#wplnst-eus-new').val().trim();
|
202 |
+
if ('' === value)
|
203 |
+
return;
|
204 |
+
elist_add('exclude-urls', {'value' : value, 'type': $('#wplnst-eus-new-type').val()}, ['wplnst-eus-new'], elist_get_row('exclude-urls', {'value' : value.esc_html(), 'type' : $('#wplnst-eus-new-type option:selected').text().esc_html()}, true));
|
205 |
+
});
|
206 |
+
|
207 |
+
$('#wplnst-eus-new').bind('keypress', function(e) {
|
208 |
+
if (e.keyCode == 13) {
|
209 |
+
$('#wplnst-eus-new-add').click();
|
210 |
+
return false;
|
211 |
+
}
|
212 |
+
});
|
213 |
+
|
214 |
+
|
215 |
+
|
216 |
+
$('#wplnst-hes-new-add').click(function() {
|
217 |
+
|
218 |
+
var att = $('#wplnst-hes-new-att').val().trim();
|
219 |
+
if ('' === att)
|
220 |
+
return;
|
221 |
+
|
222 |
+
var element = $('#wplnst-hes-new').val();
|
223 |
+
var having = $('#wplnst-hes-new-have').val();
|
224 |
+
|
225 |
+
var op = op_text = value = '';
|
226 |
+
if ('have' == having) {
|
227 |
+
|
228 |
+
var op = $('#wplnst-hes-new-op').val();
|
229 |
+
var op_text = $('#wplnst-hes-new-op option:selected').text().toLowerCase();
|
230 |
+
var value = '' + $('#wplnst-hes-new-val').val().trim();
|
231 |
+
|
232 |
+
if ('not-empty' == op || 'empty' == op) {
|
233 |
+
value = '';
|
234 |
+
} else if ('' === value) {
|
235 |
+
return;
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
elist_add(
|
240 |
+
'html-attributes',
|
241 |
+
{'att' : att, 'element' : element, 'having' : having, 'op' : op, 'value' : value},
|
242 |
+
['wplnst-hes-new-att', 'wplnst-hes-new-val'],
|
243 |
+
elist_get_row('html-attributes', {'element' : element.esc_html(), 'having' : $('#wplnst-hes-new-have option:selected').text().toLowerCase().esc_html(), 'att' : att.esc_html(), 'op' : op_text.esc_html(), 'value' : value.esc_html()}, true)
|
244 |
+
);
|
245 |
+
});
|
246 |
+
|
247 |
+
$('#wplnst-hes-new-att').bind('keypress', function(e) {
|
248 |
+
if (e.keyCode == 13) {
|
249 |
+
$('#wplnst-hes-new-add').click();
|
250 |
+
return false;
|
251 |
+
}
|
252 |
+
});
|
253 |
+
|
254 |
+
$('#wplnst-hes-new-val').bind('keypress', function(e) {
|
255 |
+
if (e.keyCode == 13) {
|
256 |
+
$('#wplnst-hes-new-add').click();
|
257 |
+
return false;
|
258 |
+
}
|
259 |
+
});
|
260 |
+
|
261 |
+
$('#wplnst-hes-new-have').change(function() {
|
262 |
+
var disabled = ('have' != $(this).val());
|
263 |
+
$('#wplnst-hes-new-op').attr('disabled', disabled);
|
264 |
+
$('#wplnst-hes-new-val').attr('disabled', disabled);
|
265 |
+
});
|
266 |
+
|
267 |
+
$('#wplnst-hes-new-op').change(function() {
|
268 |
+
$('#wplnst-hes-new-val').attr('disabled', ('empty' == $(this).val() || 'not-empty' == $(this).val()));
|
269 |
+
});
|
270 |
+
|
271 |
+
|
272 |
+
|
273 |
+
elist_arrange(['custom-fields', 'anchor-filters', 'include-urls', 'exclude-urls', 'html-attributes']);
|
274 |
+
|
275 |
+
|
276 |
+
|
277 |
+
});
|
assets/js/admin.js
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
;'use strict';
|
2 |
+
|
3 |
+
if (!String.prototype.trim) {(function() {
|
4 |
+
var r = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
|
5 |
+
String.prototype.trim = function() {
|
6 |
+
return this.replace(r, '');
|
7 |
+
};
|
8 |
+
})();};
|
9 |
+
|
10 |
+
if (!String.prototype.esc_html) {(function() {
|
11 |
+
var r = /[&<>"'\/]/g;
|
12 |
+
var entity_map = {'&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/'};
|
13 |
+
String.prototype.esc_html = function() {
|
14 |
+
return this.replace(r, function from_entity_map(s) {
|
15 |
+
return entity_map[s];
|
16 |
+
});
|
17 |
+
};
|
18 |
+
})();};
|
19 |
+
|
20 |
+
if (!String.prototype.capitalize) {
|
21 |
+
String.prototype.capitalize = function() {
|
22 |
+
return this.charAt(0).toUpperCase() + this.slice(1);
|
23 |
+
}
|
24 |
+
};
|
25 |
+
|
26 |
+
jQuery(document).ready(function($) {
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
$('#wplnst-tabs-nav').find('a.nav-tab').click(function() {
|
31 |
+
$('#wplnst-tabs-nav').find('a').removeClass('nav-tab-active');
|
32 |
+
$('.wplnst-tab').removeClass('wplnst-tab-active');
|
33 |
+
var id = $(this).attr('id').replace('-tab', '');
|
34 |
+
$('#' + id).addClass('wplnst-tab-active');
|
35 |
+
$(this).addClass('nav-tab-active');
|
36 |
+
var action = $('#wplnst-form').attr('action').split('#top#');
|
37 |
+
$('#wplnst-form').attr('action', action[0] + '#top#' + id);
|
38 |
+
});
|
39 |
+
|
40 |
+
if ($('.wplnst-tab-default').length) {
|
41 |
+
var active_tab = window.location.hash.replace('#top', '').replace('#wplnst-', '');
|
42 |
+
if ('' === active_tab || active_tab === '#_=_')
|
43 |
+
active_tab = $('.wplnst-tab-default').attr('id').replace('wplnst-', '');
|
44 |
+
$('#wplnst-' + active_tab).addClass('wplnst-tab-active');
|
45 |
+
$('#wplnst-' + active_tab + '-tab').addClass('nav-tab-active');
|
46 |
+
$('#wplnst-' + active_tab + '-tab').click();
|
47 |
+
if ('general' == active_tab && 0 == $('#wplnst-scan-id').val())
|
48 |
+
$('#tx-name').focus();
|
49 |
+
}
|
50 |
+
|
51 |
+
$('.wplnst-scan-delete').click(function() {
|
52 |
+
if (confirm($('#wplnst-scans').attr('data-confirm-delete'))) {
|
53 |
+
$(this).attr('href', $(this).attr('href') + '&confirm=on');
|
54 |
+
return true;
|
55 |
+
}
|
56 |
+
return false;
|
57 |
+
});
|
58 |
+
|
59 |
+
$('.wplnst-scan-delete-isolated').click(function() {
|
60 |
+
if (confirm($(this).attr('data-confirm-delete'))) {
|
61 |
+
$(this).attr('href', $(this).attr('href') + '&confirm=on');
|
62 |
+
return true;
|
63 |
+
}
|
64 |
+
return false;
|
65 |
+
});
|
66 |
+
|
67 |
+
|
68 |
+
|
69 |
+
$('.wplnst-remove-entry').click(function() {
|
70 |
+
return confirm($('#wplnst-results').attr('data-confirm-delete-entry'));
|
71 |
+
});
|
72 |
+
|
73 |
+
$('.wplnst-remove-comment').click(function() {
|
74 |
+
return confirm($('#wplnst-results').attr('data-confirm-delete-comment'));
|
75 |
+
});
|
76 |
+
|
77 |
+
$('.wplnst-remove-bookmark').click(function() {
|
78 |
+
return confirm($('#wplnst-results').attr('data-confirm-delete-bookmark'));
|
79 |
+
});
|
80 |
+
|
81 |
+
|
82 |
+
|
83 |
+
|
84 |
+
$('.wplnst-scans-bulkactions-top .button.action').click(function() {
|
85 |
+
scans_bulkactions($('#bulk-action-selector-top').val());
|
86 |
+
return false;
|
87 |
+
});
|
88 |
+
|
89 |
+
$('.wplnst-scans-bulkactions-bottom .button.action').click(function() {
|
90 |
+
scans_bulkactions($('#bulk-action-selector-bottom').val());
|
91 |
+
return false;
|
92 |
+
});
|
93 |
+
|
94 |
+
function scans_bulkactions(action) {
|
95 |
+
|
96 |
+
if ('delete' == action) {
|
97 |
+
|
98 |
+
var checked = [];
|
99 |
+
$('input[type=checkbox].wplnst-ck-scan-id').each(function() {
|
100 |
+
if ($(this).is(':checked'))
|
101 |
+
checked.push($(this).val());
|
102 |
+
});
|
103 |
+
|
104 |
+
if (checked.length > 0) {
|
105 |
+
if (confirm($('#wplnst-scans').attr('data-confirm-delete-bulk')))
|
106 |
+
window.location.href = $('#wplnst-scans').attr('data-href-delete').replace('%scan_id%', '-' + checked.join('-')) + '&confirm=on';
|
107 |
+
}
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
|
112 |
+
|
113 |
+
$('#wplnst-filter-button').click(function() {
|
114 |
+
var args = '', value;
|
115 |
+
var fields = $(this).attr('data-fields').split(',');
|
116 |
+
for (var i in fields) {
|
117 |
+
value = $('#wplnst-filter-' + fields[i]).val();
|
118 |
+
if (typeof value != 'undefined' && '' !== value)
|
119 |
+
args += '&' + fields[i] + '=' + value;
|
120 |
+
}
|
121 |
+
window.location.href = $(this).attr('data-href') + args;
|
122 |
+
return false;
|
123 |
+
});
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
$('#current-page-selector').keydown(function(e) {
|
128 |
+
if (e.keyCode == 13) {
|
129 |
+
var paged = parseInt($(this).val(), 10);
|
130 |
+
var pages = parseInt($('.total-pages').first().text(), 10);
|
131 |
+
window.location.href = $(this).closest('form').attr('action') + ((paged > 1)? '&paged=' + ((paged > pages)? pages : paged) : '');
|
132 |
+
return false;
|
133 |
+
}
|
134 |
+
});
|
135 |
+
|
136 |
+
|
137 |
+
|
138 |
+
});
|
assets/js/lightboxed/LICENSE
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
2 |
+
you may not use this file except in compliance with the License.
|
3 |
+
You may obtain a copy of the License at
|
4 |
+
|
5 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
6 |
+
|
7 |
+
Unless required by applicable law or agreed to in writing, software
|
8 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
9 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10 |
+
See the License for the specific language governing permissions and
|
11 |
+
limitations under the License.
|
assets/js/lightboxed/jquery.lightboxed.js
ADDED
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* $ lightboxed 1.0
|
3 |
+
* By Pau Iglesias on seedplugins.com
|
4 |
+
*
|
5 |
+
* Based on lightbox_me 2.4 by Buck Wilson
|
6 |
+
*
|
7 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
8 |
+
* you may not use this file except in compliance with the License.
|
9 |
+
* You may obtain a copy of the License at
|
10 |
+
*
|
11 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
12 |
+
*
|
13 |
+
* Unless required by applicable law or agreed to in writing, software
|
14 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
15 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16 |
+
* See the License for the specific language governing permissions and
|
17 |
+
* limitations under the License.
|
18 |
+
*/
|
19 |
+
|
20 |
+
(function($) {
|
21 |
+
|
22 |
+
|
23 |
+
|
24 |
+
var zIndex = false, fronts = [];
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
$(document).on('keyup', observeKeyPress);
|
29 |
+
|
30 |
+
function observeKeyPress(e) {
|
31 |
+
if (fronts.length && (e.keyCode == 27 || (e.DOM_VK_ESCAPE == 27 && e.which==0)))
|
32 |
+
fronts[fronts.length - 1].trigger('escPress');
|
33 |
+
}
|
34 |
+
|
35 |
+
|
36 |
+
|
37 |
+
|
38 |
+
$.fn.wplnst_lightboxed = function(options) {
|
39 |
+
|
40 |
+
return this.each(function() {
|
41 |
+
|
42 |
+
|
43 |
+
|
44 |
+
var settings = $.extend({}, $.fn.wplnst_lightboxed.defaults, options);
|
45 |
+
var $self = $(this), $overlay;
|
46 |
+
|
47 |
+
|
48 |
+
|
49 |
+
function init() {
|
50 |
+
|
51 |
+
fronts.push($self);
|
52 |
+
$('body').append($self.hide());
|
53 |
+
|
54 |
+
zIndex = (false === zIndex)? settings.zIndex : zIndex + 1;
|
55 |
+
|
56 |
+
if (settings.showOverlay) {
|
57 |
+
|
58 |
+
$overlay = $('<div class="' + settings.classPrefix + '_overlay"/>');
|
59 |
+
|
60 |
+
$('body').append($overlay);
|
61 |
+
|
62 |
+
setOverlayHeight();
|
63 |
+
$(window).resize(setOverlayHeight);
|
64 |
+
|
65 |
+
$overlay.css({
|
66 |
+
position : 'absolute',
|
67 |
+
width : '100%',
|
68 |
+
top : 0,
|
69 |
+
left : 0,
|
70 |
+
right : 0,
|
71 |
+
bottom : 0,
|
72 |
+
zIndex : zIndex,
|
73 |
+
display : 'none',
|
74 |
+
});
|
75 |
+
|
76 |
+
$overlay.css(settings.overlayCSS);
|
77 |
+
|
78 |
+
$overlay.fadeIn(settings.overlaySpeed, function() {
|
79 |
+
setSelfPosition();
|
80 |
+
$self[settings.appearEffect](settings.lightboxSpeed, function() {
|
81 |
+
raiseOnLoad();
|
82 |
+
if (settings.closeClickOutside) {
|
83 |
+
$overlay.click(function(e) {
|
84 |
+
closeLightbox();
|
85 |
+
e.preventDefault;
|
86 |
+
return false;
|
87 |
+
});
|
88 |
+
}
|
89 |
+
});
|
90 |
+
});
|
91 |
+
|
92 |
+
} else {
|
93 |
+
|
94 |
+
setSelfPosition();
|
95 |
+
$self[settings.appearEffect](settings.lightboxSpeed, function() {
|
96 |
+
$self.show();
|
97 |
+
raiseOnLoad();
|
98 |
+
if (settings.closeClickOutside)
|
99 |
+
$(document).on('click', onClickOutside);
|
100 |
+
});
|
101 |
+
}
|
102 |
+
|
103 |
+
if (settings.parentLightbox)
|
104 |
+
settings.parentLightbox.fadeOut(200);
|
105 |
+
|
106 |
+
$(window).resize(setSelfPosition).scroll(setSelfPosition);
|
107 |
+
$(document).on('click', settings.closeSelector, onCloseSelector);
|
108 |
+
|
109 |
+
$self.on('close', closeLightbox);
|
110 |
+
$self.on('escPress', onEscPress);
|
111 |
+
$self.on('reposition', setSelfPosition);
|
112 |
+
}
|
113 |
+
|
114 |
+
|
115 |
+
|
116 |
+
function closeLightbox() {
|
117 |
+
|
118 |
+
fronts.pop();
|
119 |
+
|
120 |
+
if (settings.showOverlay) {
|
121 |
+
$overlay.remove();
|
122 |
+
$(window).unbind('resize', setOverlayHeight);
|
123 |
+
} else if (settings.closeClickOutside) {
|
124 |
+
$(document).off('click', onClickOutside);
|
125 |
+
}
|
126 |
+
|
127 |
+
if (settings.parentLightbox)
|
128 |
+
settings.parentLightbox.fadeIn(200);
|
129 |
+
|
130 |
+
if (settings.preventScroll)
|
131 |
+
$('body').css('overflow', '');
|
132 |
+
|
133 |
+
$(document).off('click', settings.closeSelector, onCloseSelector);
|
134 |
+
|
135 |
+
$self.off('close', closeLightbox);
|
136 |
+
$self.off('escPress', onEscPress);
|
137 |
+
$self.off('reposition', setSelfPosition);
|
138 |
+
|
139 |
+
$(window).unbind('resize', setSelfPosition);
|
140 |
+
$(window).unbind('scroll', setSelfPosition);
|
141 |
+
|
142 |
+
$self[settings.disappearEffect](settings.lightboxSpeed, function() {
|
143 |
+
raiseOnClose();
|
144 |
+
});
|
145 |
+
|
146 |
+
//$self.hide();
|
147 |
+
}
|
148 |
+
|
149 |
+
|
150 |
+
|
151 |
+
function setOverlayHeight() {
|
152 |
+
($(window).height() < $(document).height())? $overlay.css({ height : $(document).height() + 'px' }) : $overlay.css({ height : '100%' });
|
153 |
+
}
|
154 |
+
|
155 |
+
|
156 |
+
|
157 |
+
function setSelfPosition() {
|
158 |
+
|
159 |
+
$self.css({
|
160 |
+
left : '50%',
|
161 |
+
marginLeft : ($self.outerWidth() / 2) * -1,
|
162 |
+
zIndex : zIndex + 1
|
163 |
+
});
|
164 |
+
|
165 |
+
if (($self.height() + 80 >= $(window).height()) && ($self.css('position') != 'absolute')) {
|
166 |
+
|
167 |
+
var topOffset = $(document).scrollTop() + 40;
|
168 |
+
|
169 |
+
$self.css({
|
170 |
+
position : 'absolute',
|
171 |
+
top : topOffset + 'px',
|
172 |
+
marginTop : 0
|
173 |
+
});
|
174 |
+
|
175 |
+
} else if ($self.height() + 80 < $(window).height()) {
|
176 |
+
|
177 |
+
settings.centered? $self.css({
|
178 |
+
position : 'fixed',
|
179 |
+
top : '50%',
|
180 |
+
marginTop : ($self.outerHeight() / 2) * -1
|
181 |
+
}) : $self.css({
|
182 |
+
position : 'fixed'
|
183 |
+
}).css(settings.modalCSS);
|
184 |
+
|
185 |
+
if (settings.preventScroll)
|
186 |
+
$('body').css('overflow', 'hidden');
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
|
191 |
+
|
192 |
+
function onEscPress() {
|
193 |
+
if (settings.closeEsc)
|
194 |
+
closeLightbox();
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
|
199 |
+
function onClickOutside(e) {
|
200 |
+
if (!$self.is(e.target) && 0 === $self.has(e.target).length) {
|
201 |
+
closeLightbox();
|
202 |
+
e.preventDefault;
|
203 |
+
return false;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
|
208 |
+
|
209 |
+
function onCloseSelector(e) {
|
210 |
+
if ($self.has(e.target).length) {
|
211 |
+
closeLightbox();
|
212 |
+
e.preventDefault();
|
213 |
+
return false;
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
|
218 |
+
|
219 |
+
function raiseOnLoad() {
|
220 |
+
$self.trigger('lightboxedLoad');
|
221 |
+
$self.off('lightboxedLoad');
|
222 |
+
}
|
223 |
+
|
224 |
+
|
225 |
+
|
226 |
+
function raiseOnClose() {
|
227 |
+
$self.trigger('lightboxedClose');
|
228 |
+
$self.off('lightboxedClose');
|
229 |
+
}
|
230 |
+
|
231 |
+
|
232 |
+
|
233 |
+
// Start
|
234 |
+
init();
|
235 |
+
|
236 |
+
|
237 |
+
|
238 |
+
});
|
239 |
+
};
|
240 |
+
|
241 |
+
|
242 |
+
|
243 |
+
$.fn.wplnst_lightboxed.defaults = {
|
244 |
+
|
245 |
+
// Animation
|
246 |
+
appearEffect : 'fadeIn',
|
247 |
+
appearEase : '',
|
248 |
+
disappearEffect : 'fadeOut',
|
249 |
+
disappearEase : '',
|
250 |
+
lightboxSpeed : 200,
|
251 |
+
overlaySpeed : 250,
|
252 |
+
|
253 |
+
// Close
|
254 |
+
closeSelector : '.wplnst_lightboxed_close',
|
255 |
+
closeClickOutside : true,
|
256 |
+
closeEsc : true,
|
257 |
+
|
258 |
+
// Behavior
|
259 |
+
showOverlay : true,
|
260 |
+
parentLightbox : false,
|
261 |
+
preventScroll : true,
|
262 |
+
|
263 |
+
// Style
|
264 |
+
centered : false,
|
265 |
+
classPrefix : 'wplnst_lbx',
|
266 |
+
zIndex : 9999,
|
267 |
+
modalCSS : { top : '40px' },
|
268 |
+
overlayCSS : { background : 'black', opacity : .3 }
|
269 |
+
}
|
270 |
+
|
271 |
+
|
272 |
+
|
273 |
+
})(jQuery);
|
assets/js/lightboxed/jquery.lightboxed.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e){function o(e){n.length&&(27==e.keyCode||27==e.DOM_VK_ESCAPE&&0==e.which)&&n[n.length-1].trigger("escPress")}var t=!1,n=[];e(document).on("keyup",o),e.fn.wplnst_lightboxed=function(o){return this.each(function(){function i(){n.push(g),e("body").append(g.hide()),t=!1===t?u.zIndex:t+1,u.showOverlay?(h=e('<div class="'+u.classPrefix+'_overlay"/>'),e("body").append(h),c(),e(window).resize(c),h.css({position:"absolute",width:"100%",top:0,left:0,right:0,bottom:0,zIndex:t,display:"none"}),h.css(u.overlayCSS),h.fadeIn(u.overlaySpeed,function(){l(),g[u.appearEffect](u.lightboxSpeed,function(){f(),u.closeClickOutside&&h.click(function(e){return s(),e.preventDefault,!1})})})):(l(),g[u.appearEffect](u.lightboxSpeed,function(){g.show(),f(),u.closeClickOutside&&e(document).on("click",d)})),u.parentLightbox&&u.parentLightbox.fadeOut(200),e(window).resize(l).scroll(l),e(document).on("click",u.closeSelector,a),g.on("close",s),g.on("escPress",r),g.on("reposition",l)}function s(){n.pop(),u.showOverlay?(h.remove(),e(window).unbind("resize",c)):u.closeClickOutside&&e(document).off("click",d),u.parentLightbox&&u.parentLightbox.fadeIn(200),u.preventScroll&&e("body").css("overflow",""),e(document).off("click",u.closeSelector,a),g.off("close",s),g.off("escPress",r),g.off("reposition",l),e(window).unbind("resize",l),e(window).unbind("scroll",l),g[u.disappearEffect](u.lightboxSpeed,function(){p()})}function c(){e(window).height()<e(document).height()?h.css({height:e(document).height()+"px"}):h.css({height:"100%"})}function l(){if(g.css({left:"50%",marginLeft:g.outerWidth()/2*-1,zIndex:t+1}),g.height()+80>=e(window).height()&&"absolute"!=g.css("position")){var o=e(document).scrollTop()+40;g.css({position:"absolute",top:o+"px",marginTop:0})}else g.height()+80<e(window).height()&&(u.centered?g.css({position:"fixed",top:"50%",marginTop:g.outerHeight()/2*-1}):g.css({position:"fixed"}).css(u.modalCSS),u.preventScroll&&e("body").css("overflow","hidden"))}function r(){u.closeEsc&&s()}function d(e){return g.is(e.target)||0!==g.has(e.target).length?void 0:(s(),e.preventDefault,!1)}function a(e){return g.has(e.target).length?(s(),e.preventDefault(),!1):void 0}function f(){g.trigger("lightboxedLoad"),g.off("lightboxedLoad")}function p(){g.trigger("lightboxedClose"),g.off("lightboxedClose")}var h,u=e.extend({},e.fn.wplnst_lightboxed.defaults,o),g=e(this);i()})},e.fn.wplnst_lightboxed.defaults={appearEffect:"fadeIn",appearEase:"",disappearEffect:"fadeOut",disappearEase:"",lightboxSpeed:200,overlaySpeed:250,closeSelector:".wplnst_lightboxed_close",closeClickOutside:!0,closeEsc:!0,showOverlay:!0,parentLightbox:!1,preventScroll:!0,centered:!1,classPrefix:"wplnst_lbx",zIndex:9999,modalCSS:{top:"40px"},overlayCSS:{background:"black",opacity:.3}}}(jQuery);
|
core/alive.php
ADDED
@@ -0,0 +1,531 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Alive class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Alive {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
// Checks and launch crawler procedures
|
14 |
+
// ---------------------------------------------------------------------------------------------------
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Start the check
|
20 |
+
*/
|
21 |
+
public static function check() {
|
22 |
+
self::start(get_class());
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Check running crawler
|
29 |
+
*/
|
30 |
+
public static function start($source) {
|
31 |
+
|
32 |
+
// Load util file first
|
33 |
+
require_once(WPLNST_PATH.'/core/util.php');
|
34 |
+
|
35 |
+
// Version components
|
36 |
+
$source::start_version();
|
37 |
+
|
38 |
+
// Load common plugin dependencies
|
39 |
+
wplnst_require('core', 'types');
|
40 |
+
|
41 |
+
// Load custom nonce system
|
42 |
+
wplnst_require('core', 'nonce/nonce');
|
43 |
+
|
44 |
+
// Check crawl request arguments
|
45 |
+
if (!(defined('DOING_AJAX') && DOING_AJAX) || empty($_GET['wplnst_crawler']) || empty($_GET['wplnst_nonce']) || empty($_GET['wplnst_slug'])) {
|
46 |
+
|
47 |
+
// Check notifications
|
48 |
+
if (!empty($_GET['wplnst_notify_email']) && 'on' == $_GET['wplnst_notify_email']) {
|
49 |
+
|
50 |
+
// And finally check notify nonce
|
51 |
+
if (!empty($_GET['wplnst_notify_nonce']) && self::verify_notify_nonce($_GET['wplnst_notify_nonce']))
|
52 |
+
add_action('plugins_loaded', array($source, 'notify'));
|
53 |
+
|
54 |
+
// Check cURL needed before
|
55 |
+
} elseif (wplnst_is_curl_enabled()) {
|
56 |
+
|
57 |
+
// Activity checks
|
58 |
+
self::activity();
|
59 |
+
}
|
60 |
+
|
61 |
+
// Check this install crawler slug
|
62 |
+
} elseif ($_GET['wplnst_slug'] == self::get_crawler_slug()) {
|
63 |
+
|
64 |
+
/**
|
65 |
+
* From here we are under crawler scope,
|
66 |
+
* based on admin-ajax mode and special URL arguments.
|
67 |
+
*/
|
68 |
+
|
69 |
+
// Check cURL loaded
|
70 |
+
if (wplnst_is_curl_enabled()) {
|
71 |
+
|
72 |
+
// Check scan integer and nonce argument
|
73 |
+
$scan_id = (int) $_GET['wplnst_crawler'];
|
74 |
+
if ($scan_id > 0) {
|
75 |
+
|
76 |
+
// Check possible thread
|
77 |
+
$thread_id = isset($_GET['wplnst_thread'])? $_GET['wplnst_thread'] : false;
|
78 |
+
|
79 |
+
// Check scan and nonce
|
80 |
+
if (false === ($scan_row = self::verify_crawler($scan_id, $thread_id, $_GET['wplnst_nonce']))) {
|
81 |
+
|
82 |
+
// Debug
|
83 |
+
wplnst_debug('scan '.$scan_id.' - thread '.(empty($thread_id)? 'false' : $thread_id).' - verify crawler error', 'alive');
|
84 |
+
|
85 |
+
// Threads control
|
86 |
+
} elseif (false === ($thread_id = self::threading($scan_row, $thread_id))) {
|
87 |
+
|
88 |
+
// Debug
|
89 |
+
wplnst_debug('scan '.$scan_id.' - thread '.$thread_id.' - threading error', 'alive');
|
90 |
+
|
91 |
+
// Ok
|
92 |
+
} else {
|
93 |
+
|
94 |
+
// Run instance of crawler
|
95 |
+
$source::instantiate_crawler($scan_row, $thread_id);
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
// Debug end
|
101 |
+
wplnst_debug((empty($scan_row)? '' : 'scan '.$scan_row->scan_id.' - ').'thread '.(empty($thread_id)? '' : $thread_id).' terminate', 'alive');
|
102 |
+
|
103 |
+
// End
|
104 |
+
die;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Specific version components at start
|
112 |
+
*/
|
113 |
+
protected static function start_version() {
|
114 |
+
|
115 |
+
// Plugin definitions
|
116 |
+
wplnst_require('core', 'plugin');
|
117 |
+
}
|
118 |
+
|
119 |
+
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Start or continue active scan
|
123 |
+
*/
|
124 |
+
public static function run($scan_id, $hash, $thread_id = false) {
|
125 |
+
|
126 |
+
// Debug point
|
127 |
+
wplnst_debug('scan '.$scan_id.' - '.(empty($thread_id)? '' : 'thread '.$thread_id.' ').'run', 'alive');
|
128 |
+
|
129 |
+
// Check salt file
|
130 |
+
WPLNST_Core_Nonce::check_salt_file();
|
131 |
+
|
132 |
+
// Load cURL wrapper library
|
133 |
+
wplnst_require('core', 'curl');
|
134 |
+
|
135 |
+
// Spawn crawler call
|
136 |
+
WPLNST_Core_CURL::spawn(array(
|
137 |
+
'CURLOPT_URL' => self::get_crawler_url($scan_id, $hash, $thread_id),
|
138 |
+
'CURLOPT_USERAGENT' => wplnst_get_tsetting('user_agent'),
|
139 |
+
));
|
140 |
+
}
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Check last active scan activity and re-active scan if needed.
|
146 |
+
* This check runs in a normal WP execution, and not under any special URL,
|
147 |
+
* except at the end of a crawler process to check queued scans.
|
148 |
+
*/
|
149 |
+
public static function activity($skip_check = false) {
|
150 |
+
|
151 |
+
// Skip checks from the end
|
152 |
+
if (!$skip_check) {
|
153 |
+
|
154 |
+
// Avoid checks in plugins page
|
155 |
+
if (is_admin() && false !== stripos($_SERVER['REQUEST_URI'], '/plugins.php'))
|
156 |
+
return;
|
157 |
+
|
158 |
+
// Preliminary check to avoid constant database queries
|
159 |
+
$timestamp = (int) get_option('wplnst_crawler_timestamp');
|
160 |
+
if ($timestamp > 0 && time() - $timestamp <= wplnst_get_nsetting('crawler_alive'))
|
161 |
+
return;
|
162 |
+
|
163 |
+
// Reset timer, and exit if this is the first time
|
164 |
+
update_option('wplnst_crawler_timestamp', time());
|
165 |
+
if (empty($timestamp))
|
166 |
+
return;
|
167 |
+
}
|
168 |
+
|
169 |
+
// Retrieve active scans
|
170 |
+
$max_scans = wplnst_get_nsetting('max_scans');
|
171 |
+
$scans = self::get_ready_scans('play', 'started_at ASC', $max_scans);
|
172 |
+
|
173 |
+
// Check queued merge
|
174 |
+
if (count($scans) < $max_scans) {
|
175 |
+
$scans_queued = self::get_ready_scans('queued', 'enqueued_at ASC', $max_scans - count($scans));
|
176 |
+
if (!empty($scans_queued))
|
177 |
+
$scans = array_merge($scans, $scans_queued);
|
178 |
+
}
|
179 |
+
|
180 |
+
// Globals
|
181 |
+
global $wpdb;
|
182 |
+
|
183 |
+
// Enum active scans
|
184 |
+
foreach ($scans as $scan_info) {
|
185 |
+
|
186 |
+
// Check threads cuota
|
187 |
+
$threads = @json_decode($scan_info->threads, true);
|
188 |
+
if (!empty($threads) && is_array($threads)) {
|
189 |
+
|
190 |
+
// Initialize
|
191 |
+
$active = 0;
|
192 |
+
|
193 |
+
// Total timeout and minor correction
|
194 |
+
$total_timeout = wplnst_get_nsetting('connect_timeout', $scan_info->connect_timeout) + wplnst_get_nsetting('request_timeout', $scan_info->request_timeout) + wplnst_get_nsetting('extra_timeout');
|
195 |
+
|
196 |
+
// Count active threads
|
197 |
+
foreach ($threads as $thread_id => $thread) {
|
198 |
+
if ('on' == $thread['status']) {
|
199 |
+
if ((time() - (int) $thread['timestamp']) <= $total_timeout)
|
200 |
+
$active++;
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
// Check free limits
|
205 |
+
if ($active >= wplnst_get_nsetting('max_threads', $scan_info->max_threads))
|
206 |
+
continue;
|
207 |
+
}
|
208 |
+
|
209 |
+
// Check and cast queued to play
|
210 |
+
if ('queued' == $scan_info->status) {
|
211 |
+
|
212 |
+
// Configure update
|
213 |
+
$update = array('status' => 'play');
|
214 |
+
$current_time = current_time('mysql', true);
|
215 |
+
|
216 |
+
// First scan play
|
217 |
+
if (empty($scan_info->started_at) || '0000-00-00 00:00:00' == $scan_info->started_at) {
|
218 |
+
$update['started_at'] = $current_time;
|
219 |
+
$update['stopped_at'] = '0000-00-00 00:00:00';
|
220 |
+
|
221 |
+
// Continue
|
222 |
+
} else {
|
223 |
+
|
224 |
+
// Play again
|
225 |
+
$update['continued_at'] = $current_time;
|
226 |
+
}
|
227 |
+
|
228 |
+
// And update
|
229 |
+
$wpdb->update($wpdb->prefix.'wplnst_scans', $update, array('scan_id' => $scan_info->scan_id));
|
230 |
+
}
|
231 |
+
|
232 |
+
// Debug output
|
233 |
+
wplnst_debug('scan '.$scan_info->scan_id.' launch from activity()', 'alive');
|
234 |
+
|
235 |
+
// New thread
|
236 |
+
self::run($scan_info->scan_id, $scan_info->hash);
|
237 |
+
}
|
238 |
+
}
|
239 |
+
|
240 |
+
|
241 |
+
|
242 |
+
// Internal procedures
|
243 |
+
// ---------------------------------------------------------------------------------------------------
|
244 |
+
|
245 |
+
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Control current thread and check for free threads
|
249 |
+
* This check runs under special URL dedicated to threading
|
250 |
+
*/
|
251 |
+
private static function threading($scan_row, $current_thread_id) {
|
252 |
+
|
253 |
+
// Globals
|
254 |
+
global $wpdb;
|
255 |
+
|
256 |
+
// Check threads array
|
257 |
+
$threads = @json_decode($scan_row->threads, true);
|
258 |
+
$threads = (empty($threads) || !is_array($threads))? array() : $threads;
|
259 |
+
|
260 |
+
// Check invalid thread id
|
261 |
+
if (!empty($current_thread_id) && !isset($threads[$current_thread_id]))
|
262 |
+
return false;
|
263 |
+
|
264 |
+
// Initialize
|
265 |
+
$active = 0;
|
266 |
+
$new_thread_id = false;
|
267 |
+
|
268 |
+
// Total timeout and minor correction
|
269 |
+
$total_timeout = wplnst_get_nsetting('connect_timeout', $scan_row->connect_timeout) + wplnst_get_nsetting('request_timeout', $scan_row->request_timeout) + wplnst_get_nsetting('extra_timeout');
|
270 |
+
|
271 |
+
// Max crawler threads allowed
|
272 |
+
$max_threads = wplnst_get_nsetting('max_threads', $scan_row->max_threads);
|
273 |
+
|
274 |
+
// Inspect total active threads
|
275 |
+
foreach ($threads as $thread_id => $thread) {
|
276 |
+
|
277 |
+
// No checks for current thread
|
278 |
+
if (!empty($current_thread_id) && $current_thread_id == $thread_id) {
|
279 |
+
$active++;
|
280 |
+
|
281 |
+
// Only active threads
|
282 |
+
} elseif ('on' == $thread['status']) {
|
283 |
+
|
284 |
+
// Timestamp limit
|
285 |
+
if ((time() - (int) $thread['timestamp']) > $total_timeout) {
|
286 |
+
$threads[$thread_id]['status'] = 'off';
|
287 |
+
|
288 |
+
// Active
|
289 |
+
} else {
|
290 |
+
$active++;
|
291 |
+
}
|
292 |
+
}
|
293 |
+
}
|
294 |
+
|
295 |
+
// No current thread allowed
|
296 |
+
if ($active > $max_threads) {
|
297 |
+
if (!empty($current_thread_id))
|
298 |
+
$threads[$current_thread_id]['status'] = 'off';
|
299 |
+
$current_thread_id = false;
|
300 |
+
|
301 |
+
// Check new thread
|
302 |
+
} elseif ($active < $max_threads) {
|
303 |
+
$active++;
|
304 |
+
$new_thread_id = empty($threads)? 1 : (int) max(array_keys($threads)) + 1;
|
305 |
+
$threads[$new_thread_id] = array('status' => 'on', 'timestamp' => time());
|
306 |
+
}
|
307 |
+
|
308 |
+
// Rebuild current thread
|
309 |
+
if (!empty($current_thread_id))
|
310 |
+
$threads[$current_thread_id] = array('status' => 'on', 'timestamp' => time());
|
311 |
+
|
312 |
+
// Update threads data
|
313 |
+
$wpdb->update($wpdb->prefix.'wplnst_scans', array('threads' => @json_encode($threads)), array('scan_id' => $scan_row->scan_id));
|
314 |
+
|
315 |
+
// Launch new thread
|
316 |
+
if (!empty($new_thread_id) && $active < $max_threads)
|
317 |
+
self::run($scan_row->scan_id, $scan_row->hash);
|
318 |
+
|
319 |
+
// Done
|
320 |
+
return empty($current_thread_id)? $new_thread_id : $current_thread_id;
|
321 |
+
}
|
322 |
+
|
323 |
+
|
324 |
+
|
325 |
+
// Active scans info
|
326 |
+
// ---------------------------------------------------------------------------------------------------
|
327 |
+
|
328 |
+
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Retrieve active scan row identifier, ready state and threads value
|
332 |
+
*/
|
333 |
+
private static function get_ready_scans($status, $order, $max_scans) {
|
334 |
+
|
335 |
+
// Globals
|
336 |
+
global $wpdb;
|
337 |
+
|
338 |
+
// Retrieve scans
|
339 |
+
$scans = $wpdb->get_results($wpdb->prepare('SELECT SQL_NO_CACHE scan_id, status, ready, hash, started_at, threads, max_threads, connect_timeout, request_timeout FROM '.$wpdb->prefix.'wplnst_scans WHERE ready = 1 AND status = %s ORDER BY '.esc_sql($order), $status));
|
340 |
+
|
341 |
+
// Check results
|
342 |
+
if (empty($scans) || !is_array($scans))
|
343 |
+
return array();
|
344 |
+
|
345 |
+
// Initialize
|
346 |
+
$index = 0;
|
347 |
+
$allowed = array();
|
348 |
+
|
349 |
+
// Enum scans
|
350 |
+
foreach ($scans as $scan) {
|
351 |
+
|
352 |
+
// Check index
|
353 |
+
$index++;
|
354 |
+
if ($index > $max_scans) {
|
355 |
+
|
356 |
+
// Queue scan
|
357 |
+
if ('play' == $scan->status) {
|
358 |
+
$current_time = current_time('mysql', true);
|
359 |
+
$wpdb->query($wpdb->prepare('UPDATE '.$wpdb->prefix.'wplnst_scans SET status = "queued", enqueued_at = %s, stopped_at = %s WHERE scan_id = %d', $current_time, $current_time, $scan->scan_id));
|
360 |
+
}
|
361 |
+
|
362 |
+
// Next
|
363 |
+
continue;
|
364 |
+
}
|
365 |
+
|
366 |
+
// Add allowed
|
367 |
+
$allowed[] = $scan;
|
368 |
+
}
|
369 |
+
|
370 |
+
// Preserve allowed scans
|
371 |
+
return $allowed;
|
372 |
+
}
|
373 |
+
|
374 |
+
|
375 |
+
|
376 |
+
// Crawling related data
|
377 |
+
// ---------------------------------------------------------------------------------------------------
|
378 |
+
|
379 |
+
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Verify if crawler exists, is ready, and nonce
|
383 |
+
*/
|
384 |
+
private static function verify_crawler($scan_id, $thread_id, $nonce) {
|
385 |
+
|
386 |
+
// Globals
|
387 |
+
global $wpdb;
|
388 |
+
|
389 |
+
// Retrieve and check scan
|
390 |
+
$scan_row = $wpdb->get_row($wpdb->prepare('SELECT SQL_NO_CACHE scan_id, status, ready, hash, threads, max_threads, connect_timeout, request_timeout FROM '.$wpdb->prefix.'wplnst_scans WHERE scan_id = %d', $scan_id));
|
391 |
+
if (empty($scan_row) || !is_object($scan_row))
|
392 |
+
return false;
|
393 |
+
|
394 |
+
// Check scan status
|
395 |
+
if (empty($scan_row->status) || 'wait' == $scan_row->status || 'end' == $scan_row->status)
|
396 |
+
return false;
|
397 |
+
|
398 |
+
// Check scan ready
|
399 |
+
if (empty($scan_row->ready) || 1 != (int) $scan_row->ready)
|
400 |
+
return false;
|
401 |
+
|
402 |
+
// Check nonce and return scan
|
403 |
+
return self::verify_crawler_nonce($nonce, $scan_row->hash, $thread_id)? $scan_row : false;
|
404 |
+
}
|
405 |
+
|
406 |
+
|
407 |
+
|
408 |
+
/**
|
409 |
+
* Load a crawler instance
|
410 |
+
*/
|
411 |
+
protected static function instantiate_crawler($scan_row, $thread_id) {
|
412 |
+
|
413 |
+
// Load dependencies
|
414 |
+
wplnst_require('core', 'crawler');
|
415 |
+
|
416 |
+
// Instance
|
417 |
+
WPLNST_Core_Crawler::instantiate(array(
|
418 |
+
'scan_id' => $scan_row->scan_id,
|
419 |
+
'thread_id' => $thread_id,
|
420 |
+
'crawler_url' => self::get_crawler_url($scan_row->scan_id, $scan_row->hash, $thread_id),
|
421 |
+
));
|
422 |
+
}
|
423 |
+
|
424 |
+
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Verify crawler nonce from scan id
|
428 |
+
*/
|
429 |
+
private static function verify_crawler_nonce($value, $hash, $thread_id = false) {
|
430 |
+
return WPLNST_Core_Nonce::verify_nonce($value, 'crawl-scan-'.$hash.(empty($thread_id)? '' : '-thread-'.$thread_id.'-'.self::get_crawler_slug()));
|
431 |
+
}
|
432 |
+
|
433 |
+
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Create nonce for the crawler
|
437 |
+
*/
|
438 |
+
private static function get_crawler_nonce($hash, $thread_id = false) {
|
439 |
+
return WPLNST_Core_Nonce::create_nonce('crawl-scan-'.$hash.(empty($thread_id)? '' : '-thread-'.$thread_id.'-'.self::get_crawler_slug()));
|
440 |
+
}
|
441 |
+
|
442 |
+
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Compose current crawler URL
|
446 |
+
*/
|
447 |
+
public static function get_crawler_url($scan_id, $hash, $thread_id = false) {
|
448 |
+
|
449 |
+
// Default args
|
450 |
+
$args = array(
|
451 |
+
'wplnst_crawler' => $scan_id,
|
452 |
+
'wplnst_nonce' => self::get_crawler_nonce($hash, $thread_id),
|
453 |
+
'wplnst_slug' => self::get_crawler_slug(),
|
454 |
+
);
|
455 |
+
|
456 |
+
// Check thread arg
|
457 |
+
if (!empty($thread_id))
|
458 |
+
$args['wplnst_thread'] = $thread_id;
|
459 |
+
|
460 |
+
// Compose URL
|
461 |
+
return add_query_arg($args, rtrim(admin_url('admin-ajax.php'), '/'));
|
462 |
+
}
|
463 |
+
|
464 |
+
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Retrieve, check or generate unique crawler slug
|
468 |
+
*/
|
469 |
+
public static function get_crawler_slug() {
|
470 |
+
|
471 |
+
// Retrieve current slug
|
472 |
+
$crawler_slug = get_option('wplnst_crawler_slug');
|
473 |
+
|
474 |
+
// Check valid page slug
|
475 |
+
if (empty($crawler_slug) || 16 != strlen($crawler_slug) || !preg_match('/^[a-z0-9]+$/', $crawler_slug)) {
|
476 |
+
|
477 |
+
// Generate new slug
|
478 |
+
$crawler_slug = strtolower(WPLNST_Core_Nonce::generate_password(16, false, false));
|
479 |
+
|
480 |
+
// And update
|
481 |
+
update_option('wplnst_crawler_slug', $crawler_slug);
|
482 |
+
}
|
483 |
+
|
484 |
+
// Done
|
485 |
+
return $crawler_slug;
|
486 |
+
}
|
487 |
+
|
488 |
+
|
489 |
+
|
490 |
+
// Notifications launchers
|
491 |
+
// ---------------------------------------------------------------------------------------------------
|
492 |
+
|
493 |
+
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Verify crawler nonce from scan id
|
497 |
+
*/
|
498 |
+
protected static function verify_notify_nonce($value) {
|
499 |
+
return WPLNST_Core_Nonce::verify_nonce($value, 'crawl-notify-'.self::get_crawler_slug());
|
500 |
+
}
|
501 |
+
|
502 |
+
|
503 |
+
|
504 |
+
/**
|
505 |
+
* Create nonce for the notifier
|
506 |
+
*/
|
507 |
+
public static function get_notify_nonce() {
|
508 |
+
return WPLNST_Core_Nonce::create_nonce('crawl-notify-'.self::get_crawler_slug());
|
509 |
+
}
|
510 |
+
|
511 |
+
|
512 |
+
|
513 |
+
/**
|
514 |
+
* Check pending notifications
|
515 |
+
*/
|
516 |
+
public static function notify() {
|
517 |
+
|
518 |
+
// Load translations
|
519 |
+
WPLNST_Core_Plugin::load_plugin_textdomain();
|
520 |
+
|
521 |
+
// Include and call class
|
522 |
+
wplnst_require('core', 'notify');
|
523 |
+
WPLNST_Core_Notify::check();
|
524 |
+
|
525 |
+
// End
|
526 |
+
die;
|
527 |
+
}
|
528 |
+
|
529 |
+
|
530 |
+
|
531 |
+
}
|
core/boot.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Boot check
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Check class or constants conflict relative to other active plugins
|
11 |
+
if (class_exists('WPLNST_Core_Alive') || defined('WPLNST_VERSION') || defined('WPLNST_FILE') || defined('WPLNST_PATH')) {
|
12 |
+
|
13 |
+
// No execution allowed
|
14 |
+
trigger_error(__('Detected another version of WP Link Status already active. Please deactivate it before and try again to activate this plugin.', 'wplnst'), E_USER_ERROR);
|
15 |
+
|
16 |
+
// Check WP version via checking version expected function, because $wp_version may have been overwritten
|
17 |
+
} elseif (function_exists('add_action') && !function_exists('is_main_query')) {
|
18 |
+
|
19 |
+
// No compatible WP version
|
20 |
+
trigger_error(__('Sorry, this version of WP Link Status requires WordPress 3.3 or later.', 'wplnst'), E_USER_ERROR);
|
21 |
+
}
|
core/crawler.php
ADDED
@@ -0,0 +1,2249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Load main class
|
4 |
+
require_once(dirname(__FILE__).'/module.php');
|
5 |
+
|
6 |
+
/**
|
7 |
+
* WP Link Status Core Crawler class
|
8 |
+
*
|
9 |
+
* @package WP Link Status
|
10 |
+
* @subpackage WP Link Status Core
|
11 |
+
*/
|
12 |
+
class WPLNST_Core_Crawler extends WPLNST_Core_Module {
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
// Properties
|
17 |
+
// ---------------------------------------------------------------------------------------------------
|
18 |
+
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Current scan
|
23 |
+
*/
|
24 |
+
private $scan;
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Current thread
|
30 |
+
*/
|
31 |
+
private $thread_id;
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* All timeouts
|
37 |
+
*/
|
38 |
+
private $connect_timeout;
|
39 |
+
private $request_timeout;
|
40 |
+
private $total_timeout;
|
41 |
+
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Current pack index
|
46 |
+
*/
|
47 |
+
private $pack_index = 0;
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Totals content
|
53 |
+
*/
|
54 |
+
private $total_posts;
|
55 |
+
private $total_comments;
|
56 |
+
private $total_blogroll;
|
57 |
+
|
58 |
+
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Back crawler URL
|
62 |
+
*/
|
63 |
+
private $crawler_url;
|
64 |
+
|
65 |
+
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Content args values
|
69 |
+
*/
|
70 |
+
private $post_args;
|
71 |
+
private $comment_args;
|
72 |
+
private $blogroll_args;
|
73 |
+
|
74 |
+
|
75 |
+
|
76 |
+
// Initialization
|
77 |
+
// ---------------------------------------------------------------------------------------------------
|
78 |
+
|
79 |
+
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Creates a singleton object
|
83 |
+
*/
|
84 |
+
public static function instantiate($args = null) {
|
85 |
+
return self::get_instance(get_class(), $args);
|
86 |
+
}
|
87 |
+
|
88 |
+
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Custom constructor
|
92 |
+
*/
|
93 |
+
protected function on_construct($args = null) {
|
94 |
+
|
95 |
+
// Check scan argument
|
96 |
+
$scan_id = empty($args['scan_id'])? 0 : (int) $args['scan_id'];
|
97 |
+
if (empty($scan_id))
|
98 |
+
return;
|
99 |
+
|
100 |
+
// Check thread argument
|
101 |
+
$this->thread_id = empty($args['thread_id'])? 0 : (int) $args['thread_id'];
|
102 |
+
if (empty($this->thread_id))
|
103 |
+
return;
|
104 |
+
|
105 |
+
// Crawler URL argument
|
106 |
+
$this->crawler_url = empty($args['crawler_url'])? false : $args['crawler_url'];
|
107 |
+
if (empty($this->crawler_url))
|
108 |
+
return;
|
109 |
+
|
110 |
+
// Check scan record
|
111 |
+
if (false === ($this->scan = $this->get_scan_by_id($scan_id)))
|
112 |
+
return;
|
113 |
+
|
114 |
+
// Debug point
|
115 |
+
$this->debug('__construct');
|
116 |
+
|
117 |
+
// URL object
|
118 |
+
$this->load_url_object();
|
119 |
+
|
120 |
+
// All timeouts
|
121 |
+
$this->set_timeouts();
|
122 |
+
|
123 |
+
// Incoming POST request data
|
124 |
+
if (!empty($_POST['url_id']))
|
125 |
+
$this->request();
|
126 |
+
|
127 |
+
// Check waiting links before next content data
|
128 |
+
if (!$this->inspect())
|
129 |
+
$this->content();
|
130 |
+
}
|
131 |
+
|
132 |
+
|
133 |
+
|
134 |
+
// External request data update and quota check
|
135 |
+
// ---------------------------------------------------------------------------------------------------
|
136 |
+
|
137 |
+
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Connect and request timeout
|
141 |
+
*/
|
142 |
+
private function set_timeouts() {
|
143 |
+
|
144 |
+
// Local timeouts
|
145 |
+
$this->connect_timeout = wplnst_get_nsetting('connect_timeout', $this->scan->threads->connect_timeout);
|
146 |
+
$this->request_timeout = wplnst_get_nsetting('request_timeout', $this->scan->threads->request_timeout);
|
147 |
+
|
148 |
+
// Timeouts sum and extra
|
149 |
+
$this->total_timeout = $this->connect_timeout + $this->request_timeout + wplnst_get_nsetting('extra_timeout');
|
150 |
+
}
|
151 |
+
|
152 |
+
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Result from a external request
|
156 |
+
*/
|
157 |
+
private function request() {
|
158 |
+
|
159 |
+
// Debug point
|
160 |
+
$this->debug('request');
|
161 |
+
|
162 |
+
// Check URL id
|
163 |
+
$url_id = (int) $_POST['url_id'];
|
164 |
+
if (empty($url_id))
|
165 |
+
return;
|
166 |
+
|
167 |
+
// Check URL record
|
168 |
+
if (false === ($url = $this->scans->get_scan_url(array('id' => $url_id, 'no_cache' => true))))
|
169 |
+
return;
|
170 |
+
|
171 |
+
// Check URL status record
|
172 |
+
if (false === ($rows = $this->scans->get_scan_url_status(array('url_id' => $url_id, 'scan_id' => $this->scan->id, 'no_cache' => true))))
|
173 |
+
return;
|
174 |
+
|
175 |
+
// Check URL status phase
|
176 |
+
if (1 != count($rows) || in_array($rows[0]->phase, array('end', 'discard', 'failed')))
|
177 |
+
return;
|
178 |
+
|
179 |
+
// Check redirection mode
|
180 |
+
$redirection = (!empty($_GET['wplnst_redirection']) && '1' == $_GET['wplnst_redirection']);
|
181 |
+
|
182 |
+
// Analyze request
|
183 |
+
wplnst_require('core', 'status');
|
184 |
+
$status = new WPLNST_Core_Status($_POST);
|
185 |
+
|
186 |
+
// Check discarded response
|
187 |
+
$discard = empty($status->level)? false : (!in_array($status->level, $this->scan->status_levels) && !in_array($status->code, $this->scan->status_codes));
|
188 |
+
|
189 |
+
// Check redirection steps
|
190 |
+
$redirect_steps = @json_decode($rows[0]->redirect_steps, true);
|
191 |
+
if (empty($redirect_steps) || !is_array($redirect_steps))
|
192 |
+
$redirect_steps = array();
|
193 |
+
|
194 |
+
// Normal mode
|
195 |
+
if (!$this->scan->redir_status || !$redirection) {
|
196 |
+
|
197 |
+
// Check redirection
|
198 |
+
$phase_next = 'end';
|
199 |
+
$redirect_url_id = 0;
|
200 |
+
$redirect_url_status = "";
|
201 |
+
$redirect_curl_errno = 0;
|
202 |
+
if ($this->scan->redir_status && !$discard && 3 == $status->level && !empty($status->redirect_url)) {
|
203 |
+
|
204 |
+
// Default redirection
|
205 |
+
$redirect_url = $status->redirect_url;
|
206 |
+
|
207 |
+
// Analyze
|
208 |
+
$urlinfo = $this->urlo->parse($redirect_url, $url->url);
|
209 |
+
if ($this->urlo->is_crawleable($urlinfo)) {
|
210 |
+
|
211 |
+
// Copy final URL
|
212 |
+
$redirect_url = $urlinfo['url'];
|
213 |
+
|
214 |
+
// Search by main URL
|
215 |
+
if (false !== ($redir_url = $this->scans->get_scan_url(array('url' => $redirect_url, 'no_cache' => true)))) {
|
216 |
+
|
217 |
+
// Existing URL
|
218 |
+
$phase_next = 'redir';
|
219 |
+
$redirect_url_id = $redir_url->url_id;
|
220 |
+
|
221 |
+
// New URL for this scan
|
222 |
+
} elseif (false !== ($test_url_id = $this->scans->add_scan_url($urlinfo, $this->scan->id))) {
|
223 |
+
|
224 |
+
// Mark to check
|
225 |
+
$phase_next = 'redir';
|
226 |
+
$redirect_url_id = $test_url_id;
|
227 |
+
}
|
228 |
+
}
|
229 |
+
|
230 |
+
// Add possible fragment to save "As is"
|
231 |
+
$redirect_url .= $urlinfo['fragment'];
|
232 |
+
}
|
233 |
+
|
234 |
+
// Update status data
|
235 |
+
$this->scans->update_scan_url_status($url_id, $this->scan->id, array(
|
236 |
+
'phase' => $discard? 'discard' : $phase_next,
|
237 |
+
'request_at' => $status->request_at,
|
238 |
+
'status_level' => $status->level,
|
239 |
+
'status_code' => $status->code,
|
240 |
+
'redirect_url' => $discard? '' : (isset($redirect_url)? $redirect_url : ''),
|
241 |
+
'redirect_url_id' => $redirect_url_id,
|
242 |
+
'redirect_url_status' => $redirect_url_status,
|
243 |
+
'redirect_curl_errno' => $redirect_curl_errno,
|
244 |
+
'headers' => $discard? '' : (empty($status->headers)? '' : @json_encode($status->headers)),
|
245 |
+
'headers_request' => $discard? '' : (empty($status->headers_request)? '' : @json_encode($status->headers_request)),
|
246 |
+
'total_time' => $discard? 0 : $status->total_time,
|
247 |
+
'total_bytes' => $discard? 0 : $status->total_bytes,
|
248 |
+
'curl_errno' => $discard? 0 : $status->curl_errno,
|
249 |
+
'requests' => $discard? 0 : (int) $rows[0]->requests + 1,
|
250 |
+
));
|
251 |
+
|
252 |
+
// Update URL data
|
253 |
+
$this->scans->update_scan_url($url_id, array(
|
254 |
+
'last_scan_id' => $this->scan->id,
|
255 |
+
'last_status_level' => $status->level,
|
256 |
+
'last_status_code' => $status->code,
|
257 |
+
'last_curl_errno' => $status->curl_errno,
|
258 |
+
'last_request_at' => $status->request_at,
|
259 |
+
));
|
260 |
+
|
261 |
+
// Is Redirection
|
262 |
+
} else {
|
263 |
+
|
264 |
+
// Prepare update
|
265 |
+
$update = array(
|
266 |
+
'phase' => 'end',
|
267 |
+
'redirect_url_status' => $status->code,
|
268 |
+
'redirect_curl_errno' => $status->curl_errno,
|
269 |
+
'requests' => (int) $rows[0]->requests + 1,
|
270 |
+
);
|
271 |
+
|
272 |
+
// Check new redirection
|
273 |
+
if (empty($curl_errno) && 3 == $status->level && !empty($status->redirect_url) && ($rows[0]->requests + 1) <= wplnst_get_nsetting('max_redirs')) {
|
274 |
+
|
275 |
+
// Check crawleable
|
276 |
+
$urlinfo = $this->urlo->parse($status->redirect_url, $url->url);
|
277 |
+
if ($this->urlo->is_crawleable($urlinfo)) {
|
278 |
+
|
279 |
+
// Search by main URL
|
280 |
+
if (false !== ($redir_url = $this->scans->get_scan_url(array('url' => $urlinfo['url'], 'no_cache' => true)))) {
|
281 |
+
|
282 |
+
// Existing URL
|
283 |
+
$redirect_url_id = $redir_url->url_id;
|
284 |
+
|
285 |
+
// New URL for this scan
|
286 |
+
} elseif (false !== ($test_url_id = $this->scans->add_scan_url($urlinfo, $this->scan->id))) {
|
287 |
+
|
288 |
+
// Added URL
|
289 |
+
$redirect_url_id = $test_url_id;
|
290 |
+
}
|
291 |
+
|
292 |
+
// For existing or correctly added URL
|
293 |
+
if (!empty($redirect_url_id)) {
|
294 |
+
|
295 |
+
// Copy old steps
|
296 |
+
$redirect_steps[] = array('url' => $rows[0]->redirect_url, 'status' => $rows[0]->redirect_url_status);
|
297 |
+
|
298 |
+
// New redir
|
299 |
+
$update['phase'] = 'redir';
|
300 |
+
$update['redirect_url'] = $urlinfo['url'].$urlinfo['fragment'];
|
301 |
+
$update['redirect_url_id'] = $redirect_url_id;
|
302 |
+
$update['redirect_url_status'] = "";
|
303 |
+
$update['redirect_steps'] = @json_encode($redirection_steps);
|
304 |
+
}
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
// Update status data
|
309 |
+
$this->scans->update_scan_url_status($url_id, $this->scan->id, $update);
|
310 |
+
}
|
311 |
+
|
312 |
+
// Status codes
|
313 |
+
$this->scans->set_scan_summary_status_codes($this->scan->id, $this->scan->status_levels, $this->scan->status_codes);
|
314 |
+
|
315 |
+
// URLs summary
|
316 |
+
$this->scans->set_scan_summary_urls_phases($this->scan->id);
|
317 |
+
}
|
318 |
+
|
319 |
+
|
320 |
+
|
321 |
+
// Stored links inspection
|
322 |
+
// ---------------------------------------------------------------------------------------------------
|
323 |
+
|
324 |
+
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Launch new URL`s status checks
|
328 |
+
*/
|
329 |
+
private function inspect() {
|
330 |
+
|
331 |
+
// Debug point
|
332 |
+
$this->debug('inspect');
|
333 |
+
|
334 |
+
// Check if this scan is playing
|
335 |
+
if ('play' != $this->scans->get_scan_status($this->scan->id)) {
|
336 |
+
|
337 |
+
// Stopped or ended
|
338 |
+
return true;
|
339 |
+
|
340 |
+
// Retrieve next URL
|
341 |
+
} elseif (false !== ($url = $this->inspect_wait())) {
|
342 |
+
|
343 |
+
// Check no playing rows flag, and update started datetime
|
344 |
+
if (true !== $url && false !== $this->scans->update_scan_url_status($url->url_id, $this->scan->id, array('phase' => 'play', 'started_at' => current_time('mysql', true)))) {
|
345 |
+
|
346 |
+
// Debug point
|
347 |
+
$this->debug('inspect request');
|
348 |
+
|
349 |
+
// Check Crawler URL in redirection mode
|
350 |
+
$crawler_url = $this->crawler_url;
|
351 |
+
if (isset($url->redirection))
|
352 |
+
$crawler_url = add_query_arg('wplnst_redirection', '1', $crawler_url);
|
353 |
+
|
354 |
+
// Prepare POST fields
|
355 |
+
$postfields = array(
|
356 |
+
'url' => $url->url,
|
357 |
+
'hash' => $url->hash,
|
358 |
+
'url_id' => $url->url_id,
|
359 |
+
'connect_timeout' => $this->connect_timeout,
|
360 |
+
'request_timeout' => $this->request_timeout,
|
361 |
+
'max_download' => wplnst_get_nsetting('max_download') * 1024,
|
362 |
+
'back_url' => $crawler_url,
|
363 |
+
'debug' => wplnst_is_debug()? '1' : '0',
|
364 |
+
'user_agent' => wplnst_get_tsetting('user_agent'),
|
365 |
+
'nonce' => WPLNST_Core_Nonce::create_nonce($url->hash),
|
366 |
+
);
|
367 |
+
|
368 |
+
// Load cURL wrapper library
|
369 |
+
wplnst_require('core', 'curl');
|
370 |
+
|
371 |
+
// Spawn crawler call
|
372 |
+
WPLNST_Core_CURL::spawn(array(
|
373 |
+
'CURLOPT_URL' => plugins_url('core/requests/http.php', WPLNST_FILE),
|
374 |
+
'CURLOPT_USERAGENT' => wplnst_get_tsetting('user_agent'),
|
375 |
+
'CURLOPT_POST' => true,
|
376 |
+
'CURLOPT_POSTFIELDS' => http_build_query($postfields, null, '&'),
|
377 |
+
'CURLOPT_HTTPHEADER' => array('Content-Type: application/x-www-form-urlencoded; charset=utf-8'),
|
378 |
+
));
|
379 |
+
|
380 |
+
// Ends here, it's going out to check status
|
381 |
+
return true;
|
382 |
+
}
|
383 |
+
|
384 |
+
// Check scan ending from all content
|
385 |
+
} elseif ($this->content_end()) {
|
386 |
+
|
387 |
+
// No timeout
|
388 |
+
set_time_limit(0);
|
389 |
+
|
390 |
+
// Set "end" scan status
|
391 |
+
$this->scans->end_scan($this->scan->id);
|
392 |
+
|
393 |
+
// URLs status codes summary
|
394 |
+
$this->scans->set_scan_summary_status_codes($this->scan->id, $this->scan->status_levels, $this->scan->status_codes, true);
|
395 |
+
|
396 |
+
// URLs phases summary
|
397 |
+
$this->scans->set_scan_summary_urls_phases($this->scan->id, true);
|
398 |
+
|
399 |
+
// Update posts matched
|
400 |
+
if ($this->scan->check_posts)
|
401 |
+
$this->scans->set_scan_summary_objects_match($this->scan->id, 'posts', true);
|
402 |
+
|
403 |
+
// Update posts matched
|
404 |
+
if ($this->scan->check_comments)
|
405 |
+
$this->scans->set_scan_summary_objects_match($this->scan->id, 'comments', true);
|
406 |
+
|
407 |
+
// Update blogroll matched
|
408 |
+
if ($this->scan->check_blogroll)
|
409 |
+
$this->scans->set_scan_summary_objects_match($this->scan->id, 'blogroll', true);
|
410 |
+
|
411 |
+
// Remove discarded URLS
|
412 |
+
$this->scans->remove_scan_discard_urls($this->scan->id);
|
413 |
+
|
414 |
+
// Update real total posts
|
415 |
+
if ($this->scan->check_posts)
|
416 |
+
$this->scans->update_scan_trace($this->scan->id, array('total_posts' => $this->scans->get_scan_objects_count($this->scan->id, 'posts')));
|
417 |
+
|
418 |
+
// Remove registered objects
|
419 |
+
$this->scans->remove_scan_objects($this->scan->id);
|
420 |
+
|
421 |
+
// Check notifications
|
422 |
+
if ($this->scan->notify_default || ($this->scan->notify_address && !empty($this->scan->notify_address_email))) {
|
423 |
+
wplnst_require('core', 'notify');
|
424 |
+
WPLNST_Core_Notify::completed($this->scan);
|
425 |
+
}
|
426 |
+
|
427 |
+
// Check for queued scans
|
428 |
+
$this->activity();
|
429 |
+
|
430 |
+
// The end
|
431 |
+
return true;
|
432 |
+
}
|
433 |
+
|
434 |
+
// No wait or play with timeout
|
435 |
+
return false;
|
436 |
+
}
|
437 |
+
|
438 |
+
|
439 |
+
|
440 |
+
/**
|
441 |
+
* Inspect a waiting url to check
|
442 |
+
*/
|
443 |
+
private function inspect_wait() {
|
444 |
+
|
445 |
+
// Retrieve next wait
|
446 |
+
if (false !== ($url = $this->scans->get_scan_url_waiting($this->scan->id)))
|
447 |
+
return $url;
|
448 |
+
|
449 |
+
// Check playing rows
|
450 |
+
if (false === ($rows = $this->scans->get_scan_url_status(array('scan_id' => $this->scan->id, 'phase' => 'play', 'no_cache' => true, 'order' => 'started_at ASC'))))
|
451 |
+
return false;
|
452 |
+
|
453 |
+
// Max requests allowed
|
454 |
+
$max_requests = wplnst_get_nsetting('max_requests');
|
455 |
+
|
456 |
+
// Enum playing rows
|
457 |
+
foreach ($rows as $row) {
|
458 |
+
|
459 |
+
// Check timeouted
|
460 |
+
if (time() - strtotime($row->started_at.' UTC') > $this->total_timeout) {
|
461 |
+
|
462 |
+
// Check max requests
|
463 |
+
if ($row->requests >= $max_requests) {
|
464 |
+
|
465 |
+
// Mark as a request phase
|
466 |
+
$this->scans->update_scan_url_status($url->url_id, $this->scan->id, array('phase' => 'failed'));
|
467 |
+
|
468 |
+
// Retrieve URL
|
469 |
+
} elseif (false !== ($url = $this->scans->get_scan_url(array('id' => $row->url_id, 'no_cache' => true)))) {
|
470 |
+
|
471 |
+
// Update from play to wait
|
472 |
+
if (false !== $this->scans->update_scan_url_status($url->url_id, $this->scan->id, array('phase' => 'wait'))) {
|
473 |
+
|
474 |
+
// URLs summary
|
475 |
+
$this->scans->set_scan_summary_urls_phases($this->scan->id);
|
476 |
+
|
477 |
+
// Done
|
478 |
+
return $url;
|
479 |
+
}
|
480 |
+
}
|
481 |
+
}
|
482 |
+
}
|
483 |
+
|
484 |
+
// Playing rows
|
485 |
+
return false;
|
486 |
+
}
|
487 |
+
|
488 |
+
|
489 |
+
|
490 |
+
// Content data extraction procedures
|
491 |
+
// ---------------------------------------------------------------------------------------------------
|
492 |
+
|
493 |
+
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Initialize post args
|
497 |
+
*/
|
498 |
+
private function set_post_args() {
|
499 |
+
|
500 |
+
// Check previous
|
501 |
+
if (isset($this->post_args))
|
502 |
+
return;
|
503 |
+
|
504 |
+
// Initialize arguments
|
505 |
+
$this->post_args = array();
|
506 |
+
|
507 |
+
// Prepare types and status fragments
|
508 |
+
$this->post_args['post_types'] = (1 == count($this->scan->post_types))? '= "'.esc_sql($this->scan->post_types[0]).'"' : 'IN ("'.implode('", "', array_map('esc_sql', $this->scan->post_types)).'")';
|
509 |
+
$this->post_args['post_status'] = (1 == count($this->scan->post_status))? '= "'.esc_sql($this->scan->post_status[0]).'"' : 'IN ("'.implode('", "', array_map('esc_sql', $this->scan->post_status)).'")';
|
510 |
+
|
511 |
+
// Time scope argument
|
512 |
+
$this->post_args['time_scope'] = $this->get_time_scope_arg('post_date_gmt');
|
513 |
+
|
514 |
+
// Check order
|
515 |
+
$this->post_args['order_by'] = 'post_date_gmt '.(('asc' == $this->scan->crawl_order)? 'ASC' : 'DESC');
|
516 |
+
|
517 |
+
// Filters arguments
|
518 |
+
$this->post_args['content_filters'] = $this->get_content_filters_arg('post_content');
|
519 |
+
}
|
520 |
+
|
521 |
+
|
522 |
+
|
523 |
+
/**
|
524 |
+
* Initialize comments args
|
525 |
+
*/
|
526 |
+
private function set_comment_args() {
|
527 |
+
|
528 |
+
// Check previous
|
529 |
+
if (isset($this->comment_args))
|
530 |
+
return;
|
531 |
+
|
532 |
+
// Initialize
|
533 |
+
$this->comment_args = array();
|
534 |
+
|
535 |
+
// Comment status
|
536 |
+
$comment_types = WPLNST_Core_Types::get_comment_types_values($this->scan->comment_types);
|
537 |
+
$this->comment_args['comment_status'] = ' AND comment_approved '.((1 == count($comment_types))? '= "'.esc_sql($comment_types[0]).'"' : 'IN ("'.implode('", "', array_map('esc_sql', $comment_types)).'")');
|
538 |
+
|
539 |
+
// Time scope argument
|
540 |
+
$this->comment_args['time_scope'] = $this->get_time_scope_arg('comment_date_gmt');
|
541 |
+
|
542 |
+
// Filters arguments
|
543 |
+
$this->comment_args['content_filters'] = $this->get_content_filters_arg('comment_content');
|
544 |
+
|
545 |
+
// Check order
|
546 |
+
$this->comment_args['order_by'] = 'comment_date_gmt '.(('asc' == $this->scan->crawl_order)? 'ASC' : 'DESC');
|
547 |
+
}
|
548 |
+
|
549 |
+
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Initialize blogroll args
|
553 |
+
*/
|
554 |
+
private function set_blogroll_args() {
|
555 |
+
|
556 |
+
// Check previous
|
557 |
+
if (isset($this->blogroll_args))
|
558 |
+
return;
|
559 |
+
|
560 |
+
// Initialize arguments
|
561 |
+
$this->blogroll_args = array();
|
562 |
+
|
563 |
+
// Check order
|
564 |
+
$this->blogroll_args['order_by'] = 'link_id '.(('asc' == $this->scan->crawl_order)? 'ASC' : 'DESC');
|
565 |
+
}
|
566 |
+
|
567 |
+
|
568 |
+
|
569 |
+
/**
|
570 |
+
* Process next post
|
571 |
+
*/
|
572 |
+
private function content() {
|
573 |
+
|
574 |
+
// Debug point
|
575 |
+
$this->debug('content');
|
576 |
+
|
577 |
+
// No script timeout
|
578 |
+
set_time_limit(0);
|
579 |
+
|
580 |
+
// Retrieve trace array
|
581 |
+
$trace = $this->scans->get_scan_trace($this->scan->id);
|
582 |
+
|
583 |
+
// Initialize process flags
|
584 |
+
$process_posts = $process_comments = $process_blogroll = false;
|
585 |
+
|
586 |
+
|
587 |
+
/* Check content */
|
588 |
+
|
589 |
+
// Check posts
|
590 |
+
if ($this->scan->check_posts && empty($trace['populated_posts'])) {
|
591 |
+
$process_posts = true;
|
592 |
+
$this->content_total('posts');
|
593 |
+
}
|
594 |
+
|
595 |
+
// Check comments
|
596 |
+
if ($this->scan->check_comments && empty($trace['populated_comments'])) {
|
597 |
+
$process_comments = true;
|
598 |
+
if (empty($trace['total_comments_check']) || !$process_posts)
|
599 |
+
$this->content_total('comments');
|
600 |
+
}
|
601 |
+
|
602 |
+
// Check blogroll
|
603 |
+
if ($this->scan->check_blogroll && empty($trace['populated_blogroll'])) {
|
604 |
+
|
605 |
+
// Check links arg, if not update trace
|
606 |
+
if (!in_array('links', $this->scan->link_types)) {
|
607 |
+
$this->total_blogroll = 0;
|
608 |
+
$this->scans->update_scan_trace($this->scan->id, array('populated_blogroll' => true, 'total_blogroll' => 0));
|
609 |
+
|
610 |
+
// Continue
|
611 |
+
} else {
|
612 |
+
|
613 |
+
// Mark for process
|
614 |
+
$process_blogroll = true;
|
615 |
+
|
616 |
+
// Check first update
|
617 |
+
if (empty($trace['total_blogroll_check']) || (!$process_posts && !$process_comments))
|
618 |
+
$this->content_total('blogroll');
|
619 |
+
}
|
620 |
+
}
|
621 |
+
|
622 |
+
|
623 |
+
// Common filters
|
624 |
+
add_filter('wplnst_relative_parent_url', array(&$this, 'parent_permalink'));
|
625 |
+
|
626 |
+
|
627 |
+
/* Processing objects */
|
628 |
+
|
629 |
+
// Process posts
|
630 |
+
if ($process_posts && !$this->content_posts())
|
631 |
+
return;
|
632 |
+
|
633 |
+
// Process comments
|
634 |
+
if ($process_comments && !$this->content_comments())
|
635 |
+
return;
|
636 |
+
|
637 |
+
// Process blogroll
|
638 |
+
if ($process_blogroll && !$this->content_blogroll())
|
639 |
+
return;
|
640 |
+
|
641 |
+
|
642 |
+
/* External work or run again */
|
643 |
+
|
644 |
+
// More data or restart
|
645 |
+
if (!$this->inspect())
|
646 |
+
$this->restart();
|
647 |
+
}
|
648 |
+
|
649 |
+
|
650 |
+
|
651 |
+
/**
|
652 |
+
* Check if this is the end of all content types
|
653 |
+
*/
|
654 |
+
private function content_end() {
|
655 |
+
|
656 |
+
// Initialize
|
657 |
+
$the_end = true;
|
658 |
+
|
659 |
+
// Check posts
|
660 |
+
if ($this->scan->check_posts)
|
661 |
+
$the_end = (false !== $this->scans->get_scan_trace($this->scan->id, 'populated_posts'));
|
662 |
+
|
663 |
+
// Check comments
|
664 |
+
if ($the_end && $this->scan->check_comments)
|
665 |
+
$the_end = (false !== $this->scans->get_scan_trace($this->scan->id, 'populated_comments'));
|
666 |
+
|
667 |
+
// Check blogroll
|
668 |
+
if ($the_end && $this->scan->check_blogroll)
|
669 |
+
$the_end = (false !== $this->scans->get_scan_trace($this->scan->id, 'populated_blogroll'));
|
670 |
+
|
671 |
+
// Done
|
672 |
+
return $the_end;
|
673 |
+
}
|
674 |
+
|
675 |
+
|
676 |
+
|
677 |
+
/**
|
678 |
+
* Time scope limits
|
679 |
+
*/
|
680 |
+
private function get_time_scope_arg($field) {
|
681 |
+
|
682 |
+
// First basic check
|
683 |
+
if (empty($this->scan->time_scope) || 'anytime' == $this->scan->time_scope)
|
684 |
+
return '';
|
685 |
+
|
686 |
+
// Check real value
|
687 |
+
if (!in_array($this->scan->time_scope, array_keys(WPLNST_Core_Types::get_time_scopes())))
|
688 |
+
return '';
|
689 |
+
|
690 |
+
// Yesterday
|
691 |
+
if ('yesterday' == $this->scan->time_scope) {
|
692 |
+
$back_date = ' > "'.gmdate('Y-m-d 00:00:00', strtotime("-1 days")).'"';
|
693 |
+
|
694 |
+
// From one week ago
|
695 |
+
} elseif ('7days' == $this->scan->time_scope) {
|
696 |
+
$back_date = ' > "'.gmdate('Y-m-d 00:00:00', strtotime("-7 days")).'"';
|
697 |
+
|
698 |
+
// From 15 days ago
|
699 |
+
} elseif ('15days' == $this->scan->time_scope) {
|
700 |
+
$back_date = ' > "'.gmdate('Y-m-d 00:00:00', strtotime("-15 days")).'"';
|
701 |
+
|
702 |
+
// From 1 month ago
|
703 |
+
} elseif ('month' == $this->scan->time_scope) {
|
704 |
+
$back_date = ' > "'.gmdate('Y-m-d 00:00:00', strtotime("-1 months")).'"';
|
705 |
+
|
706 |
+
// From 3 months ago
|
707 |
+
} elseif ('3months' == $this->scan->time_scope) {
|
708 |
+
$back_date = ' > "'.gmdate('Y-m-d 00:00:00', strtotime("-3 months")).'"';
|
709 |
+
|
710 |
+
} elseif ('6months' == $this->scan->time_scope) {
|
711 |
+
$back_date = ' > "'.gmdate('Y-m-d 00:00:00', strtotime("-6 months")).'"';
|
712 |
+
|
713 |
+
} elseif ('year' == $this->scan->time_scope) {
|
714 |
+
$back_date = ' > "'.gmdate('Y-m-d 00:00:00', strtotime("-1 years")).'"';
|
715 |
+
|
716 |
+
} elseif ('custom' == $this->scan->time_scope) {
|
717 |
+
// Pending
|
718 |
+
}
|
719 |
+
|
720 |
+
// Check value and compose subquery
|
721 |
+
return isset($back_date)? ' AND '.$field.$back_date : '';
|
722 |
+
}
|
723 |
+
|
724 |
+
|
725 |
+
|
726 |
+
/**
|
727 |
+
* Content filters in query
|
728 |
+
*/
|
729 |
+
private function get_content_filters_arg($field, $op = ' AND ') {
|
730 |
+
|
731 |
+
// Content matches
|
732 |
+
$matches = $this->filter_for_queries();
|
733 |
+
if (empty($matches))
|
734 |
+
return '';
|
735 |
+
|
736 |
+
// Prepare likes
|
737 |
+
$likes = array();
|
738 |
+
foreach ($matches as $match)
|
739 |
+
$likes[] = $field.' LIKE "%'.addcslashes($match, '_%\\').'%"';
|
740 |
+
|
741 |
+
// Likes fragment
|
742 |
+
return $op.((1 == count($likes))? $likes[0] : '('.implode(' OR ', $likes).')');
|
743 |
+
}
|
744 |
+
|
745 |
+
|
746 |
+
|
747 |
+
/**
|
748 |
+
* Update total posts
|
749 |
+
*/
|
750 |
+
private function content_total($type, $final = false) {
|
751 |
+
|
752 |
+
// Globals
|
753 |
+
global $wpdb;
|
754 |
+
|
755 |
+
// Retrieve trace array
|
756 |
+
$trace = $this->scans->get_scan_trace($this->scan->id);
|
757 |
+
|
758 |
+
// Update posts
|
759 |
+
if ('posts' == $type) {
|
760 |
+
|
761 |
+
// Debug point
|
762 |
+
$this->debug('content_total posts');
|
763 |
+
|
764 |
+
// Check trace value
|
765 |
+
$total_posts = empty($trace['total_posts'])? 0 : (int) $trace['total_posts'];
|
766 |
+
|
767 |
+
// Total posts check
|
768 |
+
$timestamp = empty($trace['total_posts_check'])? false : (int) $trace['total_posts_check'];
|
769 |
+
if (false === $timestamp || (time() - $timestamp) >= wplnst_get_nsetting('total_objects')) {
|
770 |
+
|
771 |
+
// Debug point
|
772 |
+
$this->debug('content_total posts update');
|
773 |
+
|
774 |
+
// Mark checked time
|
775 |
+
$this->scans->update_scan_trace($this->scan->id, array('total_posts_check' => time()));
|
776 |
+
|
777 |
+
// Set filters
|
778 |
+
$this->set_post_args();
|
779 |
+
|
780 |
+
// Prepare query
|
781 |
+
$sql = 'SELECT COUNT(*) FROM '.$wpdb->posts.' WHERE post_type '.$this->post_args['post_types'].' AND post_status '.$this->post_args['post_status'].$this->post_args['time_scope'].$this->post_args['content_filters'];
|
782 |
+
|
783 |
+
// Check last date condition
|
784 |
+
$last_date_gmt = $this->scans->get_scan_trace($this->scan->id, 'last_post_date_gmt');
|
785 |
+
if (empty($last_date_gmt)) {
|
786 |
+
|
787 |
+
// Total posts without restrictions
|
788 |
+
$total_posts = (int) $wpdb->get_var($sql);
|
789 |
+
|
790 |
+
// Check
|
791 |
+
} else {
|
792 |
+
|
793 |
+
// Sum processed and no-processed
|
794 |
+
$where = ' AND post_date_gmt '.(('asc' == $this->scan->crawl_order)? '>=' : '<=').' "'.esc_sql($last_date_gmt).'"';
|
795 |
+
$total_posts = (int) $this->scans->get_scan_trace($this->scan->id, 'posts_index') + (int) $wpdb->get_var($sql.$where.' AND ID NOT IN (SELECT object_id FROM '.$wpdb->prefix.'wplnst_scans_objects WHERE scan_id = '.esc_sql($this->scan->id).' AND object_type = "posts")');
|
796 |
+
}
|
797 |
+
|
798 |
+
// Update total posts
|
799 |
+
$this->scans->update_scan_trace($this->scan->id, array('total_posts' => $total_posts));
|
800 |
+
}
|
801 |
+
|
802 |
+
// Assign results
|
803 |
+
$this->total_posts = $total_posts;
|
804 |
+
|
805 |
+
// Update total comments
|
806 |
+
} elseif ('comments' == $type) {
|
807 |
+
|
808 |
+
// Debug point
|
809 |
+
$this->debug('content_total comments');
|
810 |
+
|
811 |
+
// Check trace value
|
812 |
+
$total_comments = empty($trace['total_comments'])? 0 : (int) $trace['total_comments'];
|
813 |
+
|
814 |
+
// Total comments check
|
815 |
+
$timestamp = empty($trace['total_comments_check'])? false : (int) $trace['total_comments_check'];
|
816 |
+
if (false === $timestamp || (time() - $timestamp) >= wplnst_get_nsetting('total_objects')) {
|
817 |
+
|
818 |
+
// Debug point
|
819 |
+
$this->debug('content_total comments update');
|
820 |
+
|
821 |
+
// Mark checked time
|
822 |
+
$this->scans->update_scan_trace($this->scan->id, array('total_comments_check' => time()));
|
823 |
+
|
824 |
+
// Set filters
|
825 |
+
$this->set_comment_args();
|
826 |
+
|
827 |
+
// Prepare query
|
828 |
+
$sql = 'SELECT COUNT(*) FROM '.$wpdb->comments.' WHERE 1 = 1 '.$this->comment_args['comment_status'].$this->comment_args['time_scope'].$this->comment_args['content_filters'];
|
829 |
+
|
830 |
+
// Check last date condition
|
831 |
+
$last_date_gmt = $this->scans->get_scan_trace($this->scan->id, 'last_comment_date_gmt');
|
832 |
+
if (empty($last_date_gmt)) {
|
833 |
+
|
834 |
+
// Total comments without restrictions
|
835 |
+
$total_comments = (int) $wpdb->get_var($sql);
|
836 |
+
|
837 |
+
// Check
|
838 |
+
} else {
|
839 |
+
|
840 |
+
// Sum processed and no-processed
|
841 |
+
$where = ' AND comment_date_gmt '.(('asc' == $this->scan->crawl_order)? '>=' : '<=').' "'.esc_sql($last_date_gmt).'"';
|
842 |
+
$total_comments = (int) $this->scans->get_scan_trace($this->scan->id, 'comments_index') + (int) $wpdb->get_var($sql.$where.' AND comment_ID NOT IN (SELECT object_id FROM '.$wpdb->prefix.'wplnst_scans_objects WHERE scan_id = '.esc_sql($this->scan->id).' AND object_type = "comments")');
|
843 |
+
}
|
844 |
+
|
845 |
+
// Update total comments
|
846 |
+
$this->scans->update_scan_trace($this->scan->id, array('total_comments' => $total_comments));
|
847 |
+
}
|
848 |
+
|
849 |
+
// Assign results
|
850 |
+
$this->total_comments = $total_comments;
|
851 |
+
|
852 |
+
// Update total blogroll links
|
853 |
+
} elseif ('blogroll' == $type) {
|
854 |
+
|
855 |
+
// Debug point
|
856 |
+
$this->debug('content_total blogroll');
|
857 |
+
|
858 |
+
// Check trace value
|
859 |
+
$total_blogroll = empty($trace['total_blogroll'])? 0 : (int) $trace['total_blogroll'];
|
860 |
+
|
861 |
+
// Total blogroll check
|
862 |
+
$timestamp = empty($trace['total_blogroll_check'])? false : (int) $trace['total_blogroll_check'];
|
863 |
+
if (false === $timestamp || (time() - $timestamp) >= wplnst_get_nsetting('total_objects')) {
|
864 |
+
|
865 |
+
// Debug point
|
866 |
+
$this->debug('content_total blogroll update');
|
867 |
+
|
868 |
+
// Mark checked time
|
869 |
+
$this->scans->update_scan_trace($this->scan->id, array('total_blogroll_check' => time()));
|
870 |
+
|
871 |
+
// Set filters
|
872 |
+
$this->set_blogroll_args();
|
873 |
+
|
874 |
+
// Prepare query
|
875 |
+
$sql = 'SELECT COUNT(*) FROM '.$wpdb->links;
|
876 |
+
|
877 |
+
// Check last identifier condition
|
878 |
+
$last_id = (int) $this->scans->get_scan_trace($this->scan->id, 'last_blogroll_id');
|
879 |
+
if (empty($last_id)) {
|
880 |
+
|
881 |
+
// Total blogroll without restrictions
|
882 |
+
$total_blogroll = (int) $wpdb->get_var($sql);
|
883 |
+
|
884 |
+
// Check
|
885 |
+
} else {
|
886 |
+
|
887 |
+
// Sum processed and no-processed
|
888 |
+
$where = ' WHERE link_id '.(('asc' == $this->scan->crawl_order)? '>' : '<').' '.$last_id;
|
889 |
+
$total_blogroll = (int) $this->scans->get_scan_trace($this->scan->id, 'blogroll_index') + (int) $wpdb->get_var($sql.$where.' AND link_id NOT IN (SELECT object_id FROM '.$wpdb->prefix.'wplnst_scans_objects WHERE scan_id = '.esc_sql($this->scan->id).' AND object_type = "blogroll")');
|
890 |
+
}
|
891 |
+
|
892 |
+
// Update total blogroll
|
893 |
+
$this->scans->update_scan_trace($this->scan->id, array('total_blogroll' => $total_blogroll));
|
894 |
+
}
|
895 |
+
|
896 |
+
// Assign results
|
897 |
+
$this->total_blogroll = $total_blogroll;
|
898 |
+
}
|
899 |
+
}
|
900 |
+
|
901 |
+
|
902 |
+
|
903 |
+
/**
|
904 |
+
* Obtains and process contents from posts
|
905 |
+
*/
|
906 |
+
private function content_posts() {
|
907 |
+
|
908 |
+
// Recursion limit
|
909 |
+
static $recursion;
|
910 |
+
$recursion = isset($recursion)? 1 : $recursion + 1;
|
911 |
+
if ($recursion >= wplnst_get_nsetting('recursion_limit')) {
|
912 |
+
$this->restart();
|
913 |
+
return false;
|
914 |
+
}
|
915 |
+
|
916 |
+
// Content max pack
|
917 |
+
$this->pack_index++;
|
918 |
+
if ($this->pack_index > wplnst_get_nsetting('max_pack')) {
|
919 |
+
$this->restart();
|
920 |
+
return false;
|
921 |
+
}
|
922 |
+
|
923 |
+
// Check next post
|
924 |
+
if (false !== ($post = $this->content_posts_next())) {
|
925 |
+
|
926 |
+
// Register object
|
927 |
+
if (!$this->scans->register_scan_object($this->scan->id, $post->ID, 'posts', $post->post_date_gmt))
|
928 |
+
return $this->content_posts();
|
929 |
+
|
930 |
+
// Update last date gmt
|
931 |
+
$this->scans->update_scan_trace($this->scan->id, array('last_post_date_gmt' => $post->post_date_gmt));
|
932 |
+
|
933 |
+
// Update posts index
|
934 |
+
$this->scans->update_scan_trace($this->scan->id, array('posts_index' => $this->scans->get_scan_objects_count($this->scan->id, 'posts')));
|
935 |
+
|
936 |
+
// Initialize
|
937 |
+
$links_added = array();
|
938 |
+
$images_added = array();
|
939 |
+
$custom_fields_links_added = array();
|
940 |
+
$custom_fields_images_added = array();
|
941 |
+
|
942 |
+
// Parent permalink reference
|
943 |
+
$parent_url = array('post_id' => $post->ID);
|
944 |
+
|
945 |
+
// Process content
|
946 |
+
if (!empty($post->post_content)) {
|
947 |
+
|
948 |
+
// Process links
|
949 |
+
if (in_array('links', $this->scan->link_types)) {
|
950 |
+
$links = $this->extract_links($post->post_content, $parent_url, $post->ID, 'posts', $post->post_type, 'post_content', $post->post_date_gmt);
|
951 |
+
if (!empty($links))
|
952 |
+
$links_added = $this->save($links, $post->ID);
|
953 |
+
}
|
954 |
+
|
955 |
+
// Process images
|
956 |
+
if (in_array('images', $this->scan->link_types)) {
|
957 |
+
$images = $this->extract_images($post->post_content, $parent_url, $post->ID, 'posts', $post->post_type, 'post_content', $post->post_date_gmt);
|
958 |
+
if (!empty($images))
|
959 |
+
$images_added = $this->save($images, $post->ID);
|
960 |
+
}
|
961 |
+
}
|
962 |
+
|
963 |
+
// Check custom fields
|
964 |
+
if (!empty($this->scan->custom_fields)) {
|
965 |
+
|
966 |
+
// Retrieve post custom fields
|
967 |
+
$post_metas = $this->scans->get_post_metas($post->ID);
|
968 |
+
if (!empty($post_metas) && is_array($post_metas)) {
|
969 |
+
|
970 |
+
// First compare field by key
|
971 |
+
foreach ($this->scan->custom_fields as $field) {
|
972 |
+
|
973 |
+
// Check field
|
974 |
+
if (empty($field['type']) || !isset($field['name']))
|
975 |
+
continue;
|
976 |
+
|
977 |
+
// Check existing name
|
978 |
+
$name = $field['name'];
|
979 |
+
if (isset($post_metas[$name])) {
|
980 |
+
|
981 |
+
// Check custom field content
|
982 |
+
$post_meta = $post_metas[$name];
|
983 |
+
if (!empty($post_meta) && is_array($post_meta)) {
|
984 |
+
|
985 |
+
// Enum values
|
986 |
+
foreach ($post_meta as $meta_id => $value) {
|
987 |
+
|
988 |
+
// Sanitize
|
989 |
+
$value = trim($value);
|
990 |
+
if (empty($value))
|
991 |
+
continue;
|
992 |
+
|
993 |
+
// Direct URL
|
994 |
+
if ('url' == $field['type']) {
|
995 |
+
|
996 |
+
// Check URL
|
997 |
+
$urlinfo = $this->urlo->parse($value, $parent_url);
|
998 |
+
if ($this->filter_include_urls($urlinfo['url']) && $this->filter_exclude_urls($urlinfo['url'])) {
|
999 |
+
|
1000 |
+
// Create link array
|
1001 |
+
$link = array_merge($urlinfo, array(
|
1002 |
+
'anchor' => '',
|
1003 |
+
'link_type' => 'links',
|
1004 |
+
'object_id' => $post->ID,
|
1005 |
+
'object_type' => 'posts',
|
1006 |
+
'object_post_type' => $post->post_type,
|
1007 |
+
'object_field' => 'custom_field_url_'.$meta_id.'_'.$name,
|
1008 |
+
'object_date_gmt' => $post->post_date_gmt,
|
1009 |
+
));
|
1010 |
+
|
1011 |
+
// Author links
|
1012 |
+
$custom_fields_links_added = $this->save(array($link), $post->ID);
|
1013 |
+
}
|
1014 |
+
|
1015 |
+
// HTML
|
1016 |
+
} else {
|
1017 |
+
|
1018 |
+
// Process links
|
1019 |
+
if (in_array('links', $this->scan->link_types)) {
|
1020 |
+
$links = $this->extract_links($value, $parent_url, $post->ID, 'posts', $post->post_type, 'custom_field_html_'.$meta_id.'_'.$name, $post->post_date_gmt);
|
1021 |
+
if (!empty($links))
|
1022 |
+
$custom_fields_links_added = $this->save($links, $post->ID);
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
// Process images
|
1026 |
+
if (in_array('images', $this->scan->link_types)) {
|
1027 |
+
$images = $this->extract_images($value, $parent_url, $post->ID, 'posts', $post->post_type, 'custom_field_html_'.$meta_id.'_'.$name, $post->post_date_gmt);
|
1028 |
+
if (!empty($images))
|
1029 |
+
$custom_fields_images_added = $this->save($images, $post->ID);
|
1030 |
+
}
|
1031 |
+
}
|
1032 |
+
}
|
1033 |
+
}
|
1034 |
+
}
|
1035 |
+
}
|
1036 |
+
}
|
1037 |
+
}
|
1038 |
+
|
1039 |
+
// Update stats for summary
|
1040 |
+
if (!(empty($links_added) && empty($images_added) && empty($custom_fields_links_added) && empty($custom_fields_images_added))) {
|
1041 |
+
|
1042 |
+
// Update URLs phases
|
1043 |
+
$this->scans->set_scan_summary_urls_phases($this->scan->id);
|
1044 |
+
|
1045 |
+
// Update objects matched
|
1046 |
+
$this->scans->set_scan_summary_objects_match($this->scan->id, 'posts');
|
1047 |
+
|
1048 |
+
// Totals of content for each URL status added
|
1049 |
+
$added = array_unique(array_merge($links_added, $images_added, $custom_fields_links_added, $custom_fields_images_added));
|
1050 |
+
foreach ($added as $url_id)
|
1051 |
+
$this->scans->set_scan_url_status_total_content($url_id, $this->scan->id);
|
1052 |
+
|
1053 |
+
// Check inspect data
|
1054 |
+
if ($this->inspect())
|
1055 |
+
return false;
|
1056 |
+
}
|
1057 |
+
|
1058 |
+
// Empty
|
1059 |
+
} elseif ($this->scans->get_scan_objects_count($this->scan->id, 'posts') >= $this->total_posts) {
|
1060 |
+
|
1061 |
+
// Update populated status
|
1062 |
+
$this->scans->update_scan_trace($this->scan->id, array('populated_posts' => true));
|
1063 |
+
|
1064 |
+
// Check inspect data
|
1065 |
+
if ($this->inspect())
|
1066 |
+
return false;
|
1067 |
+
|
1068 |
+
// Check data to inspect
|
1069 |
+
} elseif ($this->inspect()) {
|
1070 |
+
|
1071 |
+
// Working
|
1072 |
+
return false;
|
1073 |
+
}
|
1074 |
+
|
1075 |
+
// End or next post
|
1076 |
+
return $this->scans->get_scan_trace($this->scan->id, 'populated_posts')? true : $this->content_posts();
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
|
1080 |
+
|
1081 |
+
/**
|
1082 |
+
* Retrieve next post
|
1083 |
+
*/
|
1084 |
+
private function content_posts_next($exceptions = array()) {
|
1085 |
+
|
1086 |
+
// Globals
|
1087 |
+
global $wpdb;
|
1088 |
+
|
1089 |
+
// Initialize
|
1090 |
+
$where = '1 = 1';
|
1091 |
+
|
1092 |
+
// Check exceptions
|
1093 |
+
if (!empty($exceptions))
|
1094 |
+
$where .= ' AND ID NOT IN ('.implode(',', array_map('intval', $exceptions)).')';
|
1095 |
+
|
1096 |
+
// Check last date condition
|
1097 |
+
$last_date_gmt = $this->scans->get_scan_trace($this->scan->id, 'last_post_date_gmt');
|
1098 |
+
if (!empty($last_date_gmt))
|
1099 |
+
$where .= ' AND post_date_gmt '.(('asc' == $this->scan->crawl_order)? '>=' : '<=').' "'.esc_sql($last_date_gmt).'"';
|
1100 |
+
|
1101 |
+
// Set arguments
|
1102 |
+
$this->set_post_args();
|
1103 |
+
|
1104 |
+
// Retrieve next post
|
1105 |
+
$post = $wpdb->get_row('SELECT ID, post_content, post_date_gmt, post_type FROM '.$wpdb->posts.' WHERE '.$where.' AND post_type '.$this->post_args['post_types'].' AND post_status '.$this->post_args['post_status'].$this->post_args['time_scope'].$this->post_args['content_filters'].' ORDER BY '.$this->post_args['order_by'].' LIMIT 1');
|
1106 |
+
|
1107 |
+
// Check if post is previously registered
|
1108 |
+
if (!empty($post) && $this->scans->scan_object_exists($this->scan->id, $post->ID, 'posts')) {
|
1109 |
+
|
1110 |
+
// Prepare identifiers
|
1111 |
+
$ids = array($post->ID);
|
1112 |
+
|
1113 |
+
// Check same value of last date
|
1114 |
+
if ($post->post_date_gmt == $last_date_gmt) {
|
1115 |
+
|
1116 |
+
// Check more identifiers with same date
|
1117 |
+
$existing_ids = $this->scans->get_scan_objects_ids_by_date($this->scan->id, 'posts', $last_date_gmt);
|
1118 |
+
if (!empty($existing_ids) && is_array($existing_ids))
|
1119 |
+
$ids = array_unique(array_merge($ids, $existing_ids));
|
1120 |
+
}
|
1121 |
+
|
1122 |
+
// Add exceptions
|
1123 |
+
$exceptions = empty($exceptions)? $ids : array_unique(array_merge($exceptions, $ids));
|
1124 |
+
|
1125 |
+
// Next post with exceptions
|
1126 |
+
$post = $this->content_posts_next($exceptions);
|
1127 |
+
}
|
1128 |
+
|
1129 |
+
// Done
|
1130 |
+
return empty($post)? false : $post;
|
1131 |
+
}
|
1132 |
+
|
1133 |
+
|
1134 |
+
|
1135 |
+
/**
|
1136 |
+
* Obtains and process contents from comments
|
1137 |
+
*/
|
1138 |
+
private function content_comments() {
|
1139 |
+
|
1140 |
+
// Recursion limit
|
1141 |
+
static $recursion;
|
1142 |
+
$recursion = isset($recursion)? 1 : $recursion + 1;
|
1143 |
+
if ($recursion >= wplnst_get_nsetting('recursion_limit')) {
|
1144 |
+
$this->restart();
|
1145 |
+
return false;
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
// Content max pack
|
1149 |
+
$this->pack_index++;
|
1150 |
+
if ($this->pack_index > wplnst_get_nsetting('max_pack')) {
|
1151 |
+
$this->restart();
|
1152 |
+
return false;
|
1153 |
+
}
|
1154 |
+
|
1155 |
+
// Check next comment
|
1156 |
+
if (false !== ($comment = $this->content_comments_next())) {
|
1157 |
+
|
1158 |
+
// Register object
|
1159 |
+
if (!$this->scans->register_scan_object($this->scan->id, $comment->comment_ID, 'comments', $comment->comment_date_gmt))
|
1160 |
+
return $this->content_comments();
|
1161 |
+
|
1162 |
+
// Update last date gmt
|
1163 |
+
$this->scans->update_scan_trace($this->scan->id, array('last_comment_date_gmt' => $comment->comment_date_gmt));
|
1164 |
+
|
1165 |
+
// Update comments index
|
1166 |
+
$this->scans->update_scan_trace($this->scan->id, array('comments_index' => $this->scans->get_scan_objects_count($this->scan->id, 'comments')));
|
1167 |
+
|
1168 |
+
// Initialize
|
1169 |
+
$links_added = array();
|
1170 |
+
$images_added = array();
|
1171 |
+
$authors_added = array();
|
1172 |
+
|
1173 |
+
// Retrieve parent permalink
|
1174 |
+
$parent_url = array('post_id' => $comment->comment_post_ID);
|
1175 |
+
|
1176 |
+
// Process content
|
1177 |
+
if (!empty($comment->comment_content)) {
|
1178 |
+
|
1179 |
+
// Process links
|
1180 |
+
if (in_array('links', $this->scan->link_types)) {
|
1181 |
+
$links = $this->extract_links($comment->comment_content, $parent_url, $comment->comment_ID, 'comments', "", 'comment_content', $comment->comment_date_gmt);
|
1182 |
+
if (!empty($links))
|
1183 |
+
$links_added = $this->save($links, $comment->comment_post_ID);
|
1184 |
+
}
|
1185 |
+
|
1186 |
+
// Process images
|
1187 |
+
if (in_array('images', $this->scan->link_types)) {
|
1188 |
+
$images = $this->extract_images($comment->comment_content, $parent_url, $comment->comment_ID, 'comments', "", 'comment_content', $comment->comment_date_gmt);
|
1189 |
+
if (!empty($images))
|
1190 |
+
$images_added = $this->save($images, $comment->comment_post_ID);
|
1191 |
+
}
|
1192 |
+
}
|
1193 |
+
|
1194 |
+
// Process author URL
|
1195 |
+
if (!empty($comment->comment_author_url) && in_array('links', $this->scan->link_types)) {
|
1196 |
+
|
1197 |
+
// Check URL
|
1198 |
+
$urlinfo = $this->urlo->parse($comment->comment_author_url, $parent_url);
|
1199 |
+
if ($this->filter_include_urls($urlinfo['url']) && $this->filter_exclude_urls($urlinfo['url'])) {
|
1200 |
+
|
1201 |
+
// Check anchor
|
1202 |
+
if ($this->filter_anchor_text($comment->comment_author)) {
|
1203 |
+
|
1204 |
+
// Create link array
|
1205 |
+
$link = array_merge($urlinfo, array(
|
1206 |
+
'anchor' => $comment->comment_author,
|
1207 |
+
'link_type' => 'links',
|
1208 |
+
'object_id' => $comment->comment_ID,
|
1209 |
+
'object_type' => 'comments',
|
1210 |
+
'object_post_type' => "",
|
1211 |
+
'object_field' => 'comment_author_url',
|
1212 |
+
'object_date_gmt' => $comment->comment_date_gmt,
|
1213 |
+
));
|
1214 |
+
|
1215 |
+
// Author links
|
1216 |
+
$authors_added = $this->save(array($link), $comment->comment_post_ID);
|
1217 |
+
}
|
1218 |
+
}
|
1219 |
+
}
|
1220 |
+
|
1221 |
+
// Update stats for summary
|
1222 |
+
if (!empty($links_added) || !empty($images_added) || !empty($authors_added)) {
|
1223 |
+
|
1224 |
+
// Update URLs phases
|
1225 |
+
$this->scans->set_scan_summary_urls_phases($this->scan->id);
|
1226 |
+
|
1227 |
+
// Update objects matched
|
1228 |
+
$this->scans->set_scan_summary_objects_match($this->scan->id, 'comments');
|
1229 |
+
|
1230 |
+
// Totals of content for each URL status added
|
1231 |
+
$added = array_unique(array_merge($links_added, $images_added, $authors_added));
|
1232 |
+
foreach ($added as $url_id)
|
1233 |
+
$this->scans->set_scan_url_status_total_content($url_id, $this->scan->id);
|
1234 |
+
|
1235 |
+
// Check inspect data
|
1236 |
+
if ($this->inspect())
|
1237 |
+
return false;
|
1238 |
+
}
|
1239 |
+
|
1240 |
+
// Empty
|
1241 |
+
} elseif ($this->scans->get_scan_objects_count($this->scan->id, 'comments') >= $this->total_comments) {
|
1242 |
+
|
1243 |
+
// Update populated status
|
1244 |
+
$this->scans->update_scan_trace($this->scan->id, array('populated_comments' => true));
|
1245 |
+
|
1246 |
+
// Check inspect data
|
1247 |
+
if ($this->inspect())
|
1248 |
+
return false;
|
1249 |
+
|
1250 |
+
// Check data to inspect
|
1251 |
+
} elseif ($this->inspect()) {
|
1252 |
+
|
1253 |
+
// Working
|
1254 |
+
return false;
|
1255 |
+
}
|
1256 |
+
|
1257 |
+
// End or next comment
|
1258 |
+
return $this->scans->get_scan_trace($this->scan->id, 'populated_comments')? true : $this->content_comments();
|
1259 |
+
}
|
1260 |
+
|
1261 |
+
|
1262 |
+
|
1263 |
+
/**
|
1264 |
+
* Retrieve next comment
|
1265 |
+
*/
|
1266 |
+
private function content_comments_next($exceptions = array()) {
|
1267 |
+
|
1268 |
+
// Globals
|
1269 |
+
global $wpdb;
|
1270 |
+
|
1271 |
+
// Initialize
|
1272 |
+
$where = '1 = 1';
|
1273 |
+
|
1274 |
+
// Check exceptions
|
1275 |
+
if (!empty($exceptions))
|
1276 |
+
$where .= ' AND comment_ID NOT IN ('.implode(',', array_map('intval', $exceptions)).')';
|
1277 |
+
|
1278 |
+
// Check last date condition
|
1279 |
+
$last_date_gmt = $this->scans->get_scan_trace($this->scan->id, 'last_comment_date_gmt');
|
1280 |
+
if (!empty($last_date_gmt))
|
1281 |
+
$where .= ' AND comment_date_gmt '.(('asc' == $this->scan->crawl_order)? '>=' : '<=').' "'.esc_sql($last_date_gmt).'"';
|
1282 |
+
|
1283 |
+
// Set arguments
|
1284 |
+
$this->set_comment_args();
|
1285 |
+
|
1286 |
+
// Retrieve next comment
|
1287 |
+
$comment = $wpdb->get_row('SELECT comment_ID, comment_post_ID, comment_content, comment_author, comment_author_url, comment_date_gmt FROM '.$wpdb->comments.' WHERE '.$where.' '.$this->comment_args['comment_status'].$this->comment_args['time_scope'].$this->comment_args['content_filters'].' ORDER BY '.$this->comment_args['order_by'].' LIMIT 1');
|
1288 |
+
|
1289 |
+
// Check if comment id previously registered
|
1290 |
+
if (!empty($comment) && $this->scans->scan_object_exists($this->scan->id, $comment->comment_ID, 'comments')) {
|
1291 |
+
|
1292 |
+
// Prepare identifiers
|
1293 |
+
$ids = array($comment->comment_ID);
|
1294 |
+
|
1295 |
+
// Check same value of last date
|
1296 |
+
if ($comment->comment_date_gmt == $last_date_gmt) {
|
1297 |
+
|
1298 |
+
// Check more identifiers with same date
|
1299 |
+
$existing_ids = $this->scans->get_scan_objects_ids_by_date($this->scan->id, 'comments', $last_date_gmt);
|
1300 |
+
if (!empty($existing_ids) && is_array($existing_ids))
|
1301 |
+
$ids = array_unique(array_merge($ids, $existing_ids));
|
1302 |
+
}
|
1303 |
+
|
1304 |
+
// Add exceptions
|
1305 |
+
$exceptions = empty($exceptions)? $ids : array_unique(array_merge($exceptions, $ids));
|
1306 |
+
|
1307 |
+
// Next comment with exceptions
|
1308 |
+
$comment = $this->content_comments_next($exceptions);
|
1309 |
+
}
|
1310 |
+
|
1311 |
+
// Done
|
1312 |
+
return empty($comment)? false : $comment;
|
1313 |
+
}
|
1314 |
+
|
1315 |
+
|
1316 |
+
|
1317 |
+
/**
|
1318 |
+
* Obtains and process links from the blogroll
|
1319 |
+
*/
|
1320 |
+
private function content_blogroll() {
|
1321 |
+
|
1322 |
+
// Recursion limit
|
1323 |
+
static $recursion;
|
1324 |
+
$recursion = isset($recursion)? 1 : $recursion + 1;
|
1325 |
+
if ($recursion >= wplnst_get_nsetting('recursion_limit')) {
|
1326 |
+
$this->restart();
|
1327 |
+
return false;
|
1328 |
+
}
|
1329 |
+
|
1330 |
+
// Content max pack
|
1331 |
+
$this->pack_index++;
|
1332 |
+
if ($this->pack_index > wplnst_get_nsetting('max_pack')) {
|
1333 |
+
$this->restart();
|
1334 |
+
return false;
|
1335 |
+
}
|
1336 |
+
|
1337 |
+
// Check next blogroll link
|
1338 |
+
if (false !== ($blogroll_link = $this->content_blogroll_next())) {
|
1339 |
+
|
1340 |
+
// Register object
|
1341 |
+
if (!$this->scans->register_scan_object($this->scan->id, $blogroll_link->link_id, 'blogroll'))
|
1342 |
+
return $this->content_blogroll();
|
1343 |
+
|
1344 |
+
// Update last blogroll id
|
1345 |
+
$this->scans->update_scan_trace($this->scan->id, array('last_blogroll_id' => $blogroll_link->link_id));
|
1346 |
+
|
1347 |
+
// Update blogroll index
|
1348 |
+
$this->scans->update_scan_trace($this->scan->id, array('blogroll_index' => $this->scans->get_scan_objects_count($this->scan->id, 'blogroll')));
|
1349 |
+
|
1350 |
+
// Process link URL
|
1351 |
+
if (!empty($blogroll_link->link_url)) {
|
1352 |
+
|
1353 |
+
// Check URL
|
1354 |
+
$urlinfo = $this->urlo->parse($blogroll_link->link_url);
|
1355 |
+
if ($this->filter_include_urls($urlinfo['url']) && $this->filter_exclude_urls($urlinfo['url'])) {
|
1356 |
+
|
1357 |
+
// Check anchor
|
1358 |
+
if ($this->filter_anchor_text($blogroll_link->link_name)) {
|
1359 |
+
|
1360 |
+
// Create link array
|
1361 |
+
$link = array_merge($urlinfo, array(
|
1362 |
+
'anchor' => $blogroll_link->link_name,
|
1363 |
+
'link_type' => 'links',
|
1364 |
+
'object_id' => $blogroll_link->link_id,
|
1365 |
+
'object_type' => 'blogroll',
|
1366 |
+
'object_post_type' => "",
|
1367 |
+
'object_field' => 'link_url',
|
1368 |
+
'object_date_gmt' => '0000-00-00 00:00:00',
|
1369 |
+
));
|
1370 |
+
|
1371 |
+
// Add blogroll link
|
1372 |
+
$blogroll_added = $this->save(array($link));
|
1373 |
+
|
1374 |
+
// Update URLs phases
|
1375 |
+
$this->scans->set_scan_summary_urls_phases($this->scan->id);
|
1376 |
+
|
1377 |
+
// Update objects matched
|
1378 |
+
$this->scans->set_scan_summary_objects_match($this->scan->id, 'blogroll');
|
1379 |
+
|
1380 |
+
// Totals of content for each URL status added
|
1381 |
+
foreach ($blogroll_added as $url_id)
|
1382 |
+
$this->scans->set_scan_url_status_total_content($url_id, $this->scan->id);
|
1383 |
+
|
1384 |
+
// Check inspect data
|
1385 |
+
if ($this->inspect())
|
1386 |
+
return false;
|
1387 |
+
}
|
1388 |
+
}
|
1389 |
+
}
|
1390 |
+
|
1391 |
+
// Empty
|
1392 |
+
} elseif ($this->scans->get_scan_objects_count($this->scan->id, 'blogroll') >= $this->total_blogroll) {
|
1393 |
+
|
1394 |
+
// Update populated status
|
1395 |
+
$this->scans->update_scan_trace($this->scan->id, array('populated_blogroll' => true));
|
1396 |
+
|
1397 |
+
// Check inspect data
|
1398 |
+
if ($this->inspect())
|
1399 |
+
return false;
|
1400 |
+
|
1401 |
+
// Check data to inspect
|
1402 |
+
} elseif ($this->inspect()) {
|
1403 |
+
|
1404 |
+
// Working
|
1405 |
+
return false;
|
1406 |
+
}
|
1407 |
+
|
1408 |
+
// End or next blogroll link
|
1409 |
+
return $this->scans->get_scan_trace($this->scan->id, 'populated_blogroll')? true : $this->content_blogroll();
|
1410 |
+
}
|
1411 |
+
|
1412 |
+
|
1413 |
+
|
1414 |
+
/**
|
1415 |
+
* Retrieve next blogroll link
|
1416 |
+
*/
|
1417 |
+
private function content_blogroll_next($exceptions = array()) {
|
1418 |
+
|
1419 |
+
// Globals
|
1420 |
+
global $wpdb;
|
1421 |
+
|
1422 |
+
// Initialize
|
1423 |
+
$where = '1 = 1';
|
1424 |
+
|
1425 |
+
// Check exceptions
|
1426 |
+
if (!empty($exceptions))
|
1427 |
+
$where .= ' AND link_id NOT IN ('.implode(',', array_map('intval', $exceptions)).')';
|
1428 |
+
|
1429 |
+
// Check last identifier condition
|
1430 |
+
$last_id = (int) $this->scans->get_scan_trace($this->scan->id, 'last_blogroll_id');
|
1431 |
+
if (!empty($last_id))
|
1432 |
+
$where .= ' AND link_id '.(('asc' == $this->scan->crawl_order)? '>' : '<').' '.$last_id;
|
1433 |
+
|
1434 |
+
// Set arguments
|
1435 |
+
$this->set_blogroll_args();
|
1436 |
+
|
1437 |
+
// Query next blogroll link
|
1438 |
+
$bookmark = $wpdb->get_row('SELECT link_id, link_url, link_name FROM '.$wpdb->links.' WHERE '.$where.' ORDER BY '.$this->blogroll_args['order_by'].' LIMIT 1');
|
1439 |
+
|
1440 |
+
// Check if bookmark is previously registered
|
1441 |
+
if (!empty($bookmark) && $this->scans->scan_object_exists($this->scan->id, $bookmark->link_id, 'blogroll')) {
|
1442 |
+
$exceptions[] = $bookmark->link_id;
|
1443 |
+
$bookmark = $this->content_blogroll_next($exceptions);
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
// Done
|
1447 |
+
return empty($bookmark)? false : $bookmark;
|
1448 |
+
}
|
1449 |
+
|
1450 |
+
|
1451 |
+
|
1452 |
+
/**
|
1453 |
+
* Extract links from content
|
1454 |
+
*/
|
1455 |
+
private function extract_links($content, $parent_url, $object_id, $object_type, $object_post_type, $object_field, $object_date_gmt) {
|
1456 |
+
|
1457 |
+
// Initialize
|
1458 |
+
$links = array();
|
1459 |
+
|
1460 |
+
// Check links
|
1461 |
+
if (preg_match_all('/(<a[^>]+href=["|\'](.+)["|\'][^>]*>)(.*)<\/a>/isUu', $content, $matches, PREG_SET_ORDER) > 0) {
|
1462 |
+
|
1463 |
+
// Enum matched links tags
|
1464 |
+
foreach ($matches as $match) {
|
1465 |
+
|
1466 |
+
// Skip page anchor
|
1467 |
+
if ('#' == mb_substr($match[2], 0, 1))
|
1468 |
+
continue;
|
1469 |
+
|
1470 |
+
// Check anchor
|
1471 |
+
$anchor = $match[3];
|
1472 |
+
if (!$this->filter_anchor_text($anchor))
|
1473 |
+
continue;
|
1474 |
+
|
1475 |
+
// Check URL
|
1476 |
+
$urlinfo = $this->urlo->parse($match[2], $parent_url);
|
1477 |
+
if (!$this->filter_include_urls($urlinfo['url']) || !$this->filter_exclude_urls($urlinfo['url']))
|
1478 |
+
continue;
|
1479 |
+
|
1480 |
+
// Check attributes
|
1481 |
+
$attributes = $this->urlo->extract_attributes($match[1]);
|
1482 |
+
if (!$this->filter_html_attributes('a', $attributes))
|
1483 |
+
continue;
|
1484 |
+
|
1485 |
+
// Check nofollow
|
1486 |
+
$nofollow = false;
|
1487 |
+
if (!empty($attributes['rel'])) {
|
1488 |
+
$values = explode(' ', strtolower(str_replace("\n", ' ', str_replace("\r", ' ', $attributes['rel']))));
|
1489 |
+
if (in_array('nofollow', $values))
|
1490 |
+
$nofollow = true;
|
1491 |
+
}
|
1492 |
+
|
1493 |
+
// Add item
|
1494 |
+
$links[] = array_merge($urlinfo, array(
|
1495 |
+
'chunk' => $match[0],
|
1496 |
+
'anchor' => $anchor,
|
1497 |
+
'nofollow' => $nofollow,
|
1498 |
+
'attributes' => $attributes,
|
1499 |
+
'link_type' => 'links',
|
1500 |
+
'object_id' => $object_id,
|
1501 |
+
'object_type' => $object_type,
|
1502 |
+
'object_post_type' => $object_post_type,
|
1503 |
+
'object_field' => $object_field,
|
1504 |
+
'object_date_gmt' => $object_date_gmt,
|
1505 |
+
));
|
1506 |
+
}
|
1507 |
+
}
|
1508 |
+
|
1509 |
+
// Done
|
1510 |
+
return $links;
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
|
1514 |
+
|
1515 |
+
/**
|
1516 |
+
* Extract images from content
|
1517 |
+
*/
|
1518 |
+
private function extract_images($content, $parent_url, $object_id, $object_type, $object_post_type, $object_field, $object_date_gmt) {
|
1519 |
+
|
1520 |
+
// Initialize
|
1521 |
+
$images = array();
|
1522 |
+
|
1523 |
+
// Check links
|
1524 |
+
if (preg_match_all('/<img[^>]+src=["|\'](.+)["|\'][^>]*>/isUu', $content, $matches, PREG_SET_ORDER) > 0) {
|
1525 |
+
|
1526 |
+
// Enum matched links tags
|
1527 |
+
foreach ($matches as $match) {
|
1528 |
+
|
1529 |
+
// Skip page anchor
|
1530 |
+
if ('#' == mb_substr($match[1], 0, 1))
|
1531 |
+
continue;
|
1532 |
+
|
1533 |
+
// Check URL
|
1534 |
+
$urlinfo = $this->urlo->parse($match[1], $parent_url);
|
1535 |
+
if (!$this->filter_include_urls($urlinfo['url']) || !$this->filter_exclude_urls($urlinfo['url']))
|
1536 |
+
continue;
|
1537 |
+
|
1538 |
+
// Check attributes
|
1539 |
+
$attributes = $this->urlo->extract_attributes($match[0]);
|
1540 |
+
if (!$this->filter_html_attributes('img', $attributes))
|
1541 |
+
continue;
|
1542 |
+
|
1543 |
+
// Add item
|
1544 |
+
$images[] = array_merge($urlinfo, array(
|
1545 |
+
'chunk' => $match[0],
|
1546 |
+
'attributes' => $attributes,
|
1547 |
+
'link_type' => 'images',
|
1548 |
+
'object_id' => $object_id,
|
1549 |
+
'object_type' => $object_type,
|
1550 |
+
'object_post_type' => $object_post_type,
|
1551 |
+
'object_field' => $object_field,
|
1552 |
+
'object_date_gmt' => $object_date_gmt,
|
1553 |
+
));
|
1554 |
+
}
|
1555 |
+
}
|
1556 |
+
|
1557 |
+
// Done
|
1558 |
+
return $images;
|
1559 |
+
}
|
1560 |
+
|
1561 |
+
|
1562 |
+
|
1563 |
+
// Filter content
|
1564 |
+
// ---------------------------------------------------------------------------------------------------
|
1565 |
+
|
1566 |
+
|
1567 |
+
|
1568 |
+
/**
|
1569 |
+
* Check if passes anchor text filters
|
1570 |
+
*/
|
1571 |
+
private function filter_anchor_text($anchor) {
|
1572 |
+
|
1573 |
+
// Check filters
|
1574 |
+
if (empty($this->scan->anchor_filters))
|
1575 |
+
return true;
|
1576 |
+
|
1577 |
+
// Initialize
|
1578 |
+
$passed = array();
|
1579 |
+
|
1580 |
+
// Version without tags
|
1581 |
+
$anchor_text = strip_tags($anchor);
|
1582 |
+
|
1583 |
+
// Enum filters
|
1584 |
+
foreach ($this->scan->anchor_filters as $filter) {
|
1585 |
+
|
1586 |
+
// Check filter
|
1587 |
+
if (empty($filter['type']) || !isset($filter['value']))
|
1588 |
+
continue;
|
1589 |
+
|
1590 |
+
// Check if contains a value
|
1591 |
+
if ('contains' == $filter['type']) {
|
1592 |
+
|
1593 |
+
// Continue if passed
|
1594 |
+
if (isset($passed['contains']) && true === $passed['contains'])
|
1595 |
+
continue;
|
1596 |
+
|
1597 |
+
// Check tag in filter
|
1598 |
+
$is_filter_tag = (false !== strpos($filter['value'], '<') || false !== strpos($filter['value'], '>'));
|
1599 |
+
|
1600 |
+
// Test
|
1601 |
+
$passed['contains'] = (false !== stripos($anchor_text, $filter['value'])) || ($is_filter_tag && false !== stripos($anchor, $filter['value']));
|
1602 |
+
|
1603 |
+
// Check if not contain a value
|
1604 |
+
} elseif ('not-contains' == $filter['type']) {
|
1605 |
+
|
1606 |
+
// Continue if passed
|
1607 |
+
if (isset($passed['contains']) && false === $passed['contains'])
|
1608 |
+
continue;
|
1609 |
+
|
1610 |
+
// Check tag in filter
|
1611 |
+
$is_filter_tag = (false !== strpos($filter['value'], '<') || false !== strpos($filter['value'], '>'));
|
1612 |
+
|
1613 |
+
// Test
|
1614 |
+
$passed['not-contains'] = (false === stripos($anchor_text, $filter['value'])) || ($is_filter_tag && false === stripos($anchor, $filter['value']));
|
1615 |
+
|
1616 |
+
// Check if equal to a value
|
1617 |
+
} elseif ('equal-to' == $filter['type']) {
|
1618 |
+
|
1619 |
+
// Continue if passed
|
1620 |
+
if (isset($passed['equal-to']) && true === $passed['equal-to'])
|
1621 |
+
continue;
|
1622 |
+
|
1623 |
+
// Test
|
1624 |
+
$passed['equal-to'] = ($anchor == $filter['value']);
|
1625 |
+
|
1626 |
+
// Check if not equal to a value
|
1627 |
+
} elseif ('not-equal-to' == $filter['type']) {
|
1628 |
+
|
1629 |
+
// Continue if passed
|
1630 |
+
if (isset($passed['not-equal-to']) && false === $passed['not-equal-to'])
|
1631 |
+
continue;
|
1632 |
+
|
1633 |
+
// Test
|
1634 |
+
$passed['not-equal-to'] = ($anchor != $filter['value']);
|
1635 |
+
|
1636 |
+
// Check if begins with value
|
1637 |
+
} elseif ('begins-with' == $filter['type']) {
|
1638 |
+
|
1639 |
+
// Continue if passed
|
1640 |
+
if (isset($passed['begins-with']) && true === $passed['begins-with'])
|
1641 |
+
continue;
|
1642 |
+
|
1643 |
+
// Test
|
1644 |
+
$passed['begins-with'] = (0 === stripos($anchor, $filter['value']));
|
1645 |
+
|
1646 |
+
// Check if ends with value
|
1647 |
+
} elseif ('ends-by' == $filter['type']) {
|
1648 |
+
|
1649 |
+
// Continue if passed
|
1650 |
+
if (isset($passed['ends-by']) && true === $passed['ends-by'])
|
1651 |
+
continue;
|
1652 |
+
|
1653 |
+
// Test
|
1654 |
+
$passed['ends-by'] = (($temp = strlen($anchor) - strlen($filter['value'])) >= 0 && stripos($anchor, $filter['value'], $temp) !== false);
|
1655 |
+
|
1656 |
+
// Check if is empty
|
1657 |
+
} elseif ('empty' == $filter['type']) {
|
1658 |
+
|
1659 |
+
// Continue if passed
|
1660 |
+
if (isset($passed['empty']))
|
1661 |
+
continue;
|
1662 |
+
|
1663 |
+
// Test
|
1664 |
+
$passed['empty'] = ($anchor === '');
|
1665 |
+
}
|
1666 |
+
}
|
1667 |
+
|
1668 |
+
// Check filters
|
1669 |
+
$checks = array('contains', 'not-contains', 'equal-to', 'not-equal', 'begins-with', 'ends-by', 'empty');
|
1670 |
+
foreach ($checks as $check) {
|
1671 |
+
if (isset($passed[$check]) && false === $passed[$check])
|
1672 |
+
return false;
|
1673 |
+
}
|
1674 |
+
|
1675 |
+
// Done
|
1676 |
+
return true;
|
1677 |
+
}
|
1678 |
+
|
1679 |
+
|
1680 |
+
|
1681 |
+
/**
|
1682 |
+
* Filter for URL including
|
1683 |
+
*/
|
1684 |
+
private function filter_include_urls($url) {
|
1685 |
+
|
1686 |
+
// Check filters
|
1687 |
+
if (empty($this->scan->include_urls))
|
1688 |
+
return true;
|
1689 |
+
|
1690 |
+
// Initialize
|
1691 |
+
$passed = array();
|
1692 |
+
|
1693 |
+
// Enum filters
|
1694 |
+
foreach ($this->scan->include_urls as $filter) {
|
1695 |
+
|
1696 |
+
// Check filter
|
1697 |
+
if (empty($filter['type']) || !isset($filter['value']))
|
1698 |
+
continue;
|
1699 |
+
|
1700 |
+
// Check if match all value
|
1701 |
+
if ('full-url' == $filter['type']) {
|
1702 |
+
|
1703 |
+
// Continue if passed
|
1704 |
+
if (isset($passed['full-url']) && true === $passed['full-url'])
|
1705 |
+
continue;
|
1706 |
+
|
1707 |
+
// Test
|
1708 |
+
$passed['full-url'] = ($url == $filter['value']);
|
1709 |
+
|
1710 |
+
// Check if match a value
|
1711 |
+
} elseif ('matched-string' == $filter['type']) {
|
1712 |
+
|
1713 |
+
// Continue if passed
|
1714 |
+
if (isset($passed['matched-string']) && true === $passed['matched-string'])
|
1715 |
+
continue;
|
1716 |
+
|
1717 |
+
// Test
|
1718 |
+
$passed['matched-string'] = (false !== stripos($url, $filter['value']));
|
1719 |
+
|
1720 |
+
// Check if is prefixed
|
1721 |
+
} elseif ('url-prefix' == $filter['type']) {
|
1722 |
+
|
1723 |
+
// Continue if passed
|
1724 |
+
if (isset($passed['url-prefix']) && true === $passed['url-prefix'])
|
1725 |
+
continue;
|
1726 |
+
|
1727 |
+
// Test
|
1728 |
+
$passed['url-prefix'] = (0 === stripos($url, $filter['value']));
|
1729 |
+
|
1730 |
+
// Check if ends with value
|
1731 |
+
} elseif ('url-suffix' == $filter['type']) {
|
1732 |
+
|
1733 |
+
// Continue if passed
|
1734 |
+
if (isset($passed['url-suffix']) && true === $passed['url-suffix'])
|
1735 |
+
continue;
|
1736 |
+
|
1737 |
+
// Test
|
1738 |
+
$passed['url-suffix'] = (($temp = strlen($url) - strlen($filter['value'])) >= 0 && stripos($url, $filter['value'], $temp) !== false);
|
1739 |
+
}
|
1740 |
+
}
|
1741 |
+
|
1742 |
+
// Check filters
|
1743 |
+
$checks = array('full-url', 'matched-string', 'url-prefix', 'url-suffix');
|
1744 |
+
foreach ($checks as $check) {
|
1745 |
+
if (isset($passed[$check]) && false === $passed[$check])
|
1746 |
+
return false;
|
1747 |
+
}
|
1748 |
+
|
1749 |
+
// Done
|
1750 |
+
return true;
|
1751 |
+
}
|
1752 |
+
|
1753 |
+
|
1754 |
+
|
1755 |
+
/**
|
1756 |
+
* Filter for URL excluding
|
1757 |
+
*/
|
1758 |
+
private function filter_exclude_urls($url) {
|
1759 |
+
|
1760 |
+
// Check filters
|
1761 |
+
if (empty($this->scan->exclude_urls))
|
1762 |
+
return true;
|
1763 |
+
|
1764 |
+
// Initialize
|
1765 |
+
$passed = array();
|
1766 |
+
|
1767 |
+
// Enum filters
|
1768 |
+
foreach ($this->scan->exclude_urls as $filter) {
|
1769 |
+
|
1770 |
+
// Check filter
|
1771 |
+
if (empty($filter['type']) || !isset($filter['value']))
|
1772 |
+
continue;
|
1773 |
+
|
1774 |
+
// Check if match all value
|
1775 |
+
if ('full-url' == $filter['type']) {
|
1776 |
+
|
1777 |
+
// Continue if passed
|
1778 |
+
if (isset($passed['full-url']) && false === $passed['full-url'])
|
1779 |
+
continue;
|
1780 |
+
|
1781 |
+
// Test
|
1782 |
+
$passed['full-url'] = ($url != $filter['value']);
|
1783 |
+
|
1784 |
+
// Check if match a value
|
1785 |
+
} elseif ('matched-string' == $filter['type']) {
|
1786 |
+
|
1787 |
+
// Continue if passed
|
1788 |
+
if (isset($passed['matched-string']) && false === $passed['matched-string'])
|
1789 |
+
continue;
|
1790 |
+
|
1791 |
+
// Test
|
1792 |
+
$passed['matched-string'] = (false === stripos($url, $filter['value']));
|
1793 |
+
|
1794 |
+
// Check if is prefixed
|
1795 |
+
} elseif ('url-prefix' == $filter['type']) {
|
1796 |
+
|
1797 |
+
// Continue if passed
|
1798 |
+
if (isset($passed['url-prefix']) && false === $passed['url-prefix'])
|
1799 |
+
continue;
|
1800 |
+
|
1801 |
+
// Test
|
1802 |
+
$passed['url-prefix'] = (0 !== stripos($url, $filter['value']));
|
1803 |
+
|
1804 |
+
// Check if ends with value
|
1805 |
+
} elseif ('url-suffix' == $filter['type']) {
|
1806 |
+
|
1807 |
+
// Continue if passed
|
1808 |
+
if (isset($passed['url-suffix']) && false === $passed['url-suffix'])
|
1809 |
+
continue;
|
1810 |
+
|
1811 |
+
// Test
|
1812 |
+
$passed['url-suffix'] = (($temp = strlen($url) - strlen($filter['value'])) >= 0 && stripos($url, $filter['value'], $temp) === false);
|
1813 |
+
}
|
1814 |
+
}
|
1815 |
+
|
1816 |
+
// Check filters
|
1817 |
+
$checks = array('full-url', 'matched-string', 'url-prefix', 'url-suffix');
|
1818 |
+
foreach ($checks as $check) {
|
1819 |
+
if (isset($passed[$check]) && false === $passed[$check])
|
1820 |
+
return false;
|
1821 |
+
}
|
1822 |
+
|
1823 |
+
// Done
|
1824 |
+
return true;
|
1825 |
+
}
|
1826 |
+
|
1827 |
+
|
1828 |
+
|
1829 |
+
/**
|
1830 |
+
* Filter based on attributes
|
1831 |
+
*/
|
1832 |
+
private function filter_html_attributes($element, $attributes) {
|
1833 |
+
|
1834 |
+
// Check filters
|
1835 |
+
if (empty($this->scan->html_attributes))
|
1836 |
+
return true;
|
1837 |
+
|
1838 |
+
// Initialize
|
1839 |
+
$passed = array();
|
1840 |
+
|
1841 |
+
// Isolate attributes
|
1842 |
+
$att_names = array_keys($attributes);
|
1843 |
+
|
1844 |
+
// Enum filters
|
1845 |
+
foreach ($this->scan->html_attributes as $filter) {
|
1846 |
+
|
1847 |
+
// Check filter
|
1848 |
+
if (empty($filter['element']) || $element != $filter['element'] || !isset($filter['att']) || empty($filter['having']))
|
1849 |
+
continue;
|
1850 |
+
|
1851 |
+
// Check if not have an attribute
|
1852 |
+
if ('not-have' == $filter['having']) {
|
1853 |
+
|
1854 |
+
// Continue if not passed
|
1855 |
+
if (isset($passed['not-have']) && false === $passed['not-have'])
|
1856 |
+
continue;
|
1857 |
+
|
1858 |
+
// Test
|
1859 |
+
$passed['not-have'] = !in_array($filter['att'], $att_names);
|
1860 |
+
|
1861 |
+
// Contains
|
1862 |
+
} elseif ('contains' == $filter['op']) {
|
1863 |
+
|
1864 |
+
// Continue if passed
|
1865 |
+
if (isset($passed['contains']) && true === $passed['contains'])
|
1866 |
+
continue;
|
1867 |
+
|
1868 |
+
// Need a filter value
|
1869 |
+
if (!isset($filter['value']) || '' === ''.trim($filter['value'])) {
|
1870 |
+
$passed['contains'] = false;
|
1871 |
+
continue;
|
1872 |
+
}
|
1873 |
+
|
1874 |
+
// Check att name compatibility
|
1875 |
+
if (!in_array($filter['att'], $att_names)) {
|
1876 |
+
$passed['contains'] = false;
|
1877 |
+
continue;
|
1878 |
+
}
|
1879 |
+
|
1880 |
+
// Final test
|
1881 |
+
$passed['contains'] = in_array(strtolower($filter['value']), $att_values)? $filter['value'] : false;
|
1882 |
+
|
1883 |
+
// Not contains
|
1884 |
+
} elseif ('not-contains' == $filter['op']) {
|
1885 |
+
|
1886 |
+
// Continue if passed
|
1887 |
+
if (isset($passed['not-contains']) && true === $passed['not-contains'])
|
1888 |
+
continue;
|
1889 |
+
|
1890 |
+
// Need a filter value
|
1891 |
+
if (!isset($filter['value']) || '' === ''.trim($filter['value'])) {
|
1892 |
+
$passed['not-contains'] = false;
|
1893 |
+
continue;
|
1894 |
+
}
|
1895 |
+
|
1896 |
+
// Check att name compatibility
|
1897 |
+
if (!in_array($filter['att'], $att_names)) {
|
1898 |
+
$passed['not-contains'] = false;
|
1899 |
+
continue;
|
1900 |
+
}
|
1901 |
+
|
1902 |
+
// Final test
|
1903 |
+
$passed['not-contains'] = !in_array(strtolower($filter['value']), $att_values)? $filter['value'] : false;
|
1904 |
+
|
1905 |
+
// Equal
|
1906 |
+
} elseif ('equal' == $filter['op']) {
|
1907 |
+
|
1908 |
+
// Continue if passed
|
1909 |
+
if (isset($passed['equal']) && true === $passed['equal'])
|
1910 |
+
continue;
|
1911 |
+
|
1912 |
+
// Test
|
1913 |
+
$passed['equal'] = in_array($filter['att'], $att_names)? ($attributes[$filter['att']] == (isset($filter['value'])? $filter['value'] : '')) : false;
|
1914 |
+
|
1915 |
+
// Not equal
|
1916 |
+
} elseif ('not-equal' == $filter['op']) {
|
1917 |
+
|
1918 |
+
// Continue if passed
|
1919 |
+
if (isset($passed['not-equal']) && false === $passed['not-equal'])
|
1920 |
+
continue;
|
1921 |
+
|
1922 |
+
// Test
|
1923 |
+
$passed['not-equal'] = in_array($filter['att'], $att_names)? ($attributes[$filter['att']] != (isset($filter['value'])? $filter['value'] : '')) : false;
|
1924 |
+
|
1925 |
+
// Not empty value
|
1926 |
+
} elseif ('not-empty' == $filter['op']) {
|
1927 |
+
|
1928 |
+
// Continue if passed
|
1929 |
+
if (isset($passed['not-empty']) && false === $passed['not-empty'])
|
1930 |
+
continue;
|
1931 |
+
|
1932 |
+
// Test
|
1933 |
+
$passed['not-empty'] = in_array($filter['att'], $att_names)? ($attributes[$filter['att']] !== '') : false;
|
1934 |
+
|
1935 |
+
// Empty value
|
1936 |
+
} elseif ('empty' == $filter['op']) {
|
1937 |
+
|
1938 |
+
// Continue if passed
|
1939 |
+
if (isset($passed['empty']) && false === $passed['empty'])
|
1940 |
+
continue;
|
1941 |
+
|
1942 |
+
// Test
|
1943 |
+
$passed['empty'] = in_array($filter['att'], $att_names)? ($attributes[$filter['att']] === '') : false;
|
1944 |
+
}
|
1945 |
+
}
|
1946 |
+
|
1947 |
+
// Check filters
|
1948 |
+
$checks = array('not-have', 'contains', 'not-contains', 'equal', 'not-equal', 'not-empty', 'empty');
|
1949 |
+
foreach ($checks as $check) {
|
1950 |
+
if (isset($passed[$check]) && false === $passed[$check])
|
1951 |
+
return false;
|
1952 |
+
}
|
1953 |
+
|
1954 |
+
// Done
|
1955 |
+
return true;
|
1956 |
+
}
|
1957 |
+
|
1958 |
+
|
1959 |
+
|
1960 |
+
/**
|
1961 |
+
* Extract filter content for queries
|
1962 |
+
*/
|
1963 |
+
private function filter_for_queries() {
|
1964 |
+
|
1965 |
+
|
1966 |
+
/* Initialization */
|
1967 |
+
|
1968 |
+
// Check cache
|
1969 |
+
static $matches;
|
1970 |
+
if (isset($matches))
|
1971 |
+
return $matches;
|
1972 |
+
$matches = array();
|
1973 |
+
|
1974 |
+
// Check configuration
|
1975 |
+
if (!$this->scan->filtered_query)
|
1976 |
+
return $matches;
|
1977 |
+
|
1978 |
+
|
1979 |
+
/* Anchor filters */
|
1980 |
+
|
1981 |
+
// Check anchor filters
|
1982 |
+
if (!empty($this->scan->anchor_filters)) {
|
1983 |
+
|
1984 |
+
// Enum anchor filters
|
1985 |
+
foreach ($this->scan->anchor_filters as $filter) {
|
1986 |
+
|
1987 |
+
// Check filter
|
1988 |
+
if (empty($filter['type']) || !isset($filter['value']) || '' === ''.trim($filter['value']))
|
1989 |
+
continue;
|
1990 |
+
|
1991 |
+
// Match filters
|
1992 |
+
if (in_array($filter['type'], array('contains', 'equal-to', 'begins-with', 'ends-by'))) {
|
1993 |
+
|
1994 |
+
// Need this string
|
1995 |
+
$matches[] = $filter['value'];
|
1996 |
+
}
|
1997 |
+
}
|
1998 |
+
}
|
1999 |
+
|
2000 |
+
|
2001 |
+
/* Include URLs */
|
2002 |
+
|
2003 |
+
// Check include filters
|
2004 |
+
if (!empty($this->scan->include_urls)) {
|
2005 |
+
|
2006 |
+
// Enum include filters
|
2007 |
+
foreach ($this->scan->include_urls as $filter) {
|
2008 |
+
|
2009 |
+
// Check filter
|
2010 |
+
if (empty($filter['type']) || !isset($filter['value']) || '' === ''.trim($filter['value']))
|
2011 |
+
continue;
|
2012 |
+
|
2013 |
+
// Match filters
|
2014 |
+
if (in_array($filter['type'], array('full-url', 'matched-string', 'url-prefix', 'url-suffix'))) {
|
2015 |
+
|
2016 |
+
// Need this string
|
2017 |
+
$matches[] = $filter['value'];
|
2018 |
+
}
|
2019 |
+
}
|
2020 |
+
}
|
2021 |
+
|
2022 |
+
|
2023 |
+
/* HTML attributes */
|
2024 |
+
|
2025 |
+
// Check attributes filters
|
2026 |
+
if (!empty($this->scan->html_attributes)) {
|
2027 |
+
|
2028 |
+
// Enum filters
|
2029 |
+
foreach ($this->scan->html_attributes as $filter) {
|
2030 |
+
|
2031 |
+
// Check filter value
|
2032 |
+
if (!isset($filter['value']) || '' === ''.trim($filter['value']))
|
2033 |
+
continue;
|
2034 |
+
|
2035 |
+
// Check having and attribute part
|
2036 |
+
if (empty($filter['having']) || 'have' != $filter['having'] || empty($filter['att']) || '' == 'att'.trim($filter['att']))
|
2037 |
+
continue;
|
2038 |
+
|
2039 |
+
// Check operation
|
2040 |
+
if (empty($filter['op']) || !in_array($filter['op'], array('contains', 'equal')))
|
2041 |
+
continue;
|
2042 |
+
|
2043 |
+
// Add string
|
2044 |
+
$matches[] = $filter['value'];
|
2045 |
+
}
|
2046 |
+
}
|
2047 |
+
|
2048 |
+
|
2049 |
+
// Done
|
2050 |
+
return $matches;
|
2051 |
+
}
|
2052 |
+
|
2053 |
+
|
2054 |
+
|
2055 |
+
// Data access to store content data
|
2056 |
+
// ---------------------------------------------------------------------------------------------------
|
2057 |
+
|
2058 |
+
|
2059 |
+
|
2060 |
+
/**
|
2061 |
+
* Save links
|
2062 |
+
*/
|
2063 |
+
private function save($links, $parent_post_id = 0) {
|
2064 |
+
|
2065 |
+
// Initialize
|
2066 |
+
$statuses = array();
|
2067 |
+
|
2068 |
+
// Enum links
|
2069 |
+
foreach ($links as $link) {
|
2070 |
+
|
2071 |
+
// Avoid empty URLs
|
2072 |
+
if ('' === ''.trim($link['url']))
|
2073 |
+
continue;
|
2074 |
+
|
2075 |
+
// Malformed links tracking
|
2076 |
+
if ($link['malformed']) {
|
2077 |
+
if (!$this->scan->malformed)
|
2078 |
+
continue;
|
2079 |
+
}
|
2080 |
+
|
2081 |
+
// Search by main URL
|
2082 |
+
if (false !== ($row = $this->scans->get_scan_url(array('url' => $link['url'], 'no_cache' => true)))) {
|
2083 |
+
$url_id = $row->url_id;
|
2084 |
+
|
2085 |
+
// Register scan URL
|
2086 |
+
} elseif (false === ($url_id = $this->scans->add_scan_url($link, $this->scan->id))) {
|
2087 |
+
continue;
|
2088 |
+
}
|
2089 |
+
|
2090 |
+
// Check destination type
|
2091 |
+
if (isset($link['scope']) && in_array($this->scan->destination_type, array('internal', 'external')) && $link['scope'] != $this->scan->destination_type)
|
2092 |
+
continue;
|
2093 |
+
|
2094 |
+
// Save URL location
|
2095 |
+
$this->scans->add_scan_url_location($url_id, $this->scan->id, $link);
|
2096 |
+
|
2097 |
+
// Check our tiny cache
|
2098 |
+
if (in_array($url_id, $statuses))
|
2099 |
+
continue;
|
2100 |
+
|
2101 |
+
// Check if exists a previous status identifier
|
2102 |
+
if (false !== $this->scans->get_scan_url_status(array('url_id' => $url_id, 'scan_id' => $this->scan->id))) {
|
2103 |
+
$statuses[] = $url_id;
|
2104 |
+
continue;
|
2105 |
+
}
|
2106 |
+
|
2107 |
+
// Check phase
|
2108 |
+
$phase = $this->urlo->is_crawleable($link)? 'wait' : 'end';
|
2109 |
+
|
2110 |
+
// Create URL status
|
2111 |
+
$this->scans->add_scan_url_status($url_id, $this->scan->id, $phase);
|
2112 |
+
|
2113 |
+
// Status on
|
2114 |
+
$statuses[] = $url_id;
|
2115 |
+
}
|
2116 |
+
|
2117 |
+
// Done
|
2118 |
+
return $statuses;
|
2119 |
+
}
|
2120 |
+
|
2121 |
+
|
2122 |
+
|
2123 |
+
// Utilities functions
|
2124 |
+
// ---------------------------------------------------------------------------------------------------
|
2125 |
+
|
2126 |
+
|
2127 |
+
|
2128 |
+
/**
|
2129 |
+
* Cast relative URLs to absolute
|
2130 |
+
*/
|
2131 |
+
public function parent_permalink($parent) {
|
2132 |
+
|
2133 |
+
// Check array
|
2134 |
+
if (!is_array($parent) || !isset($parent['post_id']))
|
2135 |
+
return false;
|
2136 |
+
|
2137 |
+
// Check identifier
|
2138 |
+
$post_id = (int) $parent['post_id'];
|
2139 |
+
if (empty($post_id))
|
2140 |
+
return false;
|
2141 |
+
|
2142 |
+
// Return permalink
|
2143 |
+
return $this->get_permalink($post_id);
|
2144 |
+
}
|
2145 |
+
|
2146 |
+
|
2147 |
+
|
2148 |
+
/**
|
2149 |
+
* Retrieve permalink based on WP redirection.
|
2150 |
+
* Here is too early to call WP get_permalink function,
|
2151 |
+
* so we use the short permalink form to catch the redirection.
|
2152 |
+
*/
|
2153 |
+
private function get_permalink($post_id) {
|
2154 |
+
|
2155 |
+
// Permalinks cache
|
2156 |
+
static $permalinks;
|
2157 |
+
if (!isset($permalinks))
|
2158 |
+
$permalinks = array();
|
2159 |
+
|
2160 |
+
// Check cache
|
2161 |
+
if (isset($permalinks[$post_id]))
|
2162 |
+
return $permalinks[$post_id];
|
2163 |
+
|
2164 |
+
// Initialize
|
2165 |
+
$permalinks[$post_id] = false;
|
2166 |
+
|
2167 |
+
// Load cURL wrapper library
|
2168 |
+
wplnst_require('core', 'curl');
|
2169 |
+
|
2170 |
+
// cURL request
|
2171 |
+
$response = WPLNST_Core_CURL::request(array(
|
2172 |
+
'CURLOPT_URL' => $this->urlo->home_url.'/?p='.$post_id,
|
2173 |
+
'CURLOPT_HEADER' => true,
|
2174 |
+
'CURLOPT_NOBODY' => true,
|
2175 |
+
'CURLOPT_HTTPHEADER' => array('Expect:'),
|
2176 |
+
'CURLOPT_FOLLOWLOCATION' => false,
|
2177 |
+
'CURLOPT_RETURNTRANSFER' => true,
|
2178 |
+
'CURLOPT_FRESH_CONNECT' => true,
|
2179 |
+
'CURLOPT_CONNECTTIMEOUT' => $this->connect_timeout,
|
2180 |
+
'CURLOPT_TIMEOUT' => $this->request_timeout,
|
2181 |
+
'CURLOPT_USERAGENT' => wplnst_get_tsetting('user_agent'),
|
2182 |
+
));
|
2183 |
+
|
2184 |
+
// Check response
|
2185 |
+
if ($response['error'])
|
2186 |
+
return false;
|
2187 |
+
|
2188 |
+
// Check response
|
2189 |
+
$data = trim($response['data']);
|
2190 |
+
if (empty($data))
|
2191 |
+
return false;
|
2192 |
+
|
2193 |
+
// Enum response links
|
2194 |
+
$data = explode("\n", $data);
|
2195 |
+
foreach ($data as $line) {
|
2196 |
+
|
2197 |
+
// Clear line
|
2198 |
+
$line = trim(preg_replace('/\s+/', ' ', $line));
|
2199 |
+
|
2200 |
+
// Check redirection in status code
|
2201 |
+
if (!isset($status_code) && 0 === stripos($line, 'HTTP/')) {
|
2202 |
+
$line = explode(' ', $line);
|
2203 |
+
if (count($line) > 1) {
|
2204 |
+
$status_code = trim($line[1]);
|
2205 |
+
if ('30' != mb_substr($status_code, 0, 2))
|
2206 |
+
return false;
|
2207 |
+
}
|
2208 |
+
|
2209 |
+
// Check Location
|
2210 |
+
} elseif (isset($status_code) && 0 === stripos($line, 'location:')) {
|
2211 |
+
$location = trim(mb_substr($line, 9));
|
2212 |
+
$parts = @parse_url($location);
|
2213 |
+
if (!empty($parts['scheme']) && !empty($parts['host']))
|
2214 |
+
$permalinks[$post_id] = $location;
|
2215 |
+
}
|
2216 |
+
}
|
2217 |
+
|
2218 |
+
// Done
|
2219 |
+
return $permalinks[$post_id];
|
2220 |
+
}
|
2221 |
+
|
2222 |
+
|
2223 |
+
|
2224 |
+
// Internal debug
|
2225 |
+
private function debug($message) {
|
2226 |
+
wplnst_debug('scan '.$this->scan->id.' - thread '.$this->thread_id.' - '.$message, 'crawler');
|
2227 |
+
}
|
2228 |
+
|
2229 |
+
|
2230 |
+
|
2231 |
+
/**
|
2232 |
+
* Start again the crawler
|
2233 |
+
*/
|
2234 |
+
protected function restart() {
|
2235 |
+
WPLNST_Core_Alive::run($this->scan->id, $this->scan->hash, $this->thread_id);
|
2236 |
+
}
|
2237 |
+
|
2238 |
+
|
2239 |
+
|
2240 |
+
/**
|
2241 |
+
* Calls alive activity method to check scans activity
|
2242 |
+
*/
|
2243 |
+
protected function activity() {
|
2244 |
+
WPLNST_Core_Alive::activity(true);
|
2245 |
+
}
|
2246 |
+
|
2247 |
+
|
2248 |
+
|
2249 |
+
}
|
core/curl.php
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core CURL class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_CURL {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Spawn async request
|
15 |
+
*/
|
16 |
+
public static function spawn($setopts = array()) {
|
17 |
+
self::request(array_merge(array(
|
18 |
+
'CURLOPT_HEADER' => false,
|
19 |
+
'CURLOPT_NOBODY' => true,
|
20 |
+
'CURLOPT_FOLLOWLOCATION' => false,
|
21 |
+
'CURLOPT_RETURNTRANSFER' => false,
|
22 |
+
'CURLOPT_FRESH_CONNECT' => true,
|
23 |
+
'CURLOPT_CONNECTTIMEOUT' => 1,
|
24 |
+
'CURLOPT_TIMEOUT' => 1,
|
25 |
+
), $setopts));
|
26 |
+
}
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Submit a POST request
|
32 |
+
*/
|
33 |
+
public static function post($setopts = array(), $postfields = array()) {
|
34 |
+
return self::request(array_merge(array(
|
35 |
+
'CURLOPT_HEADER' => false,
|
36 |
+
'CURLOPT_NOBODY' => false,
|
37 |
+
'CURLOPT_FOLLOWLOCATION' => false,
|
38 |
+
'CURLOPT_RETURNTRANSFER' => true,
|
39 |
+
'CURLOPT_FRESH_CONNECT' => true,
|
40 |
+
'CURLOPT_POST' => true,
|
41 |
+
'CURLOPT_POSTFIELDS' => http_build_query($postfields, null, '&'),
|
42 |
+
'CURLOPT_HTTPHEADER' => array('Content-Type: application/x-www-form-urlencoded; charset=utf-8'),
|
43 |
+
), $setopts));
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Basic cURL wrapper
|
50 |
+
*/
|
51 |
+
public static function request($setopts = array(), $getinfo = array()) {
|
52 |
+
|
53 |
+
// Default
|
54 |
+
$response = array(
|
55 |
+
'data' => '',
|
56 |
+
'info' => array(),
|
57 |
+
'error' => true,
|
58 |
+
'errno' => 0,
|
59 |
+
'reason' => '',
|
60 |
+
'time' => 0,
|
61 |
+
'timestamp' => 0,
|
62 |
+
);
|
63 |
+
|
64 |
+
// Check cURL support
|
65 |
+
if (function_exists('wplnst_is_curl_enabled') && !wplnst_is_curl_enabled()) {
|
66 |
+
$response['reason'] = 'curl_disabled';
|
67 |
+
return $response;
|
68 |
+
}
|
69 |
+
|
70 |
+
// cURL session
|
71 |
+
if (false === ($ch = @curl_init())) {
|
72 |
+
$response['reason'] = 'curl_init';
|
73 |
+
return $response;
|
74 |
+
}
|
75 |
+
|
76 |
+
// Apply options
|
77 |
+
foreach ($setopts as $name => $value) {
|
78 |
+
if (defined($name))
|
79 |
+
@curl_setopt($ch, constant($name), $value);
|
80 |
+
}
|
81 |
+
|
82 |
+
// Now
|
83 |
+
$response['timestamp'] = time();
|
84 |
+
|
85 |
+
// Timer
|
86 |
+
$time_start = microtime(true);
|
87 |
+
|
88 |
+
// Retrieve response
|
89 |
+
$response['data'] = @curl_exec($ch);
|
90 |
+
|
91 |
+
// Time amount
|
92 |
+
$response['time'] = microtime(true) - $time_start;
|
93 |
+
|
94 |
+
// Copy error number
|
95 |
+
$response['errno'] = (int) @curl_errno($ch);
|
96 |
+
|
97 |
+
// Check info
|
98 |
+
foreach ($getinfo as $info) {
|
99 |
+
if (defined($info))
|
100 |
+
$response['info'][$info] = @curl_getinfo($ch, constant($info));
|
101 |
+
}
|
102 |
+
|
103 |
+
// Close connection
|
104 |
+
@curl_close($ch);
|
105 |
+
|
106 |
+
// Check error
|
107 |
+
$response['error'] = ($response['errno'] > 0);
|
108 |
+
|
109 |
+
// Done
|
110 |
+
return $response;
|
111 |
+
}
|
112 |
+
|
113 |
+
|
114 |
+
|
115 |
+
}
|
core/module.php
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Module class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
abstract class WPLNST_Core_Module {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
// Properties
|
14 |
+
// ---------------------------------------------------------------------------------------------------
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Scans object
|
20 |
+
*/
|
21 |
+
public $scans;
|
22 |
+
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* URL object
|
27 |
+
*/
|
28 |
+
public $url;
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Singleton objects
|
34 |
+
*/
|
35 |
+
private static $instances = array();
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
// Initialization
|
40 |
+
// ---------------------------------------------------------------------------------------------------
|
41 |
+
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Private constructor, call plugin custom method
|
46 |
+
*/
|
47 |
+
private function __construct($args = null) {
|
48 |
+
$this->on_construct($args);
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Creates a singleton object instance
|
55 |
+
* Avoided use of get_called_class for PHP < 5.3 compatibility
|
56 |
+
*/
|
57 |
+
protected static function get_instance($classname, $args = null) {
|
58 |
+
if (!isset(self::$instances[$classname]))
|
59 |
+
self::$instances[$classname] = new $classname($args);
|
60 |
+
return self::$instances[$classname];
|
61 |
+
}
|
62 |
+
|
63 |
+
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Do nothing, to override
|
67 |
+
*/
|
68 |
+
protected function on_construct($args = null) {}
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
// Plugins objects load
|
73 |
+
// ---------------------------------------------------------------------------------------------------
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Return scans object
|
79 |
+
*/
|
80 |
+
public function load_scans_object() {
|
81 |
+
if (!isset($this->scans)) {
|
82 |
+
wplnst_require('core', 'scans');
|
83 |
+
$this->scans = new WPLNST_Core_Scans();
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Return URL object
|
91 |
+
*/
|
92 |
+
public function load_url_object() {
|
93 |
+
if (!isset($this->urlo)) {
|
94 |
+
wplnst_require('core', 'url');
|
95 |
+
$this->urlo = new WPLNST_Core_URL();
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
|
101 |
+
// Wrapper methods
|
102 |
+
// ---------------------------------------------------------------------------------------------------
|
103 |
+
|
104 |
+
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Wrapper method of WPLNST_Core_Scans class
|
108 |
+
*/
|
109 |
+
public function get_scans($args) {
|
110 |
+
$this->load_scans_object();
|
111 |
+
return $this->scans->get_scans($args);
|
112 |
+
}
|
113 |
+
|
114 |
+
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Wrapper method of WPLNST_Core_Scans class
|
118 |
+
*/
|
119 |
+
public function get_scan_by_id($scan_id, $setup_names = false, $no_cache = false) {
|
120 |
+
$this->load_scans_object();
|
121 |
+
return $this->scans->get_scan_by_id($scan_id, $setup_names, $no_cache);
|
122 |
+
}
|
123 |
+
|
124 |
+
|
125 |
+
|
126 |
+
// AJAX wrappers
|
127 |
+
// ---------------------------------------------------------------------------------------------------
|
128 |
+
|
129 |
+
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Check and initialize ajax respose
|
133 |
+
*/
|
134 |
+
protected static function check_ajax_submit(&$response, $capability, $nonce = null) {
|
135 |
+
|
136 |
+
// Check default output
|
137 |
+
if (!isset($response))
|
138 |
+
$response = self::default_ajax_response($nonce);
|
139 |
+
|
140 |
+
// Check user capabilities
|
141 |
+
if (!current_user_can($capability)) {
|
142 |
+
$response['status'] = 'error';
|
143 |
+
$response['reason'] = __('Sorry, current user can`t perform this action', 'wplnst');
|
144 |
+
return false;
|
145 |
+
|
146 |
+
// Check if submitted nonce matches with the generated nonce we created earlier
|
147 |
+
} elseif (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], isset($nonce)? $nonce : __FILE__)) {
|
148 |
+
$response['status'] = 'error';
|
149 |
+
$response['reason'] = __('Sorry, security verification error. Please reload this page and try again.', 'wplnst');
|
150 |
+
return false;
|
151 |
+
}
|
152 |
+
|
153 |
+
// Submit Ok
|
154 |
+
return true;
|
155 |
+
}
|
156 |
+
|
157 |
+
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Return array of ajax response
|
161 |
+
*/
|
162 |
+
protected static function default_ajax_response($nonce = null) {
|
163 |
+
return array(
|
164 |
+
'status' => 'ok',
|
165 |
+
'reason' => '',
|
166 |
+
'nonce' => (isset($nonce) && false === $nonce)? '' : wp_create_nonce(isset($nonce)? $nonce : __FILE__),
|
167 |
+
'data' => array(),
|
168 |
+
);
|
169 |
+
}
|
170 |
+
|
171 |
+
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Custom error ajax response
|
175 |
+
*/
|
176 |
+
protected static function error_ajax_response($reason, $nonce = false) {
|
177 |
+
$response = self::default_ajax_response($nonce);
|
178 |
+
$response['status'] = 'error';
|
179 |
+
$response['reason'] = $reason;
|
180 |
+
self::output_ajax_response($response);
|
181 |
+
}
|
182 |
+
|
183 |
+
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Output AJAX in JSON format and exit
|
187 |
+
*/
|
188 |
+
protected static function output_ajax_response($response) {
|
189 |
+
@header('Content-Type: application/json');
|
190 |
+
die(@json_encode($response));
|
191 |
+
}
|
192 |
+
|
193 |
+
|
194 |
+
|
195 |
+
}
|
core/nonce/nonce.php
ADDED
@@ -0,0 +1,310 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Nonce class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Nonce {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
// Public methods
|
14 |
+
// ----------------------------------------------------------------------------------------
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Create a new, user-independent, 24H valid nonce
|
20 |
+
*/
|
21 |
+
public static function create_nonce($action = '') {
|
22 |
+
return substr(self::get_hash(self::nonce_tick().'|'.$action.'|'.__FILE__), -12, 10);
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
/*
|
28 |
+
* Check valid nonce
|
29 |
+
*/
|
30 |
+
public static function verify_nonce($nonce, $action = '') {
|
31 |
+
|
32 |
+
// First check
|
33 |
+
$nonce = (string) $nonce;
|
34 |
+
if (empty($nonce))
|
35 |
+
return false;
|
36 |
+
|
37 |
+
// Time based "tick"
|
38 |
+
$tick = self::nonce_tick();
|
39 |
+
|
40 |
+
// Nonce generated 0-12 hours ago
|
41 |
+
$expected = substr(self::get_hash($tick.'|'.$action.'|'.__FILE__), -12, 10);
|
42 |
+
if (self::hash_equals($expected, $nonce))
|
43 |
+
return 1;
|
44 |
+
|
45 |
+
// Nonce generated 12-24 hours ago
|
46 |
+
$expected = substr(self::get_hash(($tick - 1).'|'.$action.'|'.__FILE__), -12, 10);
|
47 |
+
return self::hash_equals($expected, $nonce)? 2 : false;
|
48 |
+
}
|
49 |
+
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Get system salt and hash data
|
54 |
+
*/
|
55 |
+
public static function get_hash($data) {
|
56 |
+
$salt = self::get_salt();
|
57 |
+
return self::hash_hmac('md5', $data, $salt);
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Generates random number
|
64 |
+
**/
|
65 |
+
public static function get_rand( $min = 0, $max = 0 ) {
|
66 |
+
|
67 |
+
global $wplnst_rnd_value;
|
68 |
+
|
69 |
+
// Reset $rnd_value after 14 uses
|
70 |
+
// 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value
|
71 |
+
if ( strlen($wplnst_rnd_value) < 8 ) {
|
72 |
+
$wplnst_rnd_value = md5(uniqid(microtime().mt_rand(), true));
|
73 |
+
$wplnst_rnd_value .= sha1($wplnst_rnd_value);
|
74 |
+
$wplnst_rnd_value .= sha1($wplnst_rnd_value);
|
75 |
+
}
|
76 |
+
|
77 |
+
// Take the first 8 digits for our value
|
78 |
+
$value = substr($wplnst_rnd_value, 0, 8);
|
79 |
+
|
80 |
+
// Strip the first eight, leaving the remainder for the next call to wp_rand().
|
81 |
+
$wplnst_rnd_value = substr($wplnst_rnd_value, 8);
|
82 |
+
|
83 |
+
$value = abs(hexdec($value));
|
84 |
+
|
85 |
+
// Some misconfigured 32bit environments (Entropy PHP, for example) truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats.
|
86 |
+
$max_random_number = 3000000000 === 2147483647 ? (float) "4294967295" : 4294967295; // 4294967295 = 0xffffffff
|
87 |
+
|
88 |
+
// Reduce the value to be within the min - max range
|
89 |
+
if ($max != 0)
|
90 |
+
$value = $min + ($max - $min + 1) * $value / ($max_random_number + 1);
|
91 |
+
|
92 |
+
return abs(intval($value));
|
93 |
+
}
|
94 |
+
|
95 |
+
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Password generation
|
99 |
+
*/
|
100 |
+
public static function generate_password($length = 12, $special_chars = true, $extra_special_chars = false) {
|
101 |
+
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
102 |
+
if ($special_chars)
|
103 |
+
$chars .= '!@#$%^&*()';
|
104 |
+
if ($extra_special_chars)
|
105 |
+
$chars .= '-_ []{}<>~`+=,.;:/?|';
|
106 |
+
$password = '';
|
107 |
+
for ($i = 0; $i < $length; $i++)
|
108 |
+
$password .= substr($chars, self::get_rand(0, strlen($chars) - 1), 1);
|
109 |
+
return $password;
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Check and creates new salt file
|
116 |
+
*/
|
117 |
+
public static function check_salt_file() {
|
118 |
+
return self::salt_file_ready()? true : self::create_salt_file();
|
119 |
+
}
|
120 |
+
|
121 |
+
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Check salt file and constant
|
125 |
+
*/
|
126 |
+
public static function salt_file_ready() {
|
127 |
+
|
128 |
+
// Check if file exists
|
129 |
+
$path = self::salt_file_path();
|
130 |
+
if (!@file_exists($path) || !@is_readable($path))
|
131 |
+
return false;
|
132 |
+
|
133 |
+
// Require
|
134 |
+
@require_once($path);
|
135 |
+
return defined('WPLNST_SALT');
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Attempt to create a salt file
|
142 |
+
*/
|
143 |
+
public static function create_salt_file() {
|
144 |
+
$path = self::salt_file_path();
|
145 |
+
if (!@is_writable(dirname($path)))
|
146 |
+
return false;
|
147 |
+
$result = @file_put_contents($path, "<?php /* Generated by WP Link Status: PLEASE DO NOT REMOVE OR MODIFY THIS FILE */"."\n"."define('WPLNST_SALT', '".self::generate_password(64, false, false)."');");
|
148 |
+
@chmod($path, 0664);
|
149 |
+
return (false !== $result && @file_exists($path) && @is_readable($path));
|
150 |
+
}
|
151 |
+
|
152 |
+
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Remove custom salt file
|
156 |
+
*/
|
157 |
+
public static function remove_salt_file() {
|
158 |
+
$path = self::salt_file_path();
|
159 |
+
if (@file_exists($path))
|
160 |
+
@unlink($path);
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
|
165 |
+
// Internal functions
|
166 |
+
// ----------------------------------------------------------------------------------------
|
167 |
+
|
168 |
+
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Creates a "tick", time based
|
172 |
+
* This is a clone of WP nonce_tick function without constants and filters
|
173 |
+
*/
|
174 |
+
private static function nonce_tick() {
|
175 |
+
return ceil(time()/(86400/2));
|
176 |
+
}
|
177 |
+
|
178 |
+
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Unique salt to hash strings
|
182 |
+
*/
|
183 |
+
private static function get_salt() {
|
184 |
+
|
185 |
+
// Process cache
|
186 |
+
static $cached_salt;
|
187 |
+
if (isset($cached_salt))
|
188 |
+
return $cached_salt;
|
189 |
+
|
190 |
+
// Salt from file
|
191 |
+
$salt = self::get_salt_stored();
|
192 |
+
if (empty($salt))
|
193 |
+
$salt = php_uname().'|'.phpversion().'|'.__FILE__;
|
194 |
+
|
195 |
+
// Store hash
|
196 |
+
$cached_salt = md5($salt);
|
197 |
+
return $cached_salt;
|
198 |
+
}
|
199 |
+
|
200 |
+
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Return salt from config file
|
204 |
+
*/
|
205 |
+
private static function get_salt_stored() {
|
206 |
+
|
207 |
+
// Require file
|
208 |
+
if (!defined('WPLNST_SALT'))
|
209 |
+
self::require_salt_file();
|
210 |
+
|
211 |
+
// Check constant
|
212 |
+
return defined('WPLNST_SALT')? WPLNST_SALT : false;
|
213 |
+
}
|
214 |
+
|
215 |
+
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Check if file exists and require config file
|
219 |
+
*/
|
220 |
+
private static function require_salt_file() {
|
221 |
+
|
222 |
+
// Check if file exists
|
223 |
+
$path = self::salt_file_path();
|
224 |
+
if (!@file_exists($path) || !@is_readable($path))
|
225 |
+
return false;
|
226 |
+
|
227 |
+
// Require
|
228 |
+
@require_once($path);
|
229 |
+
}
|
230 |
+
|
231 |
+
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Salt path and filename
|
235 |
+
* Yest, it is very ugly
|
236 |
+
*/
|
237 |
+
private static function salt_file_path() {
|
238 |
+
return dirname(dirname(dirname(dirname(dirname(__FILE__))))).'/wp-link-status-salt.php';
|
239 |
+
}
|
240 |
+
|
241 |
+
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Wrapper for hash_hmac function
|
245 |
+
*/
|
246 |
+
private static function hash_hmac($algo, $data, $key, $raw_output = false) {
|
247 |
+
|
248 |
+
// Check existing function
|
249 |
+
if (function_exists('hash_hmac')) {
|
250 |
+
return hash_hmac($algo, $data, $key, $raw_output);
|
251 |
+
|
252 |
+
// From WP
|
253 |
+
} else {
|
254 |
+
|
255 |
+
$packs = array('md5' => 'H32', 'sha1' => 'H40');
|
256 |
+
|
257 |
+
if (!isset($packs[$algo]))
|
258 |
+
return false;
|
259 |
+
|
260 |
+
$pack = $packs[$algo];
|
261 |
+
|
262 |
+
if (strlen($key) > 64)
|
263 |
+
$key = pack($pack, $algo($key));
|
264 |
+
|
265 |
+
$key = str_pad($key, 64, chr(0));
|
266 |
+
|
267 |
+
$ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));
|
268 |
+
$opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));
|
269 |
+
|
270 |
+
$hmac = $algo($opad.pack($pack, $algo($ipad.$data)));
|
271 |
+
|
272 |
+
if ($raw_output)
|
273 |
+
return pack($pack, $hmac);
|
274 |
+
|
275 |
+
return $hmac;
|
276 |
+
}
|
277 |
+
}
|
278 |
+
|
279 |
+
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Wrapper for hash_equals function
|
283 |
+
*/
|
284 |
+
private static function hash_equals($a, $b) {
|
285 |
+
|
286 |
+
// Check existing function
|
287 |
+
if (function_exists('hash_equals')) {
|
288 |
+
return hash_equals($a, $b);
|
289 |
+
|
290 |
+
// From WP
|
291 |
+
} else {
|
292 |
+
|
293 |
+
$a_length = strlen($a);
|
294 |
+
if ($a_length !== strlen($b))
|
295 |
+
return false;
|
296 |
+
|
297 |
+
$result = 0;
|
298 |
+
|
299 |
+
// Do not attempt to "optimize" this.
|
300 |
+
for ($i = 0; $i < $a_length; $i++) {
|
301 |
+
$result |= ord($a[$i]) ^ ord($b[$i]);
|
302 |
+
}
|
303 |
+
|
304 |
+
return $result === 0;
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
|
309 |
+
|
310 |
+
}
|
core/notify.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Notify class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Notify {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Send a notification of scan completed
|
15 |
+
*/
|
16 |
+
public static function completed($scan) {
|
17 |
+
|
18 |
+
// Get current notifications
|
19 |
+
$notifications = self::get_notifications();
|
20 |
+
if (!in_array($scan->id, $notifications)) {
|
21 |
+
|
22 |
+
// Add scan to notifications
|
23 |
+
$notifications[] = $scan->id;
|
24 |
+
self::set_notifications($notifications);
|
25 |
+
|
26 |
+
// Spawn admin ajax URL
|
27 |
+
wplnst_require('core', 'curl');
|
28 |
+
WPLNST_Core_CURL::spawn(array('CURLOPT_URL' => add_query_arg(array(
|
29 |
+
'wplnst_notify_email' => 'on',
|
30 |
+
'wplnst_notify_nonce' => WPLNST_Core_Alive::get_notify_nonce(),
|
31 |
+
), rtrim(admin_url('admin-ajax.php'), '/'))));
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Check for pending notifications
|
39 |
+
*/
|
40 |
+
public static function check() {
|
41 |
+
|
42 |
+
// Retrieve notifications
|
43 |
+
$notifications = self::get_notifications();
|
44 |
+
if (empty($notifications))
|
45 |
+
return;
|
46 |
+
|
47 |
+
// Extract first element
|
48 |
+
$scan_id = (int) array_shift($notifications);
|
49 |
+
self::set_notifications($notifications);
|
50 |
+
|
51 |
+
// Check identifier
|
52 |
+
if (!$scan_id > 0)
|
53 |
+
return;
|
54 |
+
|
55 |
+
// Check scan
|
56 |
+
global $wpdb;
|
57 |
+
$scan_row = $wpdb->get_row($wpdb->prepare('SELECT name, config FROM '.$wpdb->prefix.'wplnst_scans WHERE scan_id = %d', $scan_id));
|
58 |
+
if (empty($scan_row) || !is_object($scan_row))
|
59 |
+
return;
|
60 |
+
|
61 |
+
// Extract configuration
|
62 |
+
$config = @json_decode($scan_row->config, true);
|
63 |
+
if (empty($config) || !is_array($config))
|
64 |
+
return;
|
65 |
+
|
66 |
+
// Initialize
|
67 |
+
$emails = array();
|
68 |
+
|
69 |
+
// Default e-mail
|
70 |
+
if (isset($config['notify_default']) && true === $config['notify_default']) {
|
71 |
+
$admin_email = get_option('admin_email');
|
72 |
+
if (!empty($admin_email) && is_email($admin_email))
|
73 |
+
$emails[] = $admin_email;
|
74 |
+
}
|
75 |
+
|
76 |
+
// New addresses
|
77 |
+
if (isset($config['notify_address']) && true === $config['notify_address'] && !empty($config['notify_address_email'])) {
|
78 |
+
$addresses = str_replace(',', ';', $config['notify_address_email']);
|
79 |
+
$addresses = explode(';', $addresses);
|
80 |
+
foreach ($addresses as $address) {
|
81 |
+
if (!empty($address) && is_email($address))
|
82 |
+
$emails[] = $address;
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
// Check collection
|
87 |
+
if (empty($emails))
|
88 |
+
return;
|
89 |
+
|
90 |
+
// Send
|
91 |
+
$result = wp_mail(array_unique($emails), __('WP Link Status scan completed', 'wplnst'),
|
92 |
+
sprintf(__('
|
93 |
+
|
94 |
+
Your scan is completed, you can see the results here:
|
95 |
+
|
96 |
+
%s
|
97 |
+
%s
|
98 |
+
|
99 |
+
', 'wplnst'), empty($scan_row->name)? __('(no name)', 'wplnst') : $scan_row->name, WPLNST_Core_Plugin::get_url_scans_results($scan_id)));
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Retrieve option with scans to notify
|
106 |
+
*/
|
107 |
+
private static function get_notifications() {
|
108 |
+
$notifications = @json_decode(get_option('wplnst_notifications'), true);
|
109 |
+
return (empty($notifications) || !is_array($notifications))? array() : $notifications;
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Save notifications
|
116 |
+
*/
|
117 |
+
private static function set_notifications($notifications) {
|
118 |
+
return update_option('wplnst_notifications', @json_encode($notifications));
|
119 |
+
}
|
120 |
+
|
121 |
+
|
122 |
+
|
123 |
+
}
|
core/plugin.php
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Plugin class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Plugin {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
// Constants
|
14 |
+
// ---------------------------------------------------------------------------------------------------
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Plugin
|
20 |
+
*/
|
21 |
+
const title = 'WP Link Status';
|
22 |
+
const slug = 'wp-link-status';
|
23 |
+
const capability = 'manage_options';
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
// Compose sections URLs
|
28 |
+
// ---------------------------------------------------------------------------------------------------
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Retrieves scan base admin URL or extended
|
34 |
+
*/
|
35 |
+
public static function get_url_scans() {
|
36 |
+
return admin_url('admin.php?page='.self::slug);
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* URL for new scan
|
43 |
+
*/
|
44 |
+
public static function get_url_scans_add() {
|
45 |
+
return self::get_url_scans().'-new-scan';
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* URL to edit a scan
|
52 |
+
*/
|
53 |
+
public static function get_url_scans_edit($scan_id, $updated = false, $started = false) {
|
54 |
+
return self::get_url_scans().'&scan_id='.$scan_id.'&context=edit'.($updated? '&updated=on'.((false !== $started)? '&started='.$started : '') : '');
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
|
59 |
+
/**
|
60 |
+
* URL to start/stop scan
|
61 |
+
*/
|
62 |
+
public static function get_url_scans_crawler($scan_id, $operation, $hash) {
|
63 |
+
return self::get_url_scans().'&scan_id='.$scan_id.'&context=crawler&operation='.$operation.'&nonce='.wp_create_nonce('scan-crawler-'.$hash);
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* URL to show scan results
|
70 |
+
*/
|
71 |
+
public static function get_url_scans_results($scan_id) {
|
72 |
+
return self::get_url_scans().'&scan_id='.$scan_id.'&context=results';
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* URL to remove scan
|
79 |
+
*/
|
80 |
+
public static function get_url_scans_delete($scan_id, $hash) {
|
81 |
+
return self::get_url_scans().'&scan_id='.$scan_id.'&context=delete&nonce='.wp_create_nonce($hash);
|
82 |
+
}
|
83 |
+
|
84 |
+
|
85 |
+
|
86 |
+
/**
|
87 |
+
* URL for settings page
|
88 |
+
*/
|
89 |
+
public static function get_url_settings() {
|
90 |
+
return self::get_url_scans().'-settings';
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
+
|
95 |
+
/**
|
96 |
+
* URL for extensions page
|
97 |
+
*/
|
98 |
+
public static function get_url_extensions() {
|
99 |
+
return self::get_url_scans().'-extensions';
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
|
104 |
+
// Other plugin methods
|
105 |
+
// ---------------------------------------------------------------------------------------------------
|
106 |
+
|
107 |
+
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Load translation file
|
111 |
+
*/
|
112 |
+
public static function load_plugin_textdomain($lang_dir = '') {
|
113 |
+
load_plugin_textdomain('wplnst', false, basename(WPLNST_PATH).'/'.(empty($lang_dir)? 'languages' : $lang_dir));
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
|
118 |
+
}
|
core/register.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Register class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Register {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Plugin activation process
|
15 |
+
*/
|
16 |
+
public static function activation() {
|
17 |
+
|
18 |
+
// Check salt file
|
19 |
+
WPLNST_Core_Nonce::check_salt_file();
|
20 |
+
|
21 |
+
// Load scheme library
|
22 |
+
wplnst_require('core', 'scheme');
|
23 |
+
|
24 |
+
// Check plugins tables
|
25 |
+
if (false !== ($tables = WPLNST_Core_Scheme::check_tables()))
|
26 |
+
WPLNST_Core_Scheme::create_tables($tables);
|
27 |
+
|
28 |
+
// Check scheme upgrade
|
29 |
+
WPLNST_Core_Scheme::upgrade();
|
30 |
+
}
|
31 |
+
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Plugin deactivation process
|
36 |
+
*/
|
37 |
+
public static function deactivation() {
|
38 |
+
WPLNST_Core_Settings::delete_crawler_options();
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Uninstall plugin data
|
45 |
+
*/
|
46 |
+
public static function uninstall() {
|
47 |
+
|
48 |
+
// Uninstall info first
|
49 |
+
if (!wplnst_get_bsetting('uninstall_data'))
|
50 |
+
return;
|
51 |
+
|
52 |
+
// Remove salt file
|
53 |
+
WPLNST_Core_Nonce::remove_salt_file();
|
54 |
+
|
55 |
+
// Remove user meta
|
56 |
+
$user_id = get_current_user_id();
|
57 |
+
delete_user_meta($user_id, 'wplnst_advanced_search');
|
58 |
+
delete_user_meta($user_id, 'wplnst_scans_per_page');
|
59 |
+
delete_user_meta($user_id, 'wplnst_scan_results_per_page');
|
60 |
+
|
61 |
+
// Remove plugin options
|
62 |
+
WPLNST_Core_Settings::delete_all_options();
|
63 |
+
|
64 |
+
// Remove scheme tables
|
65 |
+
wplnst_require('core', 'scheme');
|
66 |
+
WPLNST_Core_Scheme::drop_tables();
|
67 |
+
}
|
68 |
+
|
69 |
+
|
70 |
+
|
71 |
+
}
|
core/requests/class-json.php
ADDED
@@ -0,0 +1,960 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! class_exists( 'Services_JSON' ) ) :
|
3 |
+
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
4 |
+
/**
|
5 |
+
* Converts to and from JSON format.
|
6 |
+
*
|
7 |
+
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
8 |
+
* format. It is easy for humans to read and write. It is easy for machines
|
9 |
+
* to parse and generate. It is based on a subset of the JavaScript
|
10 |
+
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
11 |
+
* This feature can also be found in Python. JSON is a text format that is
|
12 |
+
* completely language independent but uses conventions that are familiar
|
13 |
+
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
14 |
+
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
15 |
+
* ideal data-interchange language.
|
16 |
+
*
|
17 |
+
* This package provides a simple encoder and decoder for JSON notation. It
|
18 |
+
* is intended for use with client-side Javascript applications that make
|
19 |
+
* use of HTTPRequest to perform server communication functions - data can
|
20 |
+
* be encoded into JSON notation for use in a client-side javascript, or
|
21 |
+
* decoded from incoming Javascript requests. JSON format is native to
|
22 |
+
* Javascript, and can be directly eval()'ed with no further parsing
|
23 |
+
* overhead
|
24 |
+
*
|
25 |
+
* All strings should be in ASCII or UTF-8 format!
|
26 |
+
*
|
27 |
+
* LICENSE: Redistribution and use in source and binary forms, with or
|
28 |
+
* without modification, are permitted provided that the following
|
29 |
+
* conditions are met: Redistributions of source code must retain the
|
30 |
+
* above copyright notice, this list of conditions and the following
|
31 |
+
* disclaimer. Redistributions in binary form must reproduce the above
|
32 |
+
* copyright notice, this list of conditions and the following disclaimer
|
33 |
+
* in the documentation and/or other materials provided with the
|
34 |
+
* distribution.
|
35 |
+
*
|
36 |
+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
37 |
+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
38 |
+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
39 |
+
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
40 |
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
41 |
+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
42 |
+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
43 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
44 |
+
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
45 |
+
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
46 |
+
* DAMAGE.
|
47 |
+
*
|
48 |
+
* @category
|
49 |
+
* @package Services_JSON
|
50 |
+
* @author Michal Migurski <mike-json@teczno.com>
|
51 |
+
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
52 |
+
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
53 |
+
* @copyright 2005 Michal Migurski
|
54 |
+
* @version CVS: $Id: JSON.php 305040 2010-11-02 23:19:03Z alan_k $
|
55 |
+
* @license http://www.opensource.org/licenses/bsd-license.php
|
56 |
+
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
57 |
+
*/
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
61 |
+
*/
|
62 |
+
define('SERVICES_JSON_SLICE', 1);
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
66 |
+
*/
|
67 |
+
define('SERVICES_JSON_IN_STR', 2);
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
71 |
+
*/
|
72 |
+
define('SERVICES_JSON_IN_ARR', 3);
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
76 |
+
*/
|
77 |
+
define('SERVICES_JSON_IN_OBJ', 4);
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
81 |
+
*/
|
82 |
+
define('SERVICES_JSON_IN_CMT', 5);
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Behavior switch for Services_JSON::decode()
|
86 |
+
*/
|
87 |
+
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Behavior switch for Services_JSON::decode()
|
91 |
+
*/
|
92 |
+
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Behavior switch for Services_JSON::decode()
|
96 |
+
*/
|
97 |
+
define('SERVICES_JSON_USE_TO_JSON', 64);
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Converts to and from JSON format.
|
101 |
+
*
|
102 |
+
* Brief example of use:
|
103 |
+
*
|
104 |
+
* <code>
|
105 |
+
* // create a new instance of Services_JSON
|
106 |
+
* $json = new Services_JSON();
|
107 |
+
*
|
108 |
+
* // convert a complexe value to JSON notation, and send it to the browser
|
109 |
+
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
110 |
+
* $output = $json->encode($value);
|
111 |
+
*
|
112 |
+
* print($output);
|
113 |
+
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
|
114 |
+
*
|
115 |
+
* // accept incoming POST data, assumed to be in JSON notation
|
116 |
+
* $input = file_get_contents('php://input', 1000000);
|
117 |
+
* $value = $json->decode($input);
|
118 |
+
* </code>
|
119 |
+
*/
|
120 |
+
class Services_JSON
|
121 |
+
{
|
122 |
+
/**
|
123 |
+
* constructs a new JSON instance
|
124 |
+
*
|
125 |
+
* @param int $use object behavior flags; combine with boolean-OR
|
126 |
+
*
|
127 |
+
* possible values:
|
128 |
+
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
|
129 |
+
* "{...}" syntax creates associative arrays
|
130 |
+
* instead of objects in decode().
|
131 |
+
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
|
132 |
+
* Values which can't be encoded (e.g. resources)
|
133 |
+
* appear as NULL instead of throwing errors.
|
134 |
+
* By default, a deeply-nested resource will
|
135 |
+
* bubble up with an error, so all return values
|
136 |
+
* from encode() should be checked with isError()
|
137 |
+
* - SERVICES_JSON_USE_TO_JSON: call toJSON when serializing objects
|
138 |
+
* It serializes the return value from the toJSON call rather
|
139 |
+
* than the object itself, toJSON can return associative arrays,
|
140 |
+
* strings or numbers, if you return an object, make sure it does
|
141 |
+
* not have a toJSON method, otherwise an error will occur.
|
142 |
+
*/
|
143 |
+
function __construct( $use = 0 )
|
144 |
+
{
|
145 |
+
$this->use = $use;
|
146 |
+
$this->_mb_strlen = function_exists('mb_strlen');
|
147 |
+
$this->_mb_convert_encoding = function_exists('mb_convert_encoding');
|
148 |
+
$this->_mb_substr = function_exists('mb_substr');
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* PHP4 constructor.
|
153 |
+
*/
|
154 |
+
public function Services_JSON( $use = 0 ) {
|
155 |
+
self::__construct( $use );
|
156 |
+
}
|
157 |
+
// private - cache the mbstring lookup results..
|
158 |
+
var $_mb_strlen = false;
|
159 |
+
var $_mb_substr = false;
|
160 |
+
var $_mb_convert_encoding = false;
|
161 |
+
|
162 |
+
/**
|
163 |
+
* convert a string from one UTF-16 char to one UTF-8 char
|
164 |
+
*
|
165 |
+
* Normally should be handled by mb_convert_encoding, but
|
166 |
+
* provides a slower PHP-only method for installations
|
167 |
+
* that lack the multibye string extension.
|
168 |
+
*
|
169 |
+
* @param string $utf16 UTF-16 character
|
170 |
+
* @return string UTF-8 character
|
171 |
+
* @access private
|
172 |
+
*/
|
173 |
+
function utf162utf8($utf16)
|
174 |
+
{
|
175 |
+
// oh please oh please oh please oh please oh please
|
176 |
+
if($this->_mb_convert_encoding) {
|
177 |
+
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
178 |
+
}
|
179 |
+
|
180 |
+
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
181 |
+
|
182 |
+
switch(true) {
|
183 |
+
case ((0x7F & $bytes) == $bytes):
|
184 |
+
// this case should never be reached, because we are in ASCII range
|
185 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
186 |
+
return chr(0x7F & $bytes);
|
187 |
+
|
188 |
+
case (0x07FF & $bytes) == $bytes:
|
189 |
+
// return a 2-byte UTF-8 character
|
190 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
191 |
+
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
192 |
+
. chr(0x80 | ($bytes & 0x3F));
|
193 |
+
|
194 |
+
case (0xFFFF & $bytes) == $bytes:
|
195 |
+
// return a 3-byte UTF-8 character
|
196 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
197 |
+
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
198 |
+
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
199 |
+
. chr(0x80 | ($bytes & 0x3F));
|
200 |
+
}
|
201 |
+
|
202 |
+
// ignoring UTF-32 for now, sorry
|
203 |
+
return '';
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* convert a string from one UTF-8 char to one UTF-16 char
|
208 |
+
*
|
209 |
+
* Normally should be handled by mb_convert_encoding, but
|
210 |
+
* provides a slower PHP-only method for installations
|
211 |
+
* that lack the multibye string extension.
|
212 |
+
*
|
213 |
+
* @param string $utf8 UTF-8 character
|
214 |
+
* @return string UTF-16 character
|
215 |
+
* @access private
|
216 |
+
*/
|
217 |
+
function utf82utf16($utf8)
|
218 |
+
{
|
219 |
+
// oh please oh please oh please oh please oh please
|
220 |
+
if($this->_mb_convert_encoding) {
|
221 |
+
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
222 |
+
}
|
223 |
+
|
224 |
+
switch($this->strlen8($utf8)) {
|
225 |
+
case 1:
|
226 |
+
// this case should never be reached, because we are in ASCII range
|
227 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
228 |
+
return $utf8;
|
229 |
+
|
230 |
+
case 2:
|
231 |
+
// return a UTF-16 character from a 2-byte UTF-8 char
|
232 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
233 |
+
return chr(0x07 & (ord($utf8{0}) >> 2))
|
234 |
+
. chr((0xC0 & (ord($utf8{0}) << 6))
|
235 |
+
| (0x3F & ord($utf8{1})));
|
236 |
+
|
237 |
+
case 3:
|
238 |
+
// return a UTF-16 character from a 3-byte UTF-8 char
|
239 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
240 |
+
return chr((0xF0 & (ord($utf8{0}) << 4))
|
241 |
+
| (0x0F & (ord($utf8{1}) >> 2)))
|
242 |
+
. chr((0xC0 & (ord($utf8{1}) << 6))
|
243 |
+
| (0x7F & ord($utf8{2})));
|
244 |
+
}
|
245 |
+
|
246 |
+
// ignoring UTF-32 for now, sorry
|
247 |
+
return '';
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* encodes an arbitrary variable into JSON format (and sends JSON Header)
|
252 |
+
*
|
253 |
+
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
254 |
+
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
255 |
+
* if var is a strng, note that encode() always expects it
|
256 |
+
* to be in ASCII or UTF-8 format!
|
257 |
+
*
|
258 |
+
* @return mixed JSON string representation of input var or an error if a problem occurs
|
259 |
+
* @access public
|
260 |
+
*/
|
261 |
+
function encode($var)
|
262 |
+
{
|
263 |
+
header('Content-type: application/json');
|
264 |
+
return $this->encodeUnsafe($var);
|
265 |
+
}
|
266 |
+
/**
|
267 |
+
* encodes an arbitrary variable into JSON format without JSON Header - warning - may allow XSS!!!!)
|
268 |
+
*
|
269 |
+
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
270 |
+
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
271 |
+
* if var is a strng, note that encode() always expects it
|
272 |
+
* to be in ASCII or UTF-8 format!
|
273 |
+
*
|
274 |
+
* @return mixed JSON string representation of input var or an error if a problem occurs
|
275 |
+
* @access public
|
276 |
+
*/
|
277 |
+
function encodeUnsafe($var)
|
278 |
+
{
|
279 |
+
// see bug #16908 - regarding numeric locale printing
|
280 |
+
$lc = setlocale(LC_NUMERIC, 0);
|
281 |
+
setlocale(LC_NUMERIC, 'C');
|
282 |
+
$ret = $this->_encode($var);
|
283 |
+
setlocale(LC_NUMERIC, $lc);
|
284 |
+
return $ret;
|
285 |
+
|
286 |
+
}
|
287 |
+
/**
|
288 |
+
* PRIVATE CODE that does the work of encodes an arbitrary variable into JSON format
|
289 |
+
*
|
290 |
+
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
291 |
+
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
292 |
+
* if var is a strng, note that encode() always expects it
|
293 |
+
* to be in ASCII or UTF-8 format!
|
294 |
+
*
|
295 |
+
* @return mixed JSON string representation of input var or an error if a problem occurs
|
296 |
+
* @access public
|
297 |
+
*/
|
298 |
+
function _encode($var)
|
299 |
+
{
|
300 |
+
|
301 |
+
switch (gettype($var)) {
|
302 |
+
case 'boolean':
|
303 |
+
return $var ? 'true' : 'false';
|
304 |
+
|
305 |
+
case 'NULL':
|
306 |
+
return 'null';
|
307 |
+
|
308 |
+
case 'integer':
|
309 |
+
return (int) $var;
|
310 |
+
|
311 |
+
case 'double':
|
312 |
+
case 'float':
|
313 |
+
return (float) $var;
|
314 |
+
|
315 |
+
case 'string':
|
316 |
+
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
317 |
+
$ascii = '';
|
318 |
+
$strlen_var = $this->strlen8($var);
|
319 |
+
|
320 |
+
/*
|
321 |
+
* Iterate over every character in the string,
|
322 |
+
* escaping with a slash or encoding to UTF-8 where necessary
|
323 |
+
*/
|
324 |
+
for ($c = 0; $c < $strlen_var; ++$c) {
|
325 |
+
|
326 |
+
$ord_var_c = ord($var{$c});
|
327 |
+
|
328 |
+
switch (true) {
|
329 |
+
case $ord_var_c == 0x08:
|
330 |
+
$ascii .= '\b';
|
331 |
+
break;
|
332 |
+
case $ord_var_c == 0x09:
|
333 |
+
$ascii .= '\t';
|
334 |
+
break;
|
335 |
+
case $ord_var_c == 0x0A:
|
336 |
+
$ascii .= '\n';
|
337 |
+
break;
|
338 |
+
case $ord_var_c == 0x0C:
|
339 |
+
$ascii .= '\f';
|
340 |
+
break;
|
341 |
+
case $ord_var_c == 0x0D:
|
342 |
+
$ascii .= '\r';
|
343 |
+
break;
|
344 |
+
|
345 |
+
case $ord_var_c == 0x22:
|
346 |
+
case $ord_var_c == 0x2F:
|
347 |
+
case $ord_var_c == 0x5C:
|
348 |
+
// double quote, slash, slosh
|
349 |
+
$ascii .= '\\'.$var{$c};
|
350 |
+
break;
|
351 |
+
|
352 |
+
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
353 |
+
// characters U-00000000 - U-0000007F (same as ASCII)
|
354 |
+
$ascii .= $var{$c};
|
355 |
+
break;
|
356 |
+
|
357 |
+
case (($ord_var_c & 0xE0) == 0xC0):
|
358 |
+
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
359 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
360 |
+
if ($c+1 >= $strlen_var) {
|
361 |
+
$c += 1;
|
362 |
+
$ascii .= '?';
|
363 |
+
break;
|
364 |
+
}
|
365 |
+
|
366 |
+
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
367 |
+
$c += 1;
|
368 |
+
$utf16 = $this->utf82utf16($char);
|
369 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
370 |
+
break;
|
371 |
+
|
372 |
+
case (($ord_var_c & 0xF0) == 0xE0):
|
373 |
+
if ($c+2 >= $strlen_var) {
|
374 |
+
$c += 2;
|
375 |
+
$ascii .= '?';
|
376 |
+
break;
|
377 |
+
}
|
378 |
+
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
379 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
380 |
+
$char = pack('C*', $ord_var_c,
|
381 |
+
@ord($var{$c + 1}),
|
382 |
+
@ord($var{$c + 2}));
|
383 |
+
$c += 2;
|
384 |
+
$utf16 = $this->utf82utf16($char);
|
385 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
386 |
+
break;
|
387 |
+
|
388 |
+
case (($ord_var_c & 0xF8) == 0xF0):
|
389 |
+
if ($c+3 >= $strlen_var) {
|
390 |
+
$c += 3;
|
391 |
+
$ascii .= '?';
|
392 |
+
break;
|
393 |
+
}
|
394 |
+
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
395 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
396 |
+
$char = pack('C*', $ord_var_c,
|
397 |
+
ord($var{$c + 1}),
|
398 |
+
ord($var{$c + 2}),
|
399 |
+
ord($var{$c + 3}));
|
400 |
+
$c += 3;
|
401 |
+
$utf16 = $this->utf82utf16($char);
|
402 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
403 |
+
break;
|
404 |
+
|
405 |
+
case (($ord_var_c & 0xFC) == 0xF8):
|
406 |
+
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
407 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
408 |
+
if ($c+4 >= $strlen_var) {
|
409 |
+
$c += 4;
|
410 |
+
$ascii .= '?';
|
411 |
+
break;
|
412 |
+
}
|
413 |
+
$char = pack('C*', $ord_var_c,
|
414 |
+
ord($var{$c + 1}),
|
415 |
+
ord($var{$c + 2}),
|
416 |
+
ord($var{$c + 3}),
|
417 |
+
ord($var{$c + 4}));
|
418 |
+
$c += 4;
|
419 |
+
$utf16 = $this->utf82utf16($char);
|
420 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
421 |
+
break;
|
422 |
+
|
423 |
+
case (($ord_var_c & 0xFE) == 0xFC):
|
424 |
+
if ($c+5 >= $strlen_var) {
|
425 |
+
$c += 5;
|
426 |
+
$ascii .= '?';
|
427 |
+
break;
|
428 |
+
}
|
429 |
+
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
430 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
431 |
+
$char = pack('C*', $ord_var_c,
|
432 |
+
ord($var{$c + 1}),
|
433 |
+
ord($var{$c + 2}),
|
434 |
+
ord($var{$c + 3}),
|
435 |
+
ord($var{$c + 4}),
|
436 |
+
ord($var{$c + 5}));
|
437 |
+
$c += 5;
|
438 |
+
$utf16 = $this->utf82utf16($char);
|
439 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
440 |
+
break;
|
441 |
+
}
|
442 |
+
}
|
443 |
+
return '"'.$ascii.'"';
|
444 |
+
|
445 |
+
case 'array':
|
446 |
+
/*
|
447 |
+
* As per JSON spec if any array key is not an integer
|
448 |
+
* we must treat the the whole array as an object. We
|
449 |
+
* also try to catch a sparsely populated associative
|
450 |
+
* array with numeric keys here because some JS engines
|
451 |
+
* will create an array with empty indexes up to
|
452 |
+
* max_index which can cause memory issues and because
|
453 |
+
* the keys, which may be relevant, will be remapped
|
454 |
+
* otherwise.
|
455 |
+
*
|
456 |
+
* As per the ECMA and JSON specification an object may
|
457 |
+
* have any string as a property. Unfortunately due to
|
458 |
+
* a hole in the ECMA specification if the key is a
|
459 |
+
* ECMA reserved word or starts with a digit the
|
460 |
+
* parameter is only accessible using ECMAScript's
|
461 |
+
* bracket notation.
|
462 |
+
*/
|
463 |
+
|
464 |
+
// treat as a JSON object
|
465 |
+
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
466 |
+
$properties = array_map(array($this, 'name_value'),
|
467 |
+
array_keys($var),
|
468 |
+
array_values($var));
|
469 |
+
|
470 |
+
foreach($properties as $property) {
|
471 |
+
if(Services_JSON::isError($property)) {
|
472 |
+
return $property;
|
473 |
+
}
|
474 |
+
}
|
475 |
+
|
476 |
+
return '{' . join(',', $properties) . '}';
|
477 |
+
}
|
478 |
+
|
479 |
+
// treat it like a regular array
|
480 |
+
$elements = array_map(array($this, '_encode'), $var);
|
481 |
+
|
482 |
+
foreach($elements as $element) {
|
483 |
+
if(Services_JSON::isError($element)) {
|
484 |
+
return $element;
|
485 |
+
}
|
486 |
+
}
|
487 |
+
|
488 |
+
return '[' . join(',', $elements) . ']';
|
489 |
+
|
490 |
+
case 'object':
|
491 |
+
|
492 |
+
// support toJSON methods.
|
493 |
+
if (($this->use & SERVICES_JSON_USE_TO_JSON) && method_exists($var, 'toJSON')) {
|
494 |
+
// this may end up allowing unlimited recursion
|
495 |
+
// so we check the return value to make sure it's not got the same method.
|
496 |
+
$recode = $var->toJSON();
|
497 |
+
|
498 |
+
if (method_exists($recode, 'toJSON')) {
|
499 |
+
|
500 |
+
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
501 |
+
? 'null'
|
502 |
+
: new Services_JSON_Error(get_class($var).
|
503 |
+
" toJSON returned an object with a toJSON method.");
|
504 |
+
|
505 |
+
}
|
506 |
+
|
507 |
+
return $this->_encode( $recode );
|
508 |
+
}
|
509 |
+
|
510 |
+
$vars = get_object_vars($var);
|
511 |
+
|
512 |
+
$properties = array_map(array($this, 'name_value'),
|
513 |
+
array_keys($vars),
|
514 |
+
array_values($vars));
|
515 |
+
|
516 |
+
foreach($properties as $property) {
|
517 |
+
if(Services_JSON::isError($property)) {
|
518 |
+
return $property;
|
519 |
+
}
|
520 |
+
}
|
521 |
+
|
522 |
+
return '{' . join(',', $properties) . '}';
|
523 |
+
|
524 |
+
default:
|
525 |
+
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
526 |
+
? 'null'
|
527 |
+
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
528 |
+
}
|
529 |
+
}
|
530 |
+
|
531 |
+
/**
|
532 |
+
* array-walking function for use in generating JSON-formatted name-value pairs
|
533 |
+
*
|
534 |
+
* @param string $name name of key to use
|
535 |
+
* @param mixed $value reference to an array element to be encoded
|
536 |
+
*
|
537 |
+
* @return string JSON-formatted name-value pair, like '"name":value'
|
538 |
+
* @access private
|
539 |
+
*/
|
540 |
+
function name_value($name, $value)
|
541 |
+
{
|
542 |
+
$encoded_value = $this->_encode($value);
|
543 |
+
|
544 |
+
if(Services_JSON::isError($encoded_value)) {
|
545 |
+
return $encoded_value;
|
546 |
+
}
|
547 |
+
|
548 |
+
return $this->_encode(strval($name)) . ':' . $encoded_value;
|
549 |
+
}
|
550 |
+
|
551 |
+
/**
|
552 |
+
* reduce a string by removing leading and trailing comments and whitespace
|
553 |
+
*
|
554 |
+
* @param $str string string value to strip of comments and whitespace
|
555 |
+
*
|
556 |
+
* @return string string value stripped of comments and whitespace
|
557 |
+
* @access private
|
558 |
+
*/
|
559 |
+
function reduce_string($str)
|
560 |
+
{
|
561 |
+
$str = preg_replace(array(
|
562 |
+
|
563 |
+
// eliminate single line comments in '// ...' form
|
564 |
+
'#^\s*//(.+)$#m',
|
565 |
+
|
566 |
+
// eliminate multi-line comments in '/* ... */' form, at start of string
|
567 |
+
'#^\s*/\*(.+)\*/#Us',
|
568 |
+
|
569 |
+
// eliminate multi-line comments in '/* ... */' form, at end of string
|
570 |
+
'#/\*(.+)\*/\s*$#Us'
|
571 |
+
|
572 |
+
), '', $str);
|
573 |
+
|
574 |
+
// eliminate extraneous space
|
575 |
+
return trim($str);
|
576 |
+
}
|
577 |
+
|
578 |
+
/**
|
579 |
+
* decodes a JSON string into appropriate variable
|
580 |
+
*
|
581 |
+
* @param string $str JSON-formatted string
|
582 |
+
*
|
583 |
+
* @return mixed number, boolean, string, array, or object
|
584 |
+
* corresponding to given JSON input string.
|
585 |
+
* See argument 1 to Services_JSON() above for object-output behavior.
|
586 |
+
* Note that decode() always returns strings
|
587 |
+
* in ASCII or UTF-8 format!
|
588 |
+
* @access public
|
589 |
+
*/
|
590 |
+
function decode($str)
|
591 |
+
{
|
592 |
+
$str = $this->reduce_string($str);
|
593 |
+
|
594 |
+
switch (strtolower($str)) {
|
595 |
+
case 'true':
|
596 |
+
return true;
|
597 |
+
|
598 |
+
case 'false':
|
599 |
+
return false;
|
600 |
+
|
601 |
+
case 'null':
|
602 |
+
return null;
|
603 |
+
|
604 |
+
default:
|
605 |
+
$m = array();
|
606 |
+
|
607 |
+
if (is_numeric($str)) {
|
608 |
+
// Lookie-loo, it's a number
|
609 |
+
|
610 |
+
// This would work on its own, but I'm trying to be
|
611 |
+
// good about returning integers where appropriate:
|
612 |
+
// return (float)$str;
|
613 |
+
|
614 |
+
// Return float or int, as appropriate
|
615 |
+
return ((float)$str == (integer)$str)
|
616 |
+
? (integer)$str
|
617 |
+
: (float)$str;
|
618 |
+
|
619 |
+
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
620 |
+
// STRINGS RETURNED IN UTF-8 FORMAT
|
621 |
+
$delim = $this->substr8($str, 0, 1);
|
622 |
+
$chrs = $this->substr8($str, 1, -1);
|
623 |
+
$utf8 = '';
|
624 |
+
$strlen_chrs = $this->strlen8($chrs);
|
625 |
+
|
626 |
+
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
627 |
+
|
628 |
+
$substr_chrs_c_2 = $this->substr8($chrs, $c, 2);
|
629 |
+
$ord_chrs_c = ord($chrs{$c});
|
630 |
+
|
631 |
+
switch (true) {
|
632 |
+
case $substr_chrs_c_2 == '\b':
|
633 |
+
$utf8 .= chr(0x08);
|
634 |
+
++$c;
|
635 |
+
break;
|
636 |
+
case $substr_chrs_c_2 == '\t':
|
637 |
+
$utf8 .= chr(0x09);
|
638 |
+
++$c;
|
639 |
+
break;
|
640 |
+
case $substr_chrs_c_2 == '\n':
|
641 |
+
$utf8 .= chr(0x0A);
|
642 |
+
++$c;
|
643 |
+
break;
|
644 |
+
case $substr_chrs_c_2 == '\f':
|
645 |
+
$utf8 .= chr(0x0C);
|
646 |
+
++$c;
|
647 |
+
break;
|
648 |
+
case $substr_chrs_c_2 == '\r':
|
649 |
+
$utf8 .= chr(0x0D);
|
650 |
+
++$c;
|
651 |
+
break;
|
652 |
+
|
653 |
+
case $substr_chrs_c_2 == '\\"':
|
654 |
+
case $substr_chrs_c_2 == '\\\'':
|
655 |
+
case $substr_chrs_c_2 == '\\\\':
|
656 |
+
case $substr_chrs_c_2 == '\\/':
|
657 |
+
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
658 |
+
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
659 |
+
$utf8 .= $chrs{++$c};
|
660 |
+
}
|
661 |
+
break;
|
662 |
+
|
663 |
+
case preg_match('/\\\u[0-9A-F]{4}/i', $this->substr8($chrs, $c, 6)):
|
664 |
+
// single, escaped unicode character
|
665 |
+
$utf16 = chr(hexdec($this->substr8($chrs, ($c + 2), 2)))
|
666 |
+
. chr(hexdec($this->substr8($chrs, ($c + 4), 2)));
|
667 |
+
$utf8 .= $this->utf162utf8($utf16);
|
668 |
+
$c += 5;
|
669 |
+
break;
|
670 |
+
|
671 |
+
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
672 |
+
$utf8 .= $chrs{$c};
|
673 |
+
break;
|
674 |
+
|
675 |
+
case ($ord_chrs_c & 0xE0) == 0xC0:
|
676 |
+
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
677 |
+
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
678 |
+
$utf8 .= $this->substr8($chrs, $c, 2);
|
679 |
+
++$c;
|
680 |
+
break;
|
681 |
+
|
682 |
+
case ($ord_chrs_c & 0xF0) == 0xE0:
|
683 |
+
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
684 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
685 |
+
$utf8 .= $this->substr8($chrs, $c, 3);
|
686 |
+
$c += 2;
|
687 |
+
break;
|
688 |
+
|
689 |
+
case ($ord_chrs_c & 0xF8) == 0xF0:
|
690 |
+
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
691 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
692 |
+
$utf8 .= $this->substr8($chrs, $c, 4);
|
693 |
+
$c += 3;
|
694 |
+
break;
|
695 |
+
|
696 |
+
case ($ord_chrs_c & 0xFC) == 0xF8:
|
697 |
+
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
698 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
699 |
+
$utf8 .= $this->substr8($chrs, $c, 5);
|
700 |
+
$c += 4;
|
701 |
+
break;
|
702 |
+
|
703 |
+
case ($ord_chrs_c & 0xFE) == 0xFC:
|
704 |
+
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
705 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
706 |
+
$utf8 .= $this->substr8($chrs, $c, 6);
|
707 |
+
$c += 5;
|
708 |
+
break;
|
709 |
+
|
710 |
+
}
|
711 |
+
|
712 |
+
}
|
713 |
+
|
714 |
+
return $utf8;
|
715 |
+
|
716 |
+
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
717 |
+
// array, or object notation
|
718 |
+
|
719 |
+
if ($str{0} == '[') {
|
720 |
+
$stk = array(SERVICES_JSON_IN_ARR);
|
721 |
+
$arr = array();
|
722 |
+
} else {
|
723 |
+
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
724 |
+
$stk = array(SERVICES_JSON_IN_OBJ);
|
725 |
+
$obj = array();
|
726 |
+
} else {
|
727 |
+
$stk = array(SERVICES_JSON_IN_OBJ);
|
728 |
+
$obj = new stdClass();
|
729 |
+
}
|
730 |
+
}
|
731 |
+
|
732 |
+
array_push($stk, array('what' => SERVICES_JSON_SLICE,
|
733 |
+
'where' => 0,
|
734 |
+
'delim' => false));
|
735 |
+
|
736 |
+
$chrs = $this->substr8($str, 1, -1);
|
737 |
+
$chrs = $this->reduce_string($chrs);
|
738 |
+
|
739 |
+
if ($chrs == '') {
|
740 |
+
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
741 |
+
return $arr;
|
742 |
+
|
743 |
+
} else {
|
744 |
+
return $obj;
|
745 |
+
|
746 |
+
}
|
747 |
+
}
|
748 |
+
|
749 |
+
//print("\nparsing {$chrs}\n");
|
750 |
+
|
751 |
+
$strlen_chrs = $this->strlen8($chrs);
|
752 |
+
|
753 |
+
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
754 |
+
|
755 |
+
$top = end($stk);
|
756 |
+
$substr_chrs_c_2 = $this->substr8($chrs, $c, 2);
|
757 |
+
|
758 |
+
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
759 |
+
// found a comma that is not inside a string, array, etc.,
|
760 |
+
// OR we've reached the end of the character list
|
761 |
+
$slice = $this->substr8($chrs, $top['where'], ($c - $top['where']));
|
762 |
+
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
763 |
+
//print("Found split at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
764 |
+
|
765 |
+
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
766 |
+
// we are in an array, so just push an element onto the stack
|
767 |
+
array_push($arr, $this->decode($slice));
|
768 |
+
|
769 |
+
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
770 |
+
// we are in an object, so figure
|
771 |
+
// out the property name and set an
|
772 |
+
// element in an associative array,
|
773 |
+
// for now
|
774 |
+
$parts = array();
|
775 |
+
|
776 |
+
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:/Uis', $slice, $parts)) {
|
777 |
+
// "name":value pair
|
778 |
+
$key = $this->decode($parts[1]);
|
779 |
+
$val = $this->decode(trim(substr($slice, strlen($parts[0])), ", \t\n\r\0\x0B"));
|
780 |
+
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
781 |
+
$obj[$key] = $val;
|
782 |
+
} else {
|
783 |
+
$obj->$key = $val;
|
784 |
+
}
|
785 |
+
} elseif (preg_match('/^\s*(\w+)\s*:/Uis', $slice, $parts)) {
|
786 |
+
// name:value pair, where name is unquoted
|
787 |
+
$key = $parts[1];
|
788 |
+
$val = $this->decode(trim(substr($slice, strlen($parts[0])), ", \t\n\r\0\x0B"));
|
789 |
+
|
790 |
+
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
791 |
+
$obj[$key] = $val;
|
792 |
+
} else {
|
793 |
+
$obj->$key = $val;
|
794 |
+
}
|
795 |
+
}
|
796 |
+
|
797 |
+
}
|
798 |
+
|
799 |
+
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
|
800 |
+
// found a quote, and we are not inside a string
|
801 |
+
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
|
802 |
+
//print("Found start of string at {$c}\n");
|
803 |
+
|
804 |
+
} elseif (($chrs{$c} == $top['delim']) &&
|
805 |
+
($top['what'] == SERVICES_JSON_IN_STR) &&
|
806 |
+
(($this->strlen8($this->substr8($chrs, 0, $c)) - $this->strlen8(rtrim($this->substr8($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
807 |
+
// found a quote, we're in a string, and it's not escaped
|
808 |
+
// we know that it's not escaped becase there is _not_ an
|
809 |
+
// odd number of backslashes at the end of the string so far
|
810 |
+
array_pop($stk);
|
811 |
+
//print("Found end of string at {$c}: ".$this->substr8($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
812 |
+
|
813 |
+
} elseif (($chrs{$c} == '[') &&
|
814 |
+
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
815 |
+
// found a left-bracket, and we are in an array, object, or slice
|
816 |
+
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
|
817 |
+
//print("Found start of array at {$c}\n");
|
818 |
+
|
819 |
+
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
820 |
+
// found a right-bracket, and we're in an array
|
821 |
+
array_pop($stk);
|
822 |
+
//print("Found end of array at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
823 |
+
|
824 |
+
} elseif (($chrs{$c} == '{') &&
|
825 |
+
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
826 |
+
// found a left-brace, and we are in an array, object, or slice
|
827 |
+
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
|
828 |
+
//print("Found start of object at {$c}\n");
|
829 |
+
|
830 |
+
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
831 |
+
// found a right-brace, and we're in an object
|
832 |
+
array_pop($stk);
|
833 |
+
//print("Found end of object at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
834 |
+
|
835 |
+
} elseif (($substr_chrs_c_2 == '/*') &&
|
836 |
+
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
837 |
+
// found a comment start, and we are in an array, object, or slice
|
838 |
+
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
|
839 |
+
$c++;
|
840 |
+
//print("Found start of comment at {$c}\n");
|
841 |
+
|
842 |
+
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
|
843 |
+
// found a comment end, and we're in one now
|
844 |
+
array_pop($stk);
|
845 |
+
$c++;
|
846 |
+
|
847 |
+
for ($i = $top['where']; $i <= $c; ++$i)
|
848 |
+
$chrs = substr_replace($chrs, ' ', $i, 1);
|
849 |
+
|
850 |
+
//print("Found end of comment at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
851 |
+
|
852 |
+
}
|
853 |
+
|
854 |
+
}
|
855 |
+
|
856 |
+
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
857 |
+
return $arr;
|
858 |
+
|
859 |
+
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
860 |
+
return $obj;
|
861 |
+
|
862 |
+
}
|
863 |
+
|
864 |
+
}
|
865 |
+
}
|
866 |
+
}
|
867 |
+
|
868 |
+
/**
|
869 |
+
* @todo Ultimately, this should just call PEAR::isError()
|
870 |
+
*/
|
871 |
+
function isError($data, $code = null)
|
872 |
+
{
|
873 |
+
if (class_exists('pear')) {
|
874 |
+
return PEAR::isError($data, $code);
|
875 |
+
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
876 |
+
is_subclass_of($data, 'services_json_error'))) {
|
877 |
+
return true;
|
878 |
+
}
|
879 |
+
|
880 |
+
return false;
|
881 |
+
}
|
882 |
+
|
883 |
+
/**
|
884 |
+
* Calculates length of string in bytes
|
885 |
+
* @param string
|
886 |
+
* @return integer length
|
887 |
+
*/
|
888 |
+
function strlen8( $str )
|
889 |
+
{
|
890 |
+
if ( $this->_mb_strlen ) {
|
891 |
+
return mb_strlen( $str, "8bit" );
|
892 |
+
}
|
893 |
+
return strlen( $str );
|
894 |
+
}
|
895 |
+
|
896 |
+
/**
|
897 |
+
* Returns part of a string, interpreting $start and $length as number of bytes.
|
898 |
+
* @param string
|
899 |
+
* @param integer start
|
900 |
+
* @param integer length
|
901 |
+
* @return integer length
|
902 |
+
*/
|
903 |
+
function substr8( $string, $start, $length=false )
|
904 |
+
{
|
905 |
+
if ( $length === false ) {
|
906 |
+
$length = $this->strlen8( $string ) - $start;
|
907 |
+
}
|
908 |
+
if ( $this->_mb_substr ) {
|
909 |
+
return mb_substr( $string, $start, $length, "8bit" );
|
910 |
+
}
|
911 |
+
return substr( $string, $start, $length );
|
912 |
+
}
|
913 |
+
|
914 |
+
}
|
915 |
+
|
916 |
+
if (class_exists('PEAR_Error')) {
|
917 |
+
|
918 |
+
class Services_JSON_Error extends PEAR_Error
|
919 |
+
{
|
920 |
+
function __construct($message = 'unknown error', $code = null,
|
921 |
+
$mode = null, $options = null, $userinfo = null)
|
922 |
+
{
|
923 |
+
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
924 |
+
}
|
925 |
+
|
926 |
+
public function Services_JSON_Error($message = 'unknown error', $code = null,
|
927 |
+
$mode = null, $options = null, $userinfo = null) {
|
928 |
+
self::__construct($message = 'unknown error', $code = null,
|
929 |
+
$mode = null, $options = null, $userinfo = null);
|
930 |
+
}
|
931 |
+
}
|
932 |
+
|
933 |
+
} else {
|
934 |
+
|
935 |
+
/**
|
936 |
+
* @todo Ultimately, this class shall be descended from PEAR_Error
|
937 |
+
*/
|
938 |
+
class Services_JSON_Error
|
939 |
+
{
|
940 |
+
/**
|
941 |
+
* PHP5 constructor.
|
942 |
+
*/
|
943 |
+
function __construct( $message = 'unknown error', $code = null,
|
944 |
+
$mode = null, $options = null, $userinfo = null )
|
945 |
+
{
|
946 |
+
|
947 |
+
}
|
948 |
+
|
949 |
+
/**
|
950 |
+
* PHP4 constructor.
|
951 |
+
*/
|
952 |
+
public function Services_JSON_Error( $message = 'unknown error', $code = null,
|
953 |
+
$mode = null, $options = null, $userinfo = null ) {
|
954 |
+
self::__construct( $message, $code, $mode, $options, $userinfo );
|
955 |
+
}
|
956 |
+
}
|
957 |
+
|
958 |
+
}
|
959 |
+
|
960 |
+
endif;
|
core/requests/http.php
ADDED
@@ -0,0 +1,417 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Check existing class to avoid conflicts
|
4 |
+
if (!class_exists('WPLNST_Core_HTTP_Request') && !function_exists('wplnst_http_read_stream')) :
|
5 |
+
|
6 |
+
/**
|
7 |
+
* WP Link Status Core HTTP request class
|
8 |
+
*
|
9 |
+
* @package WP Link Status
|
10 |
+
* @subpackage WP Link Status Core
|
11 |
+
*/
|
12 |
+
class WPLNST_Core_HTTP_Request {
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
// Initialization
|
17 |
+
// ---------------------------------------------------------------------------------------------------
|
18 |
+
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Start request process
|
23 |
+
*/
|
24 |
+
public static function start() {
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
/* Initialization */
|
29 |
+
|
30 |
+
// Default timezone
|
31 |
+
date_default_timezone_set('UTC');
|
32 |
+
|
33 |
+
// Check basic arguments
|
34 |
+
if (!empty($_GET) || empty($_POST) || empty($_POST['url']) || empty($_POST['url_id']) || empty($_POST['connect_timeout']) || empty($_POST['request_timeout']) || empty($_POST['max_download']) || empty($_POST['nonce']) || empty($_POST['hash']))
|
35 |
+
self::terminate();
|
36 |
+
|
37 |
+
// Check URL
|
38 |
+
$url = $_POST['url'];
|
39 |
+
if (empty($url) || (0 !== stripos($url, 'http://') && 0 !== stripos($url, 'https://') && 0 !== stripos($url, 'ftp://')))
|
40 |
+
self::terminate();
|
41 |
+
|
42 |
+
// Check URL id
|
43 |
+
$url_id = (int) $_POST['url_id'];
|
44 |
+
if (empty($url_id))
|
45 |
+
self::terminate();
|
46 |
+
|
47 |
+
// Check back URL
|
48 |
+
$back_url = empty($_POST['back_url'])? false : trim($_POST['back_url']);
|
49 |
+
if (!empty($back_url) && (0 !== stripos($back_url, 'http://') && 0 !== stripos($back_url, 'https://')))
|
50 |
+
self::terminate();
|
51 |
+
|
52 |
+
// Check connect timeout
|
53 |
+
$connect_timeout = (int) $_POST['connect_timeout'];
|
54 |
+
if (empty($connect_timeout))
|
55 |
+
self::terminate();
|
56 |
+
|
57 |
+
// Check request timeout
|
58 |
+
$request_timeout = (int) $_POST['request_timeout'];
|
59 |
+
if (empty($request_timeout))
|
60 |
+
self::terminate();
|
61 |
+
|
62 |
+
// Check max download
|
63 |
+
global $max_download, $max_download_done;
|
64 |
+
$max_download = (int) $_POST['max_download'];
|
65 |
+
if (empty($max_download))
|
66 |
+
self::terminate();
|
67 |
+
|
68 |
+
// Check only headers
|
69 |
+
global $only_headers, $only_headers_done;
|
70 |
+
$only_headers = (isset($_POST['only_headers']) && '1' == $_POST['only_headers']);
|
71 |
+
|
72 |
+
// Load nonce library
|
73 |
+
require(dirname(dirname(__FILE__)).'/nonce/nonce.php');
|
74 |
+
|
75 |
+
// Verify nonce for this URL hash
|
76 |
+
if (!WPLNST_Core_Nonce::verify_nonce($_POST['nonce'], $_POST['hash']))
|
77 |
+
self::terminate();
|
78 |
+
|
79 |
+
// Load cURL wrapper library
|
80 |
+
require(dirname(dirname(__FILE__)).'/curl.php');
|
81 |
+
|
82 |
+
// User Agent string
|
83 |
+
$user_agent = empty($_POST['user_agent'])? '' : $_POST['user_agent'];
|
84 |
+
|
85 |
+
|
86 |
+
|
87 |
+
/* URL HTTP status */
|
88 |
+
|
89 |
+
// No timeout
|
90 |
+
set_time_limit(0);
|
91 |
+
|
92 |
+
// Initialize globals
|
93 |
+
global $wplnst_http_response;
|
94 |
+
$wplnst_http_response = '';
|
95 |
+
|
96 |
+
// Prepare CURL options
|
97 |
+
$curlopts = array(
|
98 |
+
'CURLOPT_URL' => $url,
|
99 |
+
'CURLOPT_HEADER' => true,
|
100 |
+
'CURLINFO_HEADER_OUT' => true,
|
101 |
+
'CURLOPT_NOBODY' => false,
|
102 |
+
'CURLOPT_HTTPHEADER' => array('Expect:'),
|
103 |
+
'CURLOPT_FOLLOWLOCATION' => false,
|
104 |
+
'CURLOPT_RETURNTRANSFER' => false,
|
105 |
+
'CURLOPT_FRESH_CONNECT' => true,
|
106 |
+
'CURLOPT_CONNECTTIMEOUT' => $connect_timeout,
|
107 |
+
'CURLOPT_TIMEOUT' => $request_timeout,
|
108 |
+
'CURLOPT_USERAGENT' => $user_agent,
|
109 |
+
'CURLOPT_WRITEFUNCTION' => 'wplnst_http_read_stream',
|
110 |
+
);
|
111 |
+
|
112 |
+
// IP resolve options
|
113 |
+
if (defined('CURL_IPRESOLVE_V4'))
|
114 |
+
$curlopts['CURLOPT_IPRESOLVE'] = CURL_IPRESOLVE_V4;
|
115 |
+
|
116 |
+
// HTTPS checks
|
117 |
+
if (0 === strpos($url, 'https')) {
|
118 |
+
$curlopts['CURLOPT_SSL_VERIFYHOST'] = false;
|
119 |
+
$curlopts['CURLOPT_SSL_VERIFYPEER'] = false;
|
120 |
+
}
|
121 |
+
|
122 |
+
// Do the request
|
123 |
+
$response = WPLNST_Core_CURL::request($curlopts, array('CURLINFO_HEADER_OUT', 'CURLINFO_TOTAL_TIME', 'CURLINFO_SIZE_DOWNLOAD', 'CURLINFO_HEADER_SIZE'));
|
124 |
+
|
125 |
+
// Check request headers
|
126 |
+
$headers_request = isset($response['info']['CURLINFO_HEADER_OUT'])? $response['info']['CURLINFO_HEADER_OUT'] : '';
|
127 |
+
|
128 |
+
// Check total time
|
129 |
+
$total_time = isset($response['info']['CURLINFO_TOTAL_TIME'])? (int) $response['info']['CURLINFO_TOTAL_TIME'] : false;
|
130 |
+
if (empty($total_time))
|
131 |
+
$total_time = $response['time'];
|
132 |
+
|
133 |
+
// Total size
|
134 |
+
$total_bytes = isset($response['info']['CURLINFO_SIZE_DOWNLOAD'])? (int) $response['info']['CURLINFO_SIZE_DOWNLOAD'] : false;
|
135 |
+
if (empty($total_bytes))
|
136 |
+
$total_bytes = strlen($wplnst_http_response);
|
137 |
+
|
138 |
+
// Headers size
|
139 |
+
$headers_size = isset($response['info']['CURLINFO_HEADER_SIZE'])? (int) $response['info']['CURLINFO_HEADER_SIZE'] : false;
|
140 |
+
if (empty($headers_size)) {
|
141 |
+
$headers_pos = strpos($wplnst_http_response, "\r\n\r\n");
|
142 |
+
$headers_size = (false === $headers_pos)? $total_bytes : $headers_pos + 4;
|
143 |
+
}
|
144 |
+
|
145 |
+
// Extract headers (trim to avoid conflicts with this script in API mode)
|
146 |
+
$wplnst_http_headers = trim(substr($wplnst_http_response, 0, $headers_size));
|
147 |
+
|
148 |
+
// Check errno exception when aborted with this plugin
|
149 |
+
if ('23' == $response['errno'] && (!empty($max_download_done) || !empty($only_headers_done)))
|
150 |
+
$response['errno'] = 0;
|
151 |
+
|
152 |
+
|
153 |
+
/* Back to WP */
|
154 |
+
|
155 |
+
// Populate POST fields
|
156 |
+
$postfields = array(
|
157 |
+
'url_id' => $url_id,
|
158 |
+
'headers' => $wplnst_http_headers,
|
159 |
+
'headers_request' => $headers_request,
|
160 |
+
'total_time' => $total_time,
|
161 |
+
'total_bytes' => $total_bytes,
|
162 |
+
'headers_size' => $headers_size,
|
163 |
+
'curl_errno' => $response['errno'],
|
164 |
+
'timestamp' => $response['timestamp'],
|
165 |
+
);
|
166 |
+
|
167 |
+
// Aditional body field
|
168 |
+
if (!empty($_POST['return_body']) && '1' == $_POST['return_body'])
|
169 |
+
$postfields['body'] = substr($wplnst_http_response, $headers_size);
|
170 |
+
|
171 |
+
// Check back URL
|
172 |
+
if (!empty($back_url)) {
|
173 |
+
|
174 |
+
// Debug point
|
175 |
+
self::debug('script back start');
|
176 |
+
|
177 |
+
// Spawn back URL call
|
178 |
+
WPLNST_Core_CURL::spawn(array(
|
179 |
+
'CURLOPT_URL' => $back_url,
|
180 |
+
'CURLOPT_USERAGENT' => 'WPLNST HTTP Requests script',
|
181 |
+
'CURLOPT_POST' => true,
|
182 |
+
'CURLOPT_POSTFIELDS' => http_build_query($postfields, null, '&'),
|
183 |
+
'CURLOPT_HTTPHEADER' => array('Content-Type: application/x-www-form-urlencoded; charset=utf-8'),
|
184 |
+
));
|
185 |
+
|
186 |
+
// Debug point
|
187 |
+
self::debug('script back end');
|
188 |
+
|
189 |
+
// End
|
190 |
+
self::terminate();
|
191 |
+
}
|
192 |
+
|
193 |
+
// End with post data
|
194 |
+
self::terminate($postfields);
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
|
199 |
+
// Response
|
200 |
+
// ---------------------------------------------------------------------------------------------------
|
201 |
+
|
202 |
+
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Ends execution
|
206 |
+
*/
|
207 |
+
private static function terminate($output = array()) {
|
208 |
+
|
209 |
+
// Initialize
|
210 |
+
$dump = '';
|
211 |
+
|
212 |
+
// Check array output
|
213 |
+
if (!empty($output) && is_array($output)) {
|
214 |
+
|
215 |
+
// JSON response
|
216 |
+
@header('Content-Type: application/json');
|
217 |
+
|
218 |
+
// Dump data
|
219 |
+
$dump = self::json_encode(array(
|
220 |
+
'status' => 'ok',
|
221 |
+
'data' => $output,
|
222 |
+
));
|
223 |
+
}
|
224 |
+
|
225 |
+
// No cache headers
|
226 |
+
@header('Expires: Tue, 03 Jul 2001 06:00:00 GMT');
|
227 |
+
@header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
|
228 |
+
@header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
229 |
+
@header('Cache-Control: post-check=0, pre-check=0', false);
|
230 |
+
@header('Pragma: no-cache');
|
231 |
+
|
232 |
+
// Avoid indexation
|
233 |
+
@header('X-Robots-Tag: noindex');
|
234 |
+
|
235 |
+
// Debug point
|
236 |
+
self::debug('script terminate');
|
237 |
+
|
238 |
+
// End
|
239 |
+
die($dump);
|
240 |
+
}
|
241 |
+
|
242 |
+
|
243 |
+
|
244 |
+
/**
|
245 |
+
* A driver or wrapper for JSON encode
|
246 |
+
*/
|
247 |
+
private static function json_encode($string) {
|
248 |
+
|
249 |
+
// Check native function
|
250 |
+
if (function_exists('json_encode')) {
|
251 |
+
return @json_encode($string);
|
252 |
+
|
253 |
+
// Other
|
254 |
+
} else {
|
255 |
+
|
256 |
+
// Globals
|
257 |
+
global $wp_json;
|
258 |
+
|
259 |
+
// Check current instance
|
260 |
+
if (empty($wp_json) || !($wp_json instanceof Services_JSON)) {
|
261 |
+
|
262 |
+
// Include file
|
263 |
+
@require_once(dirname(__FILE__).'/class-json.php');
|
264 |
+
|
265 |
+
// Create new object
|
266 |
+
if (class_exists('Services_JSON'))
|
267 |
+
$wp_json = new Services_JSON();
|
268 |
+
}
|
269 |
+
|
270 |
+
// Check object
|
271 |
+
return (!empty($wp_json) && $wp_json instanceof Services_JSON)? $wp_json->encodeUnsafe($string) : false;
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
|
276 |
+
|
277 |
+
// Debug
|
278 |
+
// ---------------------------------------------------------------------------------------------------
|
279 |
+
|
280 |
+
|
281 |
+
|
282 |
+
/**
|
283 |
+
* Debug output
|
284 |
+
*/
|
285 |
+
private static function debug($message) {
|
286 |
+
|
287 |
+
// Initialize
|
288 |
+
static $debug_info;
|
289 |
+
if (!isset($debug_info))
|
290 |
+
$debug_info = self::debug_info();
|
291 |
+
|
292 |
+
// Check debug
|
293 |
+
if (false === $debug_info)
|
294 |
+
return;
|
295 |
+
|
296 |
+
// Prefix
|
297 |
+
$prefix = '';
|
298 |
+
if (!empty($debug_info['scan_id'])) {
|
299 |
+
$prefix = 'scan '.$debug_info['scan_id'];
|
300 |
+
if (!empty($debug_info['thread_id']))
|
301 |
+
$prefix .= ' - thread '.$debug_info['thread_id'];
|
302 |
+
$prefix .= ' ';
|
303 |
+
}
|
304 |
+
|
305 |
+
// Output
|
306 |
+
error_log('WPLNST - '.$prefix.'[http] '.$message);
|
307 |
+
}
|
308 |
+
|
309 |
+
|
310 |
+
|
311 |
+
/**
|
312 |
+
* Debug info check
|
313 |
+
*/
|
314 |
+
private static function debug_info() {
|
315 |
+
|
316 |
+
// Check debug argument
|
317 |
+
if (empty($_POST['debug']) || '1' != $_POST['debug'])
|
318 |
+
return false;
|
319 |
+
|
320 |
+
// Initialize
|
321 |
+
$debug_info = array();
|
322 |
+
|
323 |
+
// Check back URL
|
324 |
+
if (!empty($_POST['back_url'])) {
|
325 |
+
|
326 |
+
// Analyze back URL
|
327 |
+
$info = explode('&wplnst_', str_replace('?wplnst_', '&wplnst_', $_POST['back_url']));
|
328 |
+
|
329 |
+
// Enum elements
|
330 |
+
foreach ($info as $pair) {
|
331 |
+
|
332 |
+
// Check a pair
|
333 |
+
$pair = explode('=', $pair);
|
334 |
+
if (2 == count($pair)) {
|
335 |
+
|
336 |
+
// Scan
|
337 |
+
if ('crawl' == $pair[0]) {
|
338 |
+
$scan_id = (int) $pair[1];
|
339 |
+
if ($scan_id > 0)
|
340 |
+
$debug_info['scan_id'] = $scan_id;
|
341 |
+
|
342 |
+
// Thread
|
343 |
+
} elseif ('thread' == $pair[0]) {
|
344 |
+
$thread_id = (int) $pair[1];
|
345 |
+
if ($thread_id > 0)
|
346 |
+
$debug_info['thread_id'] = $thread_id;
|
347 |
+
}
|
348 |
+
}
|
349 |
+
}
|
350 |
+
}
|
351 |
+
|
352 |
+
// Done
|
353 |
+
return $debug_info;
|
354 |
+
}
|
355 |
+
|
356 |
+
|
357 |
+
|
358 |
+
}
|
359 |
+
|
360 |
+
|
361 |
+
|
362 |
+
// Callback functions
|
363 |
+
// ---------------------------------------------------------------------------------------------------
|
364 |
+
|
365 |
+
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Response callback function
|
369 |
+
*/
|
370 |
+
function wplnst_http_read_stream($ch, $line) {
|
371 |
+
|
372 |
+
// Globals
|
373 |
+
global $wplnst_http_response, $max_download, $max_download_done, $only_headers, $only_headers_done;
|
374 |
+
|
375 |
+
// Current lengths
|
376 |
+
$line_length = strlen($line);
|
377 |
+
$total_length = strlen($wplnst_http_response);
|
378 |
+
|
379 |
+
// Check overflow
|
380 |
+
if (($total_length + $line_length) > $max_download) {
|
381 |
+
|
382 |
+
// Check available size
|
383 |
+
$available = $max_download - $total_length;
|
384 |
+
if ($available > 0)
|
385 |
+
$wplnst_http_response .= substr($line, 0, $available);
|
386 |
+
|
387 |
+
// Max download achieved
|
388 |
+
$max_download_done = true;
|
389 |
+
|
390 |
+
// End
|
391 |
+
return 0;
|
392 |
+
}
|
393 |
+
|
394 |
+
// Add new chunk
|
395 |
+
$wplnst_http_response .= $line;
|
396 |
+
|
397 |
+
// Check only headers
|
398 |
+
if ($only_headers && false !== strpos($wplnst_http_response, "\r\n\r\n")) {
|
399 |
+
|
400 |
+
// Headers achieved
|
401 |
+
$only_headers_done = true;
|
402 |
+
|
403 |
+
// End
|
404 |
+
return 0;
|
405 |
+
}
|
406 |
+
|
407 |
+
// Done
|
408 |
+
return strlen($line);
|
409 |
+
}
|
410 |
+
|
411 |
+
|
412 |
+
// Run
|
413 |
+
WPLNST_Core_HTTP_Request::start();
|
414 |
+
|
415 |
+
|
416 |
+
// End check
|
417 |
+
endif;
|
core/scans.php
ADDED
@@ -0,0 +1,1918 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Scans class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Scans {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
// Retrieving scans data
|
14 |
+
// ---------------------------------------------------------------------------------------------------
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Retrieve existing scans
|
20 |
+
*/
|
21 |
+
public function get_scans($args) {
|
22 |
+
|
23 |
+
// Globals
|
24 |
+
global $wpdb;
|
25 |
+
|
26 |
+
// Prepare args
|
27 |
+
$args = array_merge(array(
|
28 |
+
'setup_rows' => true,
|
29 |
+
'setup_names' => false,
|
30 |
+
'no_cache' => false,
|
31 |
+
), $args);
|
32 |
+
|
33 |
+
// Set vars
|
34 |
+
extract($args);
|
35 |
+
|
36 |
+
// Params
|
37 |
+
$where = ' WHERE 1 = 1';
|
38 |
+
$limit_rows = false;
|
39 |
+
|
40 |
+
// Check scan id
|
41 |
+
if (!empty($scan_id))
|
42 |
+
$where .= ' AND scan_id = '.((int) $scan_id);
|
43 |
+
|
44 |
+
// Check limit
|
45 |
+
if (isset($limit)) {
|
46 |
+
$check = array_map('intval', array_map('trim', explode(',', $limit)));
|
47 |
+
if (1 == count($check)) {
|
48 |
+
if ($check[0] > 0)
|
49 |
+
$limit_rows = $check[0];
|
50 |
+
} elseif (2 == count($check)) {
|
51 |
+
if ($check[0] > 0 || $check[1] > 0)
|
52 |
+
$limit_rows = $check[0].', '.$check[1];
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
// Check single row
|
57 |
+
if (1 === $limit_rows) {
|
58 |
+
|
59 |
+
// Perform query
|
60 |
+
$sql = 'SELECT'.(empty($no_cache)? '' : ' SQL_NO_CACHE').' * FROM '.$wpdb->prefix.'wplnst_scans'.$where.(empty($order_by)? '' : ' ORDER BY '.$order_by).' LIMIT 1';
|
61 |
+
$results = (object) array('rows' => $wpdb->get_results($sql));
|
62 |
+
|
63 |
+
// Multiple rows
|
64 |
+
} else {
|
65 |
+
|
66 |
+
// Check page
|
67 |
+
$paged = empty($paged)? 1 : (int) $paged;
|
68 |
+
if (empty($paged))
|
69 |
+
$paged = 1;
|
70 |
+
|
71 |
+
// Check elements per page
|
72 |
+
$per_page = isset($per_page)? (int) $per_page : (int) get_user_option('wplnst_scans_per_page');
|
73 |
+
if (empty($per_page))
|
74 |
+
$per_page = WPLNST_Core_Types::scans_per_page;
|
75 |
+
|
76 |
+
// Execute query
|
77 |
+
$results = $this->pagination(array(
|
78 |
+
'paged' => $paged,
|
79 |
+
'per_page' => $per_page,
|
80 |
+
'sql' => 'SELECT $$$fields$$$ FROM '.$wpdb->prefix.'wplnst_scans'.$where,
|
81 |
+
'fields' => '*',
|
82 |
+
'order_by' => (empty($order_by)? '' : $order_by),
|
83 |
+
'calc_rows' => wplnst_get_bsetting('mysql_calc_rows'),
|
84 |
+
'no_cache' => false,
|
85 |
+
));
|
86 |
+
}
|
87 |
+
|
88 |
+
// Check setup
|
89 |
+
if (!$setup_rows || empty($results->rows))
|
90 |
+
return $results;
|
91 |
+
|
92 |
+
// Prepare rows
|
93 |
+
$rows = array();
|
94 |
+
foreach ($results->rows as $row)
|
95 |
+
$rows[] = $this->setup_row_scan($row, $setup_names);
|
96 |
+
$results->rows = $rows;
|
97 |
+
|
98 |
+
// Done
|
99 |
+
return $results;
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Return scan by its id
|
106 |
+
*/
|
107 |
+
public function get_scan_by_id($scan_id, $setup_names = false, $no_cache = false) {
|
108 |
+
|
109 |
+
// Retrieve scans list
|
110 |
+
$scans = $this->get_scans(array('scan_id' => $scan_id, 'setup_rows' => true, 'setup_names' => $setup_names, 'no_cache' => $no_cache, 'limit' => 1));
|
111 |
+
|
112 |
+
// Count elements, return first or false
|
113 |
+
return (!empty($scans->rows) && is_array($scans->rows) && 1 == count($scans->rows))? $scans->rows[0] : false;
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Setup a scan database row
|
120 |
+
*/
|
121 |
+
public function setup_row_scan($row, $names = false) {
|
122 |
+
|
123 |
+
// Cache post types
|
124 |
+
static $post_types;
|
125 |
+
if (!isset($post_types))
|
126 |
+
$post_types = WPLNST_Core_Types::get_post_types();
|
127 |
+
|
128 |
+
// Cache post types keys
|
129 |
+
static $post_types_keys;
|
130 |
+
if (!isset($post_types_keys))
|
131 |
+
$post_types_keys = array_keys($post_types);
|
132 |
+
|
133 |
+
// Cache post status
|
134 |
+
static $post_status_keys;
|
135 |
+
if (!isset($post_status_keys))
|
136 |
+
$post_status_keys = array_keys(WPLNST_Core_Types::get_post_status());
|
137 |
+
|
138 |
+
// Cache status level
|
139 |
+
static $status_levels;
|
140 |
+
if (!isset($status_levels))
|
141 |
+
$status_levels = WPLNST_Core_Types::get_status_levels();
|
142 |
+
|
143 |
+
// Cache status levels keys
|
144 |
+
static $status_levels_keys;
|
145 |
+
if (!isset($status_levels_keys))
|
146 |
+
$status_levels_keys = array_keys($status_levels);
|
147 |
+
|
148 |
+
// Cache status codes
|
149 |
+
static $status_codes_raw;
|
150 |
+
if (!isset($status_codes_raw))
|
151 |
+
$status_codes_raw = WPLNST_Core_Types::get_status_codes_raw();
|
152 |
+
|
153 |
+
// Cache status codes keys
|
154 |
+
static $status_codes_keys;
|
155 |
+
if (!isset($status_codes_keys))
|
156 |
+
$status_codes_keys = array_keys($status_codes_raw);
|
157 |
+
|
158 |
+
// Scan object
|
159 |
+
$scan = new stdClass;
|
160 |
+
$scan->row = $row;
|
161 |
+
|
162 |
+
|
163 |
+
/* scan values */
|
164 |
+
|
165 |
+
// Cast fields
|
166 |
+
$scan->id = (int) $row->scan_id;
|
167 |
+
$scan->name = $row->name;
|
168 |
+
$scan->status = $row->status;
|
169 |
+
$scan->ready = (1 == (int) $row->ready);
|
170 |
+
$scan->hash = $row->hash;
|
171 |
+
|
172 |
+
// Decode config json field
|
173 |
+
$config = @json_decode($row->config, true);
|
174 |
+
|
175 |
+
// General tab
|
176 |
+
$scan->destination_type = WPLNST_Core_Types::check_array_value($config, 'destination_type', array_keys(WPLNST_Core_Types::get_destination_types()), 'all');
|
177 |
+
$scan->time_scope = WPLNST_Core_Types::check_array_value($config, 'time_scope', array_keys(WPLNST_Core_Types::get_time_scopes()), 'anytime');
|
178 |
+
$scan->link_types = WPLNST_Core_Types::check_array_value($config, 'link_types', array_keys(WPLNST_Core_Types::get_link_types()), array());
|
179 |
+
$scan->crawl_order = WPLNST_Core_Types::check_array_value($config, 'crawl_order', array_keys(WPLNST_Core_Types::get_crawl_order()), 'desc');
|
180 |
+
$scan->redir_status = WPLNST_Core_Types::check_array_value($config, 'redir_status', true);
|
181 |
+
$scan->malformed = WPLNST_Core_Types::check_array_value($config, 'malformed', true);
|
182 |
+
$scan->notify_default = WPLNST_Core_Types::check_array_value($config, 'notify_default', true);
|
183 |
+
$scan->notify_address = WPLNST_Core_Types::check_array_value($config, 'notify_address', true);
|
184 |
+
$scan->notify_address_email = WPLNST_Core_Types::get_array_value($config, 'notify_address_email', '');
|
185 |
+
|
186 |
+
// Content options tab
|
187 |
+
$scan->post_types = WPLNST_Core_Types::check_array_value($config, 'post_types', $post_types_keys, array());
|
188 |
+
$scan->post_status = WPLNST_Core_Types::check_array_value($config, 'post_status', $post_status_keys, array());
|
189 |
+
$scan->check_posts = (!empty($scan->post_types) && is_array($scan->post_types) && !empty($scan->post_status) && is_array($scan->post_status));
|
190 |
+
$scan->comment_types = WPLNST_Core_Types::check_array_value($config, 'comment_types', array_keys(WPLNST_Core_Types::get_comment_types()), array());
|
191 |
+
$scan->check_comments = (!empty($scan->comment_types) && is_array($scan->comment_types));
|
192 |
+
$scan->check_blogroll = WPLNST_Core_Types::check_array_value($config, 'blogroll', true);
|
193 |
+
|
194 |
+
// Links status tab
|
195 |
+
$scan->status_levels = WPLNST_Core_Types::check_array_value($config, 'status_levels', $status_levels_keys, array());
|
196 |
+
$scan->status_codes = WPLNST_Core_Types::check_array_value($config, 'status_codes', array_keys(WPLNST_Core_Types::get_status_codes_raw()), array());
|
197 |
+
|
198 |
+
// Filters
|
199 |
+
$scan->custom_fields = WPLNST_Core_Types::check_array_json($config, 'custom_fields');
|
200 |
+
$scan->anchor_filters = WPLNST_Core_Types::check_array_json($config, 'anchor_filters');
|
201 |
+
$scan->include_urls = WPLNST_Core_Types::check_array_json($config, 'include_urls');
|
202 |
+
$scan->exclude_urls = WPLNST_Core_Types::check_array_json($config, 'exclude_urls');
|
203 |
+
$scan->html_attributes = WPLNST_Core_Types::check_array_json($config, 'html_attributes');
|
204 |
+
$scan->filtered_query = WPLNST_Core_Types::check_array_value($config, 'filtered_query', true);
|
205 |
+
|
206 |
+
|
207 |
+
/* scan config values names */
|
208 |
+
|
209 |
+
if ($names) {
|
210 |
+
|
211 |
+
// Destination and Time scope
|
212 |
+
$scan->destination_type_name = WPLNST_Core_Types::get_destination_type_name($scan->destination_type, 'all');
|
213 |
+
$scan->time_scope_name = WPLNST_Core_Types::get_time_scope_name($scan->time_scope, 'anytime');
|
214 |
+
|
215 |
+
// Links types
|
216 |
+
$scan->link_types_names = WPLNST_Core_Types::get_link_types_names($scan->link_types);
|
217 |
+
|
218 |
+
// Crawl order
|
219 |
+
$scan->crawl_order_name = WPLNST_Core_Types::get_crawl_order_name($scan->crawl_order, 'desc');
|
220 |
+
|
221 |
+
// Post types and status
|
222 |
+
$scan->post_types_names = WPLNST_Core_Types::get_field_values_names($post_types, $scan->post_types);
|
223 |
+
$scan->post_status_names = empty($scan->post_status)? array() : array_map('ucfirst', $scan->post_status);
|
224 |
+
|
225 |
+
// A strict mode of post types names
|
226 |
+
$scan->post_types_names_strict = array();
|
227 |
+
foreach ($scan->post_types as $post_type_value) {
|
228 |
+
if (isset($post_types[$post_type_value]))
|
229 |
+
$scan->post_types_names_strict[] = esc_html($post_types[$post_type_value]).' (<code>'.esc_html($post_type_value).'</code>)';
|
230 |
+
}
|
231 |
+
|
232 |
+
// Comment types
|
233 |
+
if ($scan->check_comments) {
|
234 |
+
$scan->comment_types_names = WPLNST_Core_Types::get_comment_types_names($scan->comment_types);
|
235 |
+
if (1 == count($scan->comment_types_names)) {
|
236 |
+
$scan->post_types_names[] = sprintf(__('%s comments', 'wplnst'), $scan->comment_types_names[0]);
|
237 |
+
} elseif (2 == count($scan->comment_types_names)) {
|
238 |
+
$scan->post_types_names[] = sprintf(__('%s and %s comments', 'wplnst'), $scan->comment_types_names[0], lcfirst($scan->comment_types_names[1]));
|
239 |
+
}
|
240 |
+
}
|
241 |
+
|
242 |
+
// Check blogroll type
|
243 |
+
if ($scan->check_blogroll)
|
244 |
+
$scan->post_types_names[] = __('Blogroll', 'wplnst');
|
245 |
+
|
246 |
+
// Links status combined
|
247 |
+
$scan->links_status_names = WPLNST_Core_Types::get_links_status_names_combined($scan->status_levels, $scan->status_codes);
|
248 |
+
|
249 |
+
// Links status levels
|
250 |
+
$scan->status_levels_names = array();
|
251 |
+
foreach ($scan->status_levels as $status_level) {
|
252 |
+
if (isset($status_levels[$status_level]))
|
253 |
+
$scan->status_levels_names[] = $status_level.'00s ' .$status_levels[$status_level];
|
254 |
+
}
|
255 |
+
|
256 |
+
// Links status codes
|
257 |
+
$scan->status_codes_names = array();
|
258 |
+
foreach ($scan->status_codes as $status_code) {
|
259 |
+
if (isset($status_codes_raw[$status_code]))
|
260 |
+
$scan->status_codes_names[] = $status_code.' ' .$status_codes_raw[$status_code];
|
261 |
+
}
|
262 |
+
}
|
263 |
+
|
264 |
+
|
265 |
+
/* Prepare trace values */
|
266 |
+
|
267 |
+
// Decode trace json field
|
268 |
+
$trace = @json_decode($row->trace, true);
|
269 |
+
if (empty($trace) || !is_array($trace))
|
270 |
+
$trace = array();
|
271 |
+
$scan->trace = $trace;
|
272 |
+
|
273 |
+
|
274 |
+
/* Prepare scan summary */
|
275 |
+
|
276 |
+
$summary = @json_decode($row->summary, true);
|
277 |
+
if (empty($summary) || !is_array($summary))
|
278 |
+
$summary = array();
|
279 |
+
$scan->summary = $summary;
|
280 |
+
|
281 |
+
|
282 |
+
/* Prepare threads values */
|
283 |
+
|
284 |
+
// Decode threads json field
|
285 |
+
$threads = @json_decode($row->threads, true);
|
286 |
+
|
287 |
+
// Create new object
|
288 |
+
$scan->threads = new stdClass;
|
289 |
+
|
290 |
+
// Assign object properties
|
291 |
+
$scan->threads->current = (empty($threads) || !is_array($threads))? array() : $threads;
|
292 |
+
$scan->threads->max = (int) $row->max_threads;
|
293 |
+
$scan->threads->connect_timeout = (int) $row->connect_timeout;
|
294 |
+
$scan->threads->request_timeout = (int) $row->request_timeout;
|
295 |
+
|
296 |
+
// Done
|
297 |
+
return $scan;
|
298 |
+
}
|
299 |
+
|
300 |
+
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Remove existing scan data
|
304 |
+
*/
|
305 |
+
public function delete_scan($scan_id) {
|
306 |
+
|
307 |
+
// Globals
|
308 |
+
global $wpdb;
|
309 |
+
|
310 |
+
// Remove from main scans table
|
311 |
+
$wpdb->query($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_scans WHERE scan_id = %d', $scan_id));
|
312 |
+
|
313 |
+
// Remove from status table
|
314 |
+
$wpdb->query($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_urls_status WHERE scan_id = %d', $scan_id));
|
315 |
+
|
316 |
+
// Remove from locations table
|
317 |
+
$wpdb->query($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_urls_locations WHERE scan_id = %d', $scan_id));
|
318 |
+
|
319 |
+
// Remove from locations attributes table
|
320 |
+
$wpdb->query($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_urls_locations_att WHERE scan_id = %d', $scan_id));
|
321 |
+
|
322 |
+
// Remove from objects table
|
323 |
+
$wpdb->query($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_scans_objects WHERE scan_id = %d', $scan_id));
|
324 |
+
}
|
325 |
+
|
326 |
+
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Number of running scans
|
330 |
+
*/
|
331 |
+
public function get_scans_play_count() {
|
332 |
+
|
333 |
+
// Globals
|
334 |
+
global $wpdb;
|
335 |
+
|
336 |
+
// Perform query
|
337 |
+
return (int) $wpdb->get_var('SELECT SQL_NO_CACHE COUNT(*) FROM '.$wpdb->prefix.'wplnst_scans WHERE status = "play"');
|
338 |
+
}
|
339 |
+
|
340 |
+
|
341 |
+
|
342 |
+
/**
|
343 |
+
* Return if is possible to play a new scan
|
344 |
+
*/
|
345 |
+
public function can_play_more_scans() {
|
346 |
+
return ($this->get_scans_play_count() < wplnst_get_nsetting('max_scans'));
|
347 |
+
}
|
348 |
+
|
349 |
+
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Check if is ready to start a crawl
|
353 |
+
*/
|
354 |
+
public static function is_scan_ready($scan) {
|
355 |
+
|
356 |
+
// Initialize
|
357 |
+
$result = array();
|
358 |
+
$empty_post_types = false;
|
359 |
+
|
360 |
+
// Check link types
|
361 |
+
if (empty($scan->link_types) || !is_array($scan->link_types))
|
362 |
+
$result['link_types'] = __('There is not any <strong>link type</strong> selected, you need to select one or more.', 'wplnst');
|
363 |
+
|
364 |
+
// Check post types
|
365 |
+
if (empty($scan->post_types) || !is_array($scan->post_types))
|
366 |
+
$empty_post_types = true;
|
367 |
+
|
368 |
+
// Check post status
|
369 |
+
if (empty($scan->post_status) || !is_array($scan->post_status)) {
|
370 |
+
if (!$empty_post_types)
|
371 |
+
$result['post_status'] = __('Need to select any <strong>post status</strong> value for the selected post types.', 'wplnst');
|
372 |
+
}
|
373 |
+
|
374 |
+
// Check comments and blogroll
|
375 |
+
if (!$scan->check_comments && !$scan->check_blogroll) {
|
376 |
+
if ($empty_post_types) {
|
377 |
+
$result['post_types'] = __('There is not any kind of <strong>post type</strong>, <strong>comments</strong> or <strong>blogroll</strong> selected.', 'wplnst');
|
378 |
+
}
|
379 |
+
}
|
380 |
+
|
381 |
+
// Check status levels and status codes
|
382 |
+
if ((empty($scan->status_levels) || !is_array($scan->status_levels)) && (empty($scan->status_codes) || !is_array($scan->status_codes)))
|
383 |
+
$result['link_status'] = __('Missing selection of any <strong>links status</strong> level or status code.', 'wplnst');
|
384 |
+
|
385 |
+
// Done
|
386 |
+
return empty($result)? true : $result;
|
387 |
+
}
|
388 |
+
|
389 |
+
|
390 |
+
|
391 |
+
/*
|
392 |
+
* Update scan ready status
|
393 |
+
*/
|
394 |
+
public function update_scan_ready($scan_id, $ready) {
|
395 |
+
|
396 |
+
// Globals
|
397 |
+
global $wpdb;
|
398 |
+
|
399 |
+
// Perform query
|
400 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('ready' => $ready? 1 : 0), array('scan_id' => $scan_id));
|
401 |
+
}
|
402 |
+
|
403 |
+
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Remove any stored stopped datetime
|
407 |
+
*/
|
408 |
+
public function remove_stopped_time($scan_id) {
|
409 |
+
// Globals
|
410 |
+
global $wpdb;
|
411 |
+
|
412 |
+
// Perform query
|
413 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('stopped_at' => '0000-00-00 00:00:00'), array('scan_id' => $scan_id));
|
414 |
+
}
|
415 |
+
|
416 |
+
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Obtains fresh scan trace data
|
420 |
+
*/
|
421 |
+
public function get_scan_trace($scan_id, $field = false) {
|
422 |
+
|
423 |
+
// Globals
|
424 |
+
global $wpdb;
|
425 |
+
|
426 |
+
// Retrieve fresh trace data
|
427 |
+
$trace = $wpdb->get_var($wpdb->prepare('SELECT SQL_NO_CACHE trace FROM '.$wpdb->prefix.'wplnst_scans WHERE scan_id = %d', $scan_id));
|
428 |
+
$trace = @json_decode($trace, true);
|
429 |
+
$trace = (empty($trace) || !is_array($trace))? array() : $trace;
|
430 |
+
|
431 |
+
// Check field or all values
|
432 |
+
return (false !== $field)? (isset($trace[$field])? $trace[$field] : false) : $trace;
|
433 |
+
}
|
434 |
+
|
435 |
+
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Update scan trace values
|
439 |
+
*/
|
440 |
+
public function update_scan_trace($scan_id, $values) {
|
441 |
+
|
442 |
+
// Globals
|
443 |
+
global $wpdb;
|
444 |
+
|
445 |
+
// Merge trace values
|
446 |
+
$trace = array_merge($this->get_scan_trace($scan_id), $values);
|
447 |
+
|
448 |
+
// Update trace values
|
449 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('trace' => @json_encode($trace)), array('scan_id' => $scan_id));
|
450 |
+
}
|
451 |
+
|
452 |
+
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Retrieve scan summary
|
456 |
+
*/
|
457 |
+
public function get_scan_summary($scan_id) {
|
458 |
+
|
459 |
+
// Globals
|
460 |
+
global $wpdb;
|
461 |
+
|
462 |
+
// Retrieve fresh summary data
|
463 |
+
$summary = $wpdb->get_var($wpdb->prepare('SELECT SQL_NO_CACHE summary FROM '.$wpdb->prefix.'wplnst_scans WHERE scan_id = %d', $scan_id));
|
464 |
+
$summary = @json_decode($summary, true);
|
465 |
+
|
466 |
+
// Check data
|
467 |
+
return (empty($summary) || !is_array($summary))? array() : $summary;
|
468 |
+
}
|
469 |
+
|
470 |
+
|
471 |
+
|
472 |
+
/**
|
473 |
+
* Remove scan summary data by prefixed keys
|
474 |
+
*/
|
475 |
+
public function remove_scan_summary_prefixed($scan_id, $prefixes) {
|
476 |
+
|
477 |
+
// Globals
|
478 |
+
global $wpdb;
|
479 |
+
|
480 |
+
// Check value
|
481 |
+
if (empty($prefixes))
|
482 |
+
return;
|
483 |
+
|
484 |
+
// Check array
|
485 |
+
if (!is_array($prefixes))
|
486 |
+
$prefixes = array($prefixes);
|
487 |
+
|
488 |
+
// Current data
|
489 |
+
$summary = $this->get_scan_summary($scan_id);
|
490 |
+
if (!empty($summary)) {
|
491 |
+
|
492 |
+
// Initialize
|
493 |
+
$summary2 = array();
|
494 |
+
|
495 |
+
// Enum summary data
|
496 |
+
foreach ($summary as $key => $value) {
|
497 |
+
|
498 |
+
// Check prefixes
|
499 |
+
$match = false;
|
500 |
+
foreach ($prefixes as $prefix) {
|
501 |
+
if (0 === stripos($key, $prefix)) {
|
502 |
+
$match = true;
|
503 |
+
break;
|
504 |
+
}
|
505 |
+
}
|
506 |
+
|
507 |
+
// Removed
|
508 |
+
if ($match)
|
509 |
+
continue;
|
510 |
+
|
511 |
+
// Copy data
|
512 |
+
$summary2[$key] = $value;
|
513 |
+
}
|
514 |
+
|
515 |
+
// Check summary update
|
516 |
+
if (count($summary) != count($summary2))
|
517 |
+
$this->update_scan_summary($scan_id, $summary2, false);
|
518 |
+
}
|
519 |
+
}
|
520 |
+
|
521 |
+
|
522 |
+
|
523 |
+
/**
|
524 |
+
* Update scan summary data
|
525 |
+
*/
|
526 |
+
public function update_scan_summary($scan_id, $values, $merge = true) {
|
527 |
+
|
528 |
+
// Globals
|
529 |
+
global $wpdb;
|
530 |
+
|
531 |
+
// Check previous summary
|
532 |
+
$summary = $this->get_scan_summary($scan_id);
|
533 |
+
|
534 |
+
// Merge data
|
535 |
+
$summary = (empty($summary) || !$merge)? $values : array_merge($summary, $values);
|
536 |
+
|
537 |
+
// Update data
|
538 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('summary' => @json_encode($summary)), array('scan_id' => $scan_id));
|
539 |
+
}
|
540 |
+
|
541 |
+
|
542 |
+
|
543 |
+
/**
|
544 |
+
* Update URL info for summary
|
545 |
+
*/
|
546 |
+
public function set_scan_summary_status_codes($scan_id, $status_levels, $status_codes, $final = false) {
|
547 |
+
|
548 |
+
// Globals
|
549 |
+
global $wpdb;
|
550 |
+
|
551 |
+
// Not the last
|
552 |
+
if (!$final) {
|
553 |
+
|
554 |
+
// Check timestamp
|
555 |
+
$timestamp = $this->get_scan_trace($scan_id, 'summary_status_codes');
|
556 |
+
if (false !== $timestamp && (time() - $timestamp) < wplnst_get_nsetting('summary_status'))
|
557 |
+
return;
|
558 |
+
|
559 |
+
// Update timestamp
|
560 |
+
$this->update_scan_trace($scan_id, array('summary_status_codes' => time()));
|
561 |
+
}
|
562 |
+
|
563 |
+
// Check levels
|
564 |
+
if (!empty($status_levels) && is_array($status_levels))
|
565 |
+
$where_levels = 's.status_level IN ("0", "'.implode('", "', array_map('esc_sql', $status_levels)).'")';
|
566 |
+
|
567 |
+
// Check codes
|
568 |
+
if (!empty($status_codes) && is_array($status_codes))
|
569 |
+
$where_codes = 's.status_code IN ("0", "'.implode('", "', array_map('esc_sql', $status_codes)).'")';
|
570 |
+
|
571 |
+
// Compose combined
|
572 |
+
if (isset($where_levels) && isset($where_codes)) {
|
573 |
+
$where = ' AND ('.$where_levels.' OR '.$where_codes.')';
|
574 |
+
|
575 |
+
// Only levels
|
576 |
+
} elseif (isset($where_levels)) {
|
577 |
+
$where = ' AND '.$where_levels;
|
578 |
+
|
579 |
+
// Only codes
|
580 |
+
} elseif (isset($where_codes)) {
|
581 |
+
$where = ' AND '.$where_codes;
|
582 |
+
|
583 |
+
// Error
|
584 |
+
} else {
|
585 |
+
return;
|
586 |
+
}
|
587 |
+
|
588 |
+
// Initialize
|
589 |
+
$total = 0;
|
590 |
+
$codes = array();
|
591 |
+
$levels = array();
|
592 |
+
|
593 |
+
// Retrieve totals of codes for not ignored locations
|
594 |
+
$results = $wpdb->get_results($wpdb->prepare('SELECT s.status_code, COUNT(*) total FROM '.$wpdb->prefix.'wplnst_urls_status s RIGHT JOIN '.$wpdb->prefix.'wplnst_urls_locations l ON s.url_id = l.url_id AND s.scan_id = l.scan_id WHERE s.scan_id = %d '.$where.' AND s.phase = "end" AND l.ignored = 0 GROUP BY status_code', $scan_id));
|
595 |
+
|
596 |
+
// Cast data to array
|
597 |
+
if (!empty($results) && is_array($results)) {
|
598 |
+
|
599 |
+
// Enum code results
|
600 |
+
foreach ($results as $result) {
|
601 |
+
|
602 |
+
// Sum all codes
|
603 |
+
$total += (int) $result->total;
|
604 |
+
|
605 |
+
// Total for this code
|
606 |
+
$codes[$result->status_code] = (int) $result->total;
|
607 |
+
|
608 |
+
// Total for this level
|
609 |
+
$level_key = mb_substr($result->status_code, 0, 1);
|
610 |
+
$levels[$level_key] = isset($levels[$level_key])? $levels[$level_key] + $codes[$result->status_code] : $codes[$result->status_code];
|
611 |
+
}
|
612 |
+
}
|
613 |
+
|
614 |
+
// Prepare to summary
|
615 |
+
$summary_keys = array();
|
616 |
+
|
617 |
+
// Prefix code keys
|
618 |
+
foreach ($codes as $key => $value)
|
619 |
+
$summary_keys['status_code_'.$key] = $value;
|
620 |
+
|
621 |
+
// Prefix level keys
|
622 |
+
foreach ($levels as $key => $value)
|
623 |
+
$summary_keys['status_level_'.$key] = $value;
|
624 |
+
|
625 |
+
// Total results
|
626 |
+
$summary_keys['status_total'] = $total;
|
627 |
+
|
628 |
+
// Remove old summary status values
|
629 |
+
$this->remove_scan_summary_prefixed($scan_id, array('status_code_', 'status_level_'));
|
630 |
+
|
631 |
+
// Update summary data
|
632 |
+
$this->update_scan_summary($scan_id, $summary_keys);
|
633 |
+
}
|
634 |
+
|
635 |
+
|
636 |
+
|
637 |
+
/**
|
638 |
+
* Update URL info for summary
|
639 |
+
*/
|
640 |
+
public function set_scan_summary_urls_phases($scan_id, $final = false) {
|
641 |
+
|
642 |
+
// Globals
|
643 |
+
global $wpdb;
|
644 |
+
|
645 |
+
// Not the last
|
646 |
+
if (!$final) {
|
647 |
+
|
648 |
+
// Check timestamp
|
649 |
+
$timestamp = $this->get_scan_trace($scan_id, 'summary_url_phases');
|
650 |
+
if (false !== $timestamp && (time() - $timestamp) < wplnst_get_nsetting('summary_phases'))
|
651 |
+
return;
|
652 |
+
|
653 |
+
// Update timestamp
|
654 |
+
$this->update_scan_trace($scan_id, array('summary_url_phases' => time()));
|
655 |
+
}
|
656 |
+
|
657 |
+
// Initialize
|
658 |
+
$phases = array();
|
659 |
+
|
660 |
+
// Retrieve totals of phases
|
661 |
+
$results = $wpdb->get_results($wpdb->prepare('SELECT phase, COUNT(*) total FROM '.$wpdb->prefix.'wplnst_urls_status WHERE scan_id = %d GROUP BY phase', $scan_id));
|
662 |
+
|
663 |
+
// Cast data to array
|
664 |
+
if (!empty($results) && is_array($results)) {
|
665 |
+
foreach ($results as $result)
|
666 |
+
$phases[$result->phase] = (int) $result->total;
|
667 |
+
}
|
668 |
+
|
669 |
+
// Merge default values
|
670 |
+
$phases = array_merge(array(
|
671 |
+
'wait' => 0,
|
672 |
+
'redir' => 0,
|
673 |
+
'play' => 0,
|
674 |
+
'end' => 0,
|
675 |
+
'discard' => 0,
|
676 |
+
'failed' => 0
|
677 |
+
), $phases);
|
678 |
+
|
679 |
+
// Sum redir to wait
|
680 |
+
$phases['wait'] += $phases['redir'];
|
681 |
+
|
682 |
+
// New values combined
|
683 |
+
$phases['processed'] = $phases['end'] + $phases['discard'] + $phases['failed'];
|
684 |
+
|
685 |
+
// Prefix keys
|
686 |
+
$summary_phases = array();
|
687 |
+
foreach ($phases as $key => $value)
|
688 |
+
$summary_phases['urls_phase_'.$key] = $value;
|
689 |
+
|
690 |
+
// Update summary data
|
691 |
+
$this->update_scan_summary($scan_id, $summary_phases);
|
692 |
+
}
|
693 |
+
|
694 |
+
|
695 |
+
|
696 |
+
/**
|
697 |
+
* Obtains the total match objects and update summary
|
698 |
+
*/
|
699 |
+
public function set_scan_summary_objects_match($scan_id, $object_type, $final = false) {
|
700 |
+
|
701 |
+
// Globals
|
702 |
+
global $wpdb;
|
703 |
+
|
704 |
+
// Not the last
|
705 |
+
if (!$final) {
|
706 |
+
|
707 |
+
// Check timestamp
|
708 |
+
$timestamp = $this->get_scan_trace($scan_id, 'summary_objects_match');
|
709 |
+
if (false !== $timestamp && (time() - $timestamp) < wplnst_get_nsetting('summary_objects'))
|
710 |
+
return;
|
711 |
+
|
712 |
+
// Update timestamp
|
713 |
+
$this->update_scan_trace($scan_id, array('summary_objects_match' => time()));
|
714 |
+
}
|
715 |
+
|
716 |
+
// Perform query
|
717 |
+
$objects_match = (int) $wpdb->get_var($wpdb->prepare('SELECT COUNT(DISTINCT object_id) FROM '.$wpdb->prefix.'wplnst_urls_locations WHERE scan_id = %d AND object_type = %s', $scan_id, $object_type));
|
718 |
+
|
719 |
+
// Update summary data
|
720 |
+
$this->update_scan_summary($scan_id, array('objects_match_'.$object_type => $objects_match));
|
721 |
+
}
|
722 |
+
|
723 |
+
|
724 |
+
|
725 |
+
/**
|
726 |
+
* Save max threads and timeouts connection options
|
727 |
+
* This works at the end of an scan crawling process
|
728 |
+
*/
|
729 |
+
public function set_scan_final_threads_options($scan_id, $args) {
|
730 |
+
|
731 |
+
// Globals
|
732 |
+
global $wpdb;
|
733 |
+
|
734 |
+
$args = array_merge(array(
|
735 |
+
'max_threads' => 0,
|
736 |
+
'connect_timeout' => 0,
|
737 |
+
'request_timeout' => 0,
|
738 |
+
), $args);
|
739 |
+
|
740 |
+
// Prepare update
|
741 |
+
$update = array(
|
742 |
+
'max_threads' => wplnst_get_nsetting('max_threads', $args['max_threads']),
|
743 |
+
'connect_timeout' => wplnst_get_nsetting('connect_timeout', $args['connect_timeout']),
|
744 |
+
'request_timeout' => wplnst_get_nsetting('request_timeout', $args['request_timeout']),
|
745 |
+
);
|
746 |
+
|
747 |
+
// Update
|
748 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', $update, array('scan_id' => $scan_id));
|
749 |
+
}
|
750 |
+
|
751 |
+
|
752 |
+
|
753 |
+
// Scan status queries
|
754 |
+
// ---------------------------------------------------------------------------------------------------
|
755 |
+
|
756 |
+
|
757 |
+
|
758 |
+
/**
|
759 |
+
* Obtains fresh scan status data
|
760 |
+
*/
|
761 |
+
public function get_scan_status($scan_id) {
|
762 |
+
|
763 |
+
// Globals
|
764 |
+
global $wpdb;
|
765 |
+
|
766 |
+
// Return status
|
767 |
+
return $wpdb->get_var($wpdb->prepare('SELECT SQL_NO_CACHE status FROM '.$wpdb->prefix.'wplnst_scans WHERE scan_id = %d', $scan_id));
|
768 |
+
}
|
769 |
+
|
770 |
+
|
771 |
+
|
772 |
+
/**
|
773 |
+
* Stop any playing scan
|
774 |
+
*/
|
775 |
+
public function stop_playing_scans() {
|
776 |
+
|
777 |
+
// Globals
|
778 |
+
global $wpdb;
|
779 |
+
|
780 |
+
// Perform query
|
781 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('status' => 'stop'), array('status' => 'play'));
|
782 |
+
}
|
783 |
+
|
784 |
+
|
785 |
+
|
786 |
+
/**
|
787 |
+
* Queue a given scan
|
788 |
+
*/
|
789 |
+
public function queue_scan($scan_id) {
|
790 |
+
|
791 |
+
// Globals
|
792 |
+
global $wpdb;
|
793 |
+
|
794 |
+
// Perform query
|
795 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('status' => 'queued', 'enqueued_at' => current_time('mysql', true)), array('scan_id' => $scan_id));
|
796 |
+
}
|
797 |
+
|
798 |
+
|
799 |
+
|
800 |
+
/**
|
801 |
+
* Unqueue scan, cast to wait
|
802 |
+
*/
|
803 |
+
public function unqueue_scan($scan_id) {
|
804 |
+
|
805 |
+
// Globals
|
806 |
+
global $wpdb;
|
807 |
+
|
808 |
+
// Perform query
|
809 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('status' => 'wait'), array('scan_id' => $scan_id));
|
810 |
+
}
|
811 |
+
|
812 |
+
|
813 |
+
|
814 |
+
/**
|
815 |
+
* Play a given scan
|
816 |
+
*/
|
817 |
+
public function play_scan($scan_id, $continued = false) {
|
818 |
+
|
819 |
+
// Globals
|
820 |
+
global $wpdb;
|
821 |
+
|
822 |
+
// Decide field
|
823 |
+
$time_field = $continued? 'continued_at' : 'started_at';
|
824 |
+
|
825 |
+
// Perform query
|
826 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('status' => 'play', $time_field => current_time('mysql', true)), array('scan_id' => $scan_id));
|
827 |
+
}
|
828 |
+
|
829 |
+
|
830 |
+
|
831 |
+
/**
|
832 |
+
* Stop a given scan
|
833 |
+
*/
|
834 |
+
public function stop_scan($scan_id) {
|
835 |
+
|
836 |
+
// Globals
|
837 |
+
global $wpdb;
|
838 |
+
|
839 |
+
// Perform query
|
840 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('status' => 'stop', 'stopped_at' => current_time('mysql', true)), array('scan_id' => $scan_id));
|
841 |
+
}
|
842 |
+
|
843 |
+
|
844 |
+
|
845 |
+
/**
|
846 |
+
* Terminated scan
|
847 |
+
*/
|
848 |
+
public function end_scan($scan_id) {
|
849 |
+
|
850 |
+
// Globals
|
851 |
+
global $wpdb;
|
852 |
+
|
853 |
+
// Perform query
|
854 |
+
return $wpdb->update($wpdb->prefix.'wplnst_scans', array('status' => 'end', 'finished_at' => current_time('mysql', true)), array('scan_id' => $scan_id));
|
855 |
+
}
|
856 |
+
|
857 |
+
|
858 |
+
|
859 |
+
// URLs crawling procedures
|
860 |
+
// ---------------------------------------------------------------------------------------------------
|
861 |
+
|
862 |
+
|
863 |
+
|
864 |
+
/**
|
865 |
+
* Replacement function of WP API because we need meta_id
|
866 |
+
*/
|
867 |
+
public function get_post_metas($post_id) {
|
868 |
+
|
869 |
+
// Globals
|
870 |
+
global $wpdb;
|
871 |
+
|
872 |
+
// Check keys input
|
873 |
+
if (!empty($keys) && !is_array($keys))
|
874 |
+
$keys = array($keys);
|
875 |
+
|
876 |
+
// Retrieve metas
|
877 |
+
$rows = $wpdb->get_results($wpdb->prepare('SELECT * FROM '.$wpdb->postmeta.' WHERE post_id = %d ORDER BY meta_id ASC', $post_id));
|
878 |
+
|
879 |
+
// Check results
|
880 |
+
if (!empty($rows) && is_array($rows)) {
|
881 |
+
|
882 |
+
// Initialize
|
883 |
+
$metas = array();
|
884 |
+
|
885 |
+
// Enum rrows
|
886 |
+
foreach ($rows as $row) {
|
887 |
+
|
888 |
+
// Check meta key
|
889 |
+
if (empty($row->meta_key))
|
890 |
+
continue;
|
891 |
+
|
892 |
+
// Check by name
|
893 |
+
if (!isset($metas[$row->meta_key]))
|
894 |
+
$metas[$row->meta_key] = array();
|
895 |
+
|
896 |
+
// Add value
|
897 |
+
$metas[$row->meta_key][$row->meta_id] = $row->meta_value;
|
898 |
+
}
|
899 |
+
|
900 |
+
// Done
|
901 |
+
return $metas;
|
902 |
+
}
|
903 |
+
|
904 |
+
// Not found
|
905 |
+
return false;
|
906 |
+
}
|
907 |
+
|
908 |
+
|
909 |
+
|
910 |
+
/**
|
911 |
+
* Register by identifiers before process the object
|
912 |
+
*/
|
913 |
+
public function register_scan_object($scan_id, $object_id, $object_type, $object_date_gmt = "0000-00-00 00:00:00") {
|
914 |
+
|
915 |
+
// Globals
|
916 |
+
global $wpdb;
|
917 |
+
|
918 |
+
// Insert attempt
|
919 |
+
return (1 == (int) $wpdb->query($wpdb->prepare('INSERT IGNORE INTO '.$wpdb->prefix.'wplnst_scans_objects SET scan_id = %d, object_id = %d, object_type = %s, object_date_gmt = %s', $scan_id, $object_id, $object_type, $object_date_gmt)));
|
920 |
+
}
|
921 |
+
|
922 |
+
|
923 |
+
|
924 |
+
/**
|
925 |
+
* Check if exists an scan object
|
926 |
+
*/
|
927 |
+
public function scan_object_exists($scan_id, $object_id, $object_type) {
|
928 |
+
|
929 |
+
// Globals
|
930 |
+
global $wpdb;
|
931 |
+
|
932 |
+
// Number of occurrences
|
933 |
+
return (1 == (int) $wpdb->get_var($wpdb->prepare('SELECT SQL_NO_CACHE COUNT(*) FROM '.$wpdb->prefix.'wplnst_scans_objects WHERE scan_id = %d AND object_id = %d AND object_type = %s', $scan_id, $object_id, $object_type)));
|
934 |
+
}
|
935 |
+
|
936 |
+
|
937 |
+
|
938 |
+
/**
|
939 |
+
* Retrieve object identifiers based on type and same date
|
940 |
+
*/
|
941 |
+
public function get_scan_objects_ids_by_date($scan_id, $object_type, $object_date_gmt) {
|
942 |
+
|
943 |
+
// Globals
|
944 |
+
global $wpdb;
|
945 |
+
|
946 |
+
// Number of occurrences
|
947 |
+
return $wpdb->get_col($wpdb->prepare('SELECT SQL_NO_CACHE object_id FROM '.$wpdb->prefix.'wplnst_scans_objects WHERE scan_id = %d AND object_type = %s AND object_date_gmt = %s', $scan_id, $object_type, $object_date_gmt));
|
948 |
+
}
|
949 |
+
|
950 |
+
|
951 |
+
|
952 |
+
/**
|
953 |
+
* Return the amount of registered objects
|
954 |
+
*/
|
955 |
+
public function get_scan_objects_count($scan_id, $object_type) {
|
956 |
+
|
957 |
+
// Globals
|
958 |
+
global $wpdb;
|
959 |
+
|
960 |
+
// Insert attempt
|
961 |
+
return (int) $wpdb->get_var($wpdb->prepare('SELECT COUNT(*) FROM '.$wpdb->prefix.'wplnst_scans_objects WHERE scan_id = %d AND object_type = %s', $scan_id, $object_type));
|
962 |
+
}
|
963 |
+
|
964 |
+
|
965 |
+
|
966 |
+
/**
|
967 |
+
* Remove all scan registered objects
|
968 |
+
*/
|
969 |
+
public function remove_scan_objects($scan_id) {
|
970 |
+
|
971 |
+
// Globals
|
972 |
+
global $wpdb;
|
973 |
+
|
974 |
+
// Insert attempt
|
975 |
+
return (int) $wpdb->get_var($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_scans_objects WHERE scan_id = %d', $scan_id));
|
976 |
+
}
|
977 |
+
|
978 |
+
|
979 |
+
|
980 |
+
/**
|
981 |
+
* Retrieve scan URL data
|
982 |
+
*/
|
983 |
+
public function get_scan_url($args) {
|
984 |
+
|
985 |
+
// Globals
|
986 |
+
global $wpdb;
|
987 |
+
|
988 |
+
// Arguments
|
989 |
+
extract($args);
|
990 |
+
|
991 |
+
// Check by id
|
992 |
+
if (isset($id)) {
|
993 |
+
|
994 |
+
// Check identifier
|
995 |
+
$id = (int) $id;
|
996 |
+
if (!empty($id)) {
|
997 |
+
$row = $wpdb->get_row($wpdb->prepare('SELECT '.(isset($no_cache)? 'SQL_NO_CACHE ' : '').'* FROM '.$wpdb->prefix.'wplnst_urls WHERE url_id = %d', $id));
|
998 |
+
return empty($row)? false : $row;
|
999 |
+
}
|
1000 |
+
|
1001 |
+
// By URL string
|
1002 |
+
} elseif (isset($url)) {
|
1003 |
+
|
1004 |
+
// Retrieve URLs by hash
|
1005 |
+
$rows = $wpdb->get_results($wpdb->prepare('SELECT '.(isset($no_cache)? 'SQL_NO_CACHE ' : '').'* FROM '.$wpdb->prefix.'wplnst_urls WHERE hash = %s ORDER BY url_id ASC', $this->get_url_hash($url)));
|
1006 |
+
if (empty($rows) || !is_array($rows) || 1 != count($rows))
|
1007 |
+
return false;
|
1008 |
+
|
1009 |
+
// Done
|
1010 |
+
return $rows[0];
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
// Default
|
1014 |
+
return false;
|
1015 |
+
}
|
1016 |
+
|
1017 |
+
|
1018 |
+
|
1019 |
+
/**
|
1020 |
+
* Creates a 64 bytes hash to avoid URLs collisions
|
1021 |
+
*/
|
1022 |
+
public function get_url_hash($url) {
|
1023 |
+
|
1024 |
+
// First part
|
1025 |
+
$hash = md5($url);
|
1026 |
+
|
1027 |
+
// Another version
|
1028 |
+
$url2 = array();
|
1029 |
+
|
1030 |
+
// Special chars
|
1031 |
+
static $special;
|
1032 |
+
if (!isset($special))
|
1033 |
+
$special = array(";", "/", "?", ":", "@", "&", "=", "+", "$", ",", "-", "_", ".", "!", "~", "*", "'", "(", ")");
|
1034 |
+
|
1035 |
+
// Enum URL chars
|
1036 |
+
$length = mb_strlen($url);
|
1037 |
+
for ($i = 0; $i < $length; $i++) {
|
1038 |
+
$char = mb_substr($url, $i, 1);
|
1039 |
+
if (!in_array($char, $special))
|
1040 |
+
$url2[] = $char;
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
// Return combined hash
|
1044 |
+
return $hash.md5(implode('', array_reverse($url2)));
|
1045 |
+
}
|
1046 |
+
|
1047 |
+
|
1048 |
+
|
1049 |
+
/**
|
1050 |
+
* Retrieve next URL with next value
|
1051 |
+
*/
|
1052 |
+
public function get_scan_url_waiting($scan_id) {
|
1053 |
+
|
1054 |
+
// Retrieve by wait status
|
1055 |
+
if (false !== ($rows = $this->get_scan_url_status(array(
|
1056 |
+
'scan_id' => $scan_id,
|
1057 |
+
'phase' => array('wait', 'redir'),
|
1058 |
+
'order' => 'created_at ASC',
|
1059 |
+
'no_cache' => true,
|
1060 |
+
'limit_rows' => 1,
|
1061 |
+
)))) {
|
1062 |
+
|
1063 |
+
// Retrieve url
|
1064 |
+
$url = $this->get_scan_url(array('id' => $rows[0]->url_id, 'no_cache' => true));
|
1065 |
+
if (false !== $url) {
|
1066 |
+
|
1067 |
+
// Check a redirection
|
1068 |
+
if ('redir' == $rows[0]->phase) {
|
1069 |
+
$url->url = $rows[0]->redirect_url;
|
1070 |
+
$url->redirection = true;
|
1071 |
+
}
|
1072 |
+
}
|
1073 |
+
|
1074 |
+
// Done
|
1075 |
+
return $url;
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
// Default
|
1079 |
+
return false;
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
|
1083 |
+
|
1084 |
+
/**
|
1085 |
+
* Add new URL scan
|
1086 |
+
*/
|
1087 |
+
public function add_scan_url($link, $scan_id) {
|
1088 |
+
|
1089 |
+
// Globals
|
1090 |
+
global $wpdb;
|
1091 |
+
|
1092 |
+
// Create hash
|
1093 |
+
$hash = $this->get_url_hash($link['url']);
|
1094 |
+
|
1095 |
+
// Prepare fields
|
1096 |
+
$scheme = isset($link['scheme'])? mb_substr($link['scheme'], 0, 20) : '';
|
1097 |
+
$host = isset($link['host'])? mb_substr($link['host'], 0, 255) : '';
|
1098 |
+
$path = isset($link['path'])? mb_substr($link['path'], 0, 255) : '';
|
1099 |
+
$query = isset($link['query'])? mb_substr($link['query'], 0, 255) : '';
|
1100 |
+
$scope = isset($link['scope'])? $link['scope'] : '';
|
1101 |
+
|
1102 |
+
// Add new scan status
|
1103 |
+
$result = $wpdb->query($wpdb->prepare('INSERT IGNORE INTO '.$wpdb->prefix.'wplnst_urls SET url = %s, hash = %s, scheme = %s, host = %s, path = %s, query = %s, scope = %s, created_at = %s, last_scan_id = %d', $link['url'], $hash, $scheme, $host, $path, $query, $scope, current_time('mysql', true), $scan_id));
|
1104 |
+
if (!empty($wpdb->insert_id)) {
|
1105 |
+
return $wpdb->insert_id;
|
1106 |
+
|
1107 |
+
// Collision?
|
1108 |
+
} else {
|
1109 |
+
|
1110 |
+
// Retrieve existing URL record
|
1111 |
+
$rows = $wpdb->get_results($wpdb->prepare('SELECT url_id, url FROM '.$wpdb->prefix.'wplnst_urls WHERE hash = %s', $hash));
|
1112 |
+
if (empty($rows) || !is_array($rows) || 1 != count($rows))
|
1113 |
+
return false;
|
1114 |
+
|
1115 |
+
// Return id only if URLs are the same
|
1116 |
+
return ($rows[0]->url === $url)? $rows[0]->url_id : false;
|
1117 |
+
}
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
|
1121 |
+
|
1122 |
+
/**
|
1123 |
+
* Update URL scan data
|
1124 |
+
*/
|
1125 |
+
public function update_scan_url($url_id, $update) {
|
1126 |
+
|
1127 |
+
// Globals
|
1128 |
+
global $wpdb;
|
1129 |
+
|
1130 |
+
// Update play value
|
1131 |
+
return $wpdb->update($wpdb->prefix.'wplnst_urls', $update, array('url_id' => $url_id));
|
1132 |
+
}
|
1133 |
+
|
1134 |
+
|
1135 |
+
|
1136 |
+
/**
|
1137 |
+
* Add location for scan url
|
1138 |
+
*/
|
1139 |
+
public function add_scan_url_location($url_id, $scan_id, $link) {
|
1140 |
+
|
1141 |
+
// Globals
|
1142 |
+
global $wpdb;
|
1143 |
+
|
1144 |
+
// Add new url
|
1145 |
+
$wpdb->insert($wpdb->prefix.'wplnst_urls_locations', array(
|
1146 |
+
'url_id' => $url_id,
|
1147 |
+
'scan_id' => $scan_id,
|
1148 |
+
'link_type' => $link['link_type'],
|
1149 |
+
'object_id' => $link['object_id'],
|
1150 |
+
'object_type' => $link['object_type'],
|
1151 |
+
'object_post_type' => $link['object_post_type'],
|
1152 |
+
'object_field' => $link['object_field'],
|
1153 |
+
'object_date_gmt' => $link['object_date_gmt'],
|
1154 |
+
'detected_at' => current_time('mysql', true),
|
1155 |
+
'chunk' => isset($link['chunk'])? $link['chunk'] : '',
|
1156 |
+
'anchor' => isset($link['anchor'])? $link['anchor'] : '',
|
1157 |
+
'raw_url' => $link['raw'],
|
1158 |
+
'fragment' => $link['fragment'],
|
1159 |
+
'spaced' => $link['spaced']? 1 : 0,
|
1160 |
+
'malformed' => $link['malformed']? 1 : 0,
|
1161 |
+
'absolute' => $link['absolute']? 1 : 0,
|
1162 |
+
'protorel' => $link['protorel']? 1 : 0,
|
1163 |
+
'relative' => $link['relative']? 1 : 0,
|
1164 |
+
'nofollow' => $link['nofollow']? 1 : 0,
|
1165 |
+
));
|
1166 |
+
|
1167 |
+
// Result
|
1168 |
+
return empty($wpdb->insert_id)? false : $wpdb->insert_id;
|
1169 |
+
}
|
1170 |
+
|
1171 |
+
|
1172 |
+
|
1173 |
+
/**
|
1174 |
+
* Update location fields
|
1175 |
+
*/
|
1176 |
+
public function update_scan_url_location($loc_id, $update) {
|
1177 |
+
|
1178 |
+
// Globals
|
1179 |
+
global $wpdb;
|
1180 |
+
|
1181 |
+
// Update
|
1182 |
+
return $wpdb->update($wpdb->prefix.'wplnst_urls_locations', $update, array('loc_id' => $loc_id));
|
1183 |
+
}
|
1184 |
+
|
1185 |
+
|
1186 |
+
|
1187 |
+
/**
|
1188 |
+
* Update several locations
|
1189 |
+
*/
|
1190 |
+
public function update_scan_url_locations($loc_ids, $update) {
|
1191 |
+
foreach ($loc_ids as $loc_id)
|
1192 |
+
$this->update_scan_url_location($loc_id, $update);
|
1193 |
+
}
|
1194 |
+
|
1195 |
+
|
1196 |
+
|
1197 |
+
/**
|
1198 |
+
* Update posts fields
|
1199 |
+
*/
|
1200 |
+
public function update_scan_post($post_id, $update, $clean_cache = true) {
|
1201 |
+
|
1202 |
+
// Globals
|
1203 |
+
global $wpdb;
|
1204 |
+
|
1205 |
+
// Update
|
1206 |
+
$result = $wpdb->update($wpdb->posts, $update, array('ID' => $post_id));
|
1207 |
+
|
1208 |
+
// Check cache
|
1209 |
+
if ($clean_cache)
|
1210 |
+
clean_post_cache($post_id);
|
1211 |
+
|
1212 |
+
// Done
|
1213 |
+
return $result;
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
|
1217 |
+
|
1218 |
+
/**
|
1219 |
+
* Update meta associated to post
|
1220 |
+
*/
|
1221 |
+
public function update_scan_post_meta($post_id, $meta_id, $content, $clean_cache = true) {
|
1222 |
+
|
1223 |
+
// Globals
|
1224 |
+
global $wpdb;
|
1225 |
+
|
1226 |
+
// Update
|
1227 |
+
$result = $wpdb->update($wpdb->postmeta, array('meta_value' => $content), array('meta_id' => $meta_id));
|
1228 |
+
|
1229 |
+
// Check cache
|
1230 |
+
if ($clean_cache)
|
1231 |
+
clean_post_cache($post_id);
|
1232 |
+
|
1233 |
+
// Done
|
1234 |
+
return $result;
|
1235 |
+
}
|
1236 |
+
|
1237 |
+
|
1238 |
+
|
1239 |
+
/**
|
1240 |
+
* Update comment fields
|
1241 |
+
*/
|
1242 |
+
public function update_scan_comment($comment_id, $update, $clean_cache = true) {
|
1243 |
+
|
1244 |
+
// Globals
|
1245 |
+
global $wpdb;
|
1246 |
+
|
1247 |
+
// Update
|
1248 |
+
$result = $wpdb->update($wpdb->comments, $update, array('comment_ID' => $comment_id));
|
1249 |
+
|
1250 |
+
// Check cache
|
1251 |
+
if ($clean_cache)
|
1252 |
+
clean_comment_cache($comment_id);
|
1253 |
+
|
1254 |
+
// Done
|
1255 |
+
return $result;
|
1256 |
+
}
|
1257 |
+
|
1258 |
+
|
1259 |
+
|
1260 |
+
/**
|
1261 |
+
* Update bookmark fields
|
1262 |
+
*/
|
1263 |
+
public function update_scan_bookmark($link_id, $update, $clean_cache = true) {
|
1264 |
+
|
1265 |
+
// Globals
|
1266 |
+
global $wpdb;
|
1267 |
+
|
1268 |
+
// Update
|
1269 |
+
$result = $wpdb->update($wpdb->links, $update, array('link_id' => $link_id));
|
1270 |
+
|
1271 |
+
// Check cache
|
1272 |
+
if ($clean_cache)
|
1273 |
+
clean_bookmark_cache($link_id);
|
1274 |
+
|
1275 |
+
// Done
|
1276 |
+
return $result;
|
1277 |
+
}
|
1278 |
+
|
1279 |
+
|
1280 |
+
|
1281 |
+
/**
|
1282 |
+
* Update total content for a given URL
|
1283 |
+
*/
|
1284 |
+
public function set_scan_url_status_total_content($url_id, $scan_id) {
|
1285 |
+
|
1286 |
+
// Globals
|
1287 |
+
global $wpdb;
|
1288 |
+
|
1289 |
+
// Initialize
|
1290 |
+
$total = array();
|
1291 |
+
|
1292 |
+
// Retrieve total rows by object type
|
1293 |
+
$results = $wpdb->get_results($wpdb->prepare('SELECT object_type, COUNT(*) total FROM '.$wpdb->prefix.'wplnst_urls_locations WHERE url_id = %d AND scan_id = %d GROUP BY object_type', $url_id, $scan_id));
|
1294 |
+
|
1295 |
+
// Cast data to array
|
1296 |
+
if (!empty($results) && is_array($results)) {
|
1297 |
+
foreach ($results as $result)
|
1298 |
+
$total[$result->object_type] = (int) $result->total;
|
1299 |
+
}
|
1300 |
+
|
1301 |
+
// Merge default values
|
1302 |
+
$total = array_merge(array(
|
1303 |
+
'posts' => 0,
|
1304 |
+
'comments' => 0,
|
1305 |
+
'blogroll' => 0,
|
1306 |
+
), $total);
|
1307 |
+
|
1308 |
+
// Update scan URL status row
|
1309 |
+
$this->update_scan_url_status($url_id, $scan_id, array('total_posts' => $total['posts'], 'total_comments' => $total['comments'], 'total_blogroll' => $total['blogroll']));
|
1310 |
+
}
|
1311 |
+
|
1312 |
+
|
1313 |
+
|
1314 |
+
/**
|
1315 |
+
* Retrieve URL status info
|
1316 |
+
*/
|
1317 |
+
public function get_scan_url_status($args = array()) {
|
1318 |
+
|
1319 |
+
// Globals
|
1320 |
+
global $wpdb;
|
1321 |
+
|
1322 |
+
// Check arguments
|
1323 |
+
if (empty($args) || !is_array($args))
|
1324 |
+
return false;
|
1325 |
+
|
1326 |
+
// Extract parameters
|
1327 |
+
extract($args);
|
1328 |
+
|
1329 |
+
// Cast arguments
|
1330 |
+
$url_id = isset($url_id)? (int) $url_id : 0;
|
1331 |
+
$scan_id = isset($scan_id)? (int) $scan_id : 0;
|
1332 |
+
$status = isset($status)? $status : false;
|
1333 |
+
$phase = isset($phase)? $phase : false;
|
1334 |
+
|
1335 |
+
// Check identifiers
|
1336 |
+
if (empty($url_id) && empty($scan_id))
|
1337 |
+
return false;
|
1338 |
+
|
1339 |
+
// Force cache for an isolated record
|
1340 |
+
if (!isset($no_cache) && !empty($url_id) && !empty($scan_id))
|
1341 |
+
$no_cache = true;
|
1342 |
+
|
1343 |
+
// Initialize
|
1344 |
+
$where = '1 = 1';
|
1345 |
+
|
1346 |
+
// Check URL id
|
1347 |
+
if (!empty($url_id))
|
1348 |
+
$where .= ' AND url_id = '.$url_id;
|
1349 |
+
|
1350 |
+
// Check scan id
|
1351 |
+
if (!empty($scan_id))
|
1352 |
+
$where .= ' AND scan_id = '.$scan_id;
|
1353 |
+
|
1354 |
+
// Check status
|
1355 |
+
if (false !== $status)
|
1356 |
+
$where .= ' AND status = "'.esc_sql($status).'"';
|
1357 |
+
|
1358 |
+
// Check phase
|
1359 |
+
if (false !== $phase)
|
1360 |
+
$where .= ' AND phase'.(is_array($phase)? ' IN ("'.implode('", "', array_map('esc_sql', $phase)).'")' : ' = "'.esc_sql($phase).'"');
|
1361 |
+
|
1362 |
+
// Order
|
1363 |
+
$order_by = '';
|
1364 |
+
if (isset($order)) {
|
1365 |
+
$order = explode(',', $order);
|
1366 |
+
foreach ($order as $order_item) {
|
1367 |
+
$order_item = explode(' ', $order_item);
|
1368 |
+
if (2 == count($order_item)) {
|
1369 |
+
if (in_array($order_item[0], array('url_id', 'scan_id', 'status', 'created_at', 'started_at'))) {
|
1370 |
+
$order_item[1] = strtoupper($order_item[1]);
|
1371 |
+
if ('ASC' == $order_item[1] || 'DESC' == $order_item[1])
|
1372 |
+
$order_by .= (empty($order_by)? ' ORDER BY ' : $order_by.', ').$order_item[0].' '.$order_item[1];
|
1373 |
+
}
|
1374 |
+
}
|
1375 |
+
}
|
1376 |
+
}
|
1377 |
+
|
1378 |
+
// Limit
|
1379 |
+
$limit = '';
|
1380 |
+
if (isset($limit_rows)) {
|
1381 |
+
$limit_rows = (int) $limit_rows;
|
1382 |
+
if (!empty($limit_rows))
|
1383 |
+
$limit = ' LIMIT '.(isset($limit_base)? (int) $limit_base.', ' : '').$limit_rows;
|
1384 |
+
}
|
1385 |
+
|
1386 |
+
// Perform query
|
1387 |
+
$rows = $wpdb->get_results('SELECT '.(isset($no_cache)? 'SQL_NO_CACHE ' : '').'* FROM '.$wpdb->prefix.'wplnst_urls_status WHERE '.$where.$order_by.$limit);
|
1388 |
+
|
1389 |
+
// Done
|
1390 |
+
return (empty($rows) || !is_array($rows))? false : $rows;
|
1391 |
+
}
|
1392 |
+
|
1393 |
+
|
1394 |
+
|
1395 |
+
/**
|
1396 |
+
* New URL status record
|
1397 |
+
*/
|
1398 |
+
public function new_scan_url_status($url_id, $scan_id, $insert) {
|
1399 |
+
|
1400 |
+
// Globals
|
1401 |
+
global $wpdb;
|
1402 |
+
|
1403 |
+
// Add new scan status
|
1404 |
+
return $wpdb->query($wpdb->prepare('INSERT IGNORE INTO '.$wpdb->prefix.'wplnst_urls_status SET url_id = %d, scan_id = %d, phase = %s, created_at = %s', $url_id, $scan_id, $phase, current_time('mysql', true)));
|
1405 |
+
}
|
1406 |
+
|
1407 |
+
|
1408 |
+
|
1409 |
+
/**
|
1410 |
+
* Insert new URL status record
|
1411 |
+
*/
|
1412 |
+
public function add_scan_url_status($url_id, $scan_id, $phase) {
|
1413 |
+
|
1414 |
+
// Globals
|
1415 |
+
global $wpdb;
|
1416 |
+
|
1417 |
+
// Add new scan status
|
1418 |
+
return $wpdb->query($wpdb->prepare('INSERT IGNORE INTO '.$wpdb->prefix.'wplnst_urls_status SET url_id = %d, scan_id = %d, phase = %s, created_at = %s', $url_id, $scan_id, $phase, current_time('mysql', true)));
|
1419 |
+
}
|
1420 |
+
|
1421 |
+
|
1422 |
+
|
1423 |
+
/**
|
1424 |
+
* Update a URL status phase
|
1425 |
+
*/
|
1426 |
+
public function update_scan_url_status($url_id, $scan_id, $update) {
|
1427 |
+
|
1428 |
+
// Globals
|
1429 |
+
global $wpdb;
|
1430 |
+
|
1431 |
+
// Update play value
|
1432 |
+
return $wpdb->update($wpdb->prefix.'wplnst_urls_status', $update, array('url_id' => $url_id, 'scan_id' => $scan_id));
|
1433 |
+
}
|
1434 |
+
|
1435 |
+
|
1436 |
+
|
1437 |
+
/**
|
1438 |
+
* Remove URL status record
|
1439 |
+
*/
|
1440 |
+
public function remove_scan_url_status($url_id, $scan_id) {
|
1441 |
+
|
1442 |
+
// Globals
|
1443 |
+
global $wpdb;
|
1444 |
+
|
1445 |
+
// Remove record
|
1446 |
+
return $wpdb->query($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_urls_status WHERE url_id = %d AND scan_id = %d LIMIT 1', $url_id, $scan_id));
|
1447 |
+
}
|
1448 |
+
|
1449 |
+
|
1450 |
+
|
1451 |
+
/**
|
1452 |
+
* Remove discard URL status and locations
|
1453 |
+
*/
|
1454 |
+
public function remove_scan_discard_urls($scan_id) {
|
1455 |
+
|
1456 |
+
// Globals
|
1457 |
+
global $wpdb;
|
1458 |
+
|
1459 |
+
// Remove locations
|
1460 |
+
$wpdb->query($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_urls_locations WHERE scan_id = %d AND url_id IN (SELECT url_id FROM '.$wpdb->prefix.'wplnst_urls_status WHERE scan_id = %d AND phase = "discard")', $scan_id, $scan_id));
|
1461 |
+
|
1462 |
+
// Remove URL status
|
1463 |
+
$wpdb->query($wpdb->prepare('DELETE FROM '.$wpdb->prefix.'wplnst_urls_status WHERE scan_id = %d AND phase = "discard"', $scan_id));
|
1464 |
+
}
|
1465 |
+
|
1466 |
+
|
1467 |
+
|
1468 |
+
// Combined results from scans, urls, status and locations
|
1469 |
+
// ---------------------------------------------------------------------------------------------------
|
1470 |
+
|
1471 |
+
|
1472 |
+
|
1473 |
+
/**
|
1474 |
+
* Retrieve URL request headers
|
1475 |
+
*/
|
1476 |
+
public function get_scan_result_headers($scan_id, $url_id) {
|
1477 |
+
|
1478 |
+
// Globals
|
1479 |
+
global $wpdb;
|
1480 |
+
|
1481 |
+
// Retrieve headers
|
1482 |
+
return $wpdb->get_row($wpdb->prepare('SELECT headers, headers_request, request_at, total_time, total_bytes FROM '.$wpdb->prefix.'wplnst_urls_status WHERE url_id = %d AND scan_id = %d', $url_id, $scan_id));
|
1483 |
+
}
|
1484 |
+
|
1485 |
+
|
1486 |
+
|
1487 |
+
/**
|
1488 |
+
* Retrieve scan results
|
1489 |
+
*/
|
1490 |
+
public function get_scan_results($args) {
|
1491 |
+
|
1492 |
+
// Globals
|
1493 |
+
global $wpdb;
|
1494 |
+
|
1495 |
+
// Check arguments
|
1496 |
+
if (empty($args) || !is_array($args))
|
1497 |
+
return false;
|
1498 |
+
|
1499 |
+
// Extract parameters
|
1500 |
+
extract($args);
|
1501 |
+
|
1502 |
+
// Check scan id
|
1503 |
+
$scan_id = empty($scan_id)? 0 : (int) $scan_id;
|
1504 |
+
if (empty($scan_id))
|
1505 |
+
return false;
|
1506 |
+
|
1507 |
+
// Check page
|
1508 |
+
$paged = empty($paged)? 1 : (int) $paged;
|
1509 |
+
if (empty($paged))
|
1510 |
+
$paged = 1;
|
1511 |
+
|
1512 |
+
// Check elements per page
|
1513 |
+
$per_page = isset($per_page)? (int) $per_page : (int) get_user_option('wplnst_scan_results_per_page');
|
1514 |
+
if (empty($per_page))
|
1515 |
+
$per_page = WPLNST_Core_Types::scans_results_per_page;
|
1516 |
+
|
1517 |
+
// Prepare fields
|
1518 |
+
$fields = 'u.url_id, u.url, u.scheme, u.host, u.scope,';
|
1519 |
+
$fields .= 's.status_level, s.status_code, s.curl_errno, s.phase, s.redirect_url, s.redirect_steps, s.redirect_url_id, s.redirect_url_status, s.redirect_curl_errno, s.total_posts, s.total_comments, s.total_blogroll, s.total_time, s.total_bytes, s.rechecked, s.requests,';
|
1520 |
+
$fields .= 'l.loc_id, l.link_type, l.object_id, l.object_type, l.object_field, l.detected_at, l.anchor, l.raw_url, l.fragment, l.spaced, l.malformed, l.absolute, l.protorel, l.relative, l.nofollow, l.ignored, l.unlinked, l.modified, l.anchored, l.attributed';
|
1521 |
+
|
1522 |
+
// Prepare inner join
|
1523 |
+
$inner_join = ' INNER JOIN '.$wpdb->prefix.'wplnst_urls_status s ON u.url_id = s.url_id ';
|
1524 |
+
|
1525 |
+
// Prepare right join
|
1526 |
+
$right_join = ' RIGHT JOIN '.$wpdb->prefix.'wplnst_urls_locations l ON s.url_id = l.url_id AND s.scan_id = l.scan_id';
|
1527 |
+
|
1528 |
+
/* Prepare where */
|
1529 |
+
|
1530 |
+
// Base conditions
|
1531 |
+
$where = 's.scan_id = '.$scan_id.' AND u.url_id = s.url_id AND s.phase = "end"';
|
1532 |
+
|
1533 |
+
// Check URL id
|
1534 |
+
if (!empty($url_id)) {
|
1535 |
+
$where .= ' AND u.url_id = '.((int) $url_id);
|
1536 |
+
|
1537 |
+
// Check status level
|
1538 |
+
} elseif (isset($status_level) && false !== $status_level) {
|
1539 |
+
$where .= ' AND s.status_level = "'.esc_sql($status_level).'"';
|
1540 |
+
|
1541 |
+
// Check status code
|
1542 |
+
} elseif (isset($status_code) && false !== $status_code) {
|
1543 |
+
$where .= ' AND s.status_code = "'.esc_sql($status_code).'"';
|
1544 |
+
}
|
1545 |
+
|
1546 |
+
// Check object type
|
1547 |
+
if (isset($object_type) && false !== $object_type)
|
1548 |
+
$where .= ' AND l.object_type = "'.esc_sql($object_type).'"';
|
1549 |
+
|
1550 |
+
// Check object post type
|
1551 |
+
if (isset($object_post_type) && false !== $object_post_type)
|
1552 |
+
$where .= ' AND l.object_post_type = "'.esc_sql($object_post_type).'"';
|
1553 |
+
|
1554 |
+
// Check link type
|
1555 |
+
if (isset($link_type) && false !== $link_type)
|
1556 |
+
$where .= ' AND l.link_type = "'.esc_sql($link_type).'"';
|
1557 |
+
|
1558 |
+
// Check ignored type
|
1559 |
+
if (isset($ignored_type) && false !== $ignored_type) {
|
1560 |
+
if ('oir' == $ignored_type)
|
1561 |
+
$where .= ' AND l.ignored = 1';
|
1562 |
+
} else {
|
1563 |
+
$where .= ' AND l.ignored = 0';
|
1564 |
+
}
|
1565 |
+
|
1566 |
+
// SEO link type
|
1567 |
+
if (isset($seo_link_type) && false !== $seo_link_type)
|
1568 |
+
$where .= ' AND l.nofollow = '.(('nf' == $seo_link_type)? '1' : '0');
|
1569 |
+
|
1570 |
+
// Protocol type
|
1571 |
+
if (isset($protocol_type) && false !== $protocol_type)
|
1572 |
+
$where .= ('rel' == $protocol_type)? ' AND l.protorel = 1' : ' AND u.scheme = "'.esc_sql($protocol_type).'" AND l.protorel = 0';
|
1573 |
+
|
1574 |
+
// Special type
|
1575 |
+
if (isset($special_type) && false !== $special_type) {
|
1576 |
+
if ('rel' == $special_type) {
|
1577 |
+
$where .= ' AND l.relative = 1';
|
1578 |
+
} elseif ('abs' == $special_type) {
|
1579 |
+
$where .= ' AND l.absolute = 1';
|
1580 |
+
} elseif ('spa' == $special_type) {
|
1581 |
+
$where .= ' AND l.spaced = 1';
|
1582 |
+
} elseif ('mal' == $special_type) {
|
1583 |
+
$where .= ' AND l.malformed = 1';
|
1584 |
+
}
|
1585 |
+
}
|
1586 |
+
|
1587 |
+
// Action type
|
1588 |
+
if (isset($action_type) && false !== $action_type) {
|
1589 |
+
if ('unl' == $action_type) {
|
1590 |
+
$where .= ' AND l.unlinked = 1';
|
1591 |
+
} elseif ('mod' == $action_type) {
|
1592 |
+
$where .= ' AND (l.modified = 1 OR l.anchored = 1 OR l.attributed = 1)';
|
1593 |
+
} elseif ('umd' == $action_type) {
|
1594 |
+
$where .= ' AND l.modified = 0 AND l.anchored = 0 AND l.attributed = 0';
|
1595 |
+
} elseif ('rec' == $action_type) {
|
1596 |
+
$where .= ' AND s.rechecked = 1';
|
1597 |
+
}
|
1598 |
+
}
|
1599 |
+
|
1600 |
+
// Check destination type
|
1601 |
+
if (isset($dest_type) && false !== $dest_type && 'all' != $dest_type)
|
1602 |
+
$where .= ' AND u.scope = "'.esc_sql($dest_type).'"';
|
1603 |
+
|
1604 |
+
// Check search URL
|
1605 |
+
if (isset($search_url) && false !== $search_url && '' !== $search_url) {
|
1606 |
+
$like = esc_sql(addcslashes($search_url, '_%\\'));
|
1607 |
+
if ('r' == $search_url_type) {
|
1608 |
+
$where .= ' AND l.fragment LIKE "%'.$like.'%"';
|
1609 |
+
} else {
|
1610 |
+
$op = ('f' == $search_url_type)? ' = "'.esc_sql($search_url).'"' : ' LIKE "'.(('s' == $search_url_type || 'm' == $search_url_type)? '%' : '').$like.(('p' == $search_url_type || 'm' == $search_url_type)? '%' : '').'"';
|
1611 |
+
$where .= ' AND (u.url'.$op.' OR s.redirect_url'.$op.')';
|
1612 |
+
}
|
1613 |
+
}
|
1614 |
+
|
1615 |
+
// Check search anchor
|
1616 |
+
if (isset($search_anchor) && false !== $search_anchor && '' !== $search_anchor) {
|
1617 |
+
$op = ('f' == $search_anchor_type)? ' = "'.esc_sql($search_anchor).'"' : ' LIKE "'.(('s' == $search_anchor_type || 'm' == $search_anchor_type)? '%' : '').esc_sql(addcslashes($search_anchor, '_%\\')).(('p' == $search_anchor_type || 'm' == $search_anchor_type)? '%' : '').'"';
|
1618 |
+
$where .= ' AND l.anchor'.$op;
|
1619 |
+
}
|
1620 |
+
|
1621 |
+
// Check first order by date
|
1622 |
+
if (isset($order_type) && false !== $order_type) {
|
1623 |
+
|
1624 |
+
// Change default order
|
1625 |
+
if (in_array($order_type, array_keys(WPLNST_Core_Types::get_crawl_order()))) {
|
1626 |
+
$order_by = 'l.object_date_gmt '.(('asc' == $order_type)? 'ASC' : 'DESC');
|
1627 |
+
|
1628 |
+
// Orders
|
1629 |
+
} else {
|
1630 |
+
if ('dma' == $order_type) {
|
1631 |
+
$order_by = 'u.host ASC';
|
1632 |
+
} elseif ('dmd' == $order_type) {
|
1633 |
+
$order_by = 'u.host DESC';
|
1634 |
+
} elseif ('dta' == $order_type) {
|
1635 |
+
$order_by = 's.total_time ASC';
|
1636 |
+
} elseif ('dtd' == $order_type) {
|
1637 |
+
$order_by = 's.total_time DESC';
|
1638 |
+
} elseif ('dsa' == $order_type) {
|
1639 |
+
$order_by = 's.total_bytes ASC';
|
1640 |
+
} elseif ('dsd' == $order_type) {
|
1641 |
+
$order_by = 's.total_bytes DESC';
|
1642 |
+
}
|
1643 |
+
}
|
1644 |
+
|
1645 |
+
// Default order
|
1646 |
+
} else {
|
1647 |
+
$order_date = (isset($order_date) && in_array(strtoupper($order_date), array('ASC', 'DESC')))? strtoupper($order_date) : 'DESC';
|
1648 |
+
$order_by = 'l.object_date_gmt '.$order_date;
|
1649 |
+
}
|
1650 |
+
|
1651 |
+
|
1652 |
+
// Done
|
1653 |
+
return $this->pagination(array(
|
1654 |
+
'paged' => $paged,
|
1655 |
+
'per_page' => $per_page,
|
1656 |
+
'sql' => 'SELECT $$$fields$$$ FROM '.$wpdb->prefix.'wplnst_urls AS u'.$inner_join.$right_join.' WHERE '.$where,
|
1657 |
+
'fields' => $fields,
|
1658 |
+
'order_by' => $order_by.', l.loc_id ASC',
|
1659 |
+
'calc_rows' => wplnst_get_bsetting('mysql_calc_rows'),
|
1660 |
+
'no_cache' => true,
|
1661 |
+
));
|
1662 |
+
}
|
1663 |
+
|
1664 |
+
|
1665 |
+
|
1666 |
+
/**
|
1667 |
+
* Retrieve scan locations
|
1668 |
+
*/
|
1669 |
+
public function get_scan_locations($args) {
|
1670 |
+
|
1671 |
+
// Globals
|
1672 |
+
global $wpdb;
|
1673 |
+
|
1674 |
+
// Check arguments
|
1675 |
+
if (empty($args) || !is_array($args))
|
1676 |
+
return false;
|
1677 |
+
|
1678 |
+
// Extract parameters
|
1679 |
+
extract($args);
|
1680 |
+
|
1681 |
+
// Check scan id
|
1682 |
+
$scan_id = empty($scan_id)? false : (int) $scan_id;
|
1683 |
+
if (empty($scan_id))
|
1684 |
+
return false;
|
1685 |
+
|
1686 |
+
// Check url id
|
1687 |
+
$url_id = empty($url_id)? false : (is_array($url_id)? array_map('intval', $url_id) : (int) $url_id);
|
1688 |
+
if (empty($url_id))
|
1689 |
+
return false;
|
1690 |
+
|
1691 |
+
// URL id where
|
1692 |
+
$url_id_where = is_array($url_id)? ' IN ('.implode(', ', $url_id).')' : ' = '.$url_id;
|
1693 |
+
|
1694 |
+
// Others
|
1695 |
+
$where = '';
|
1696 |
+
|
1697 |
+
// Check object type
|
1698 |
+
if (!empty($object_type))
|
1699 |
+
$where .= ' AND object_type = "'.esc_sql($object_type).'"';
|
1700 |
+
|
1701 |
+
// Check page
|
1702 |
+
$paged = empty($paged)? 1 : (int) $paged;
|
1703 |
+
if (empty($paged))
|
1704 |
+
$paged = 1;
|
1705 |
+
|
1706 |
+
// Check elements per page
|
1707 |
+
$per_page = isset($per_page)? (int) $per_page : (int) get_user_option('wplnst_scan_locations_per_page');
|
1708 |
+
if (empty($per_page))
|
1709 |
+
$per_page = 25;
|
1710 |
+
|
1711 |
+
// Done
|
1712 |
+
return $this->pagination(array(
|
1713 |
+
'paged' => $paged,
|
1714 |
+
'per_page' => $per_page,
|
1715 |
+
'sql' => $wpdb->prepare('SELECT $$$fields$$$ FROM '.$wpdb->prefix.'wplnst_urls_locations WHERE url_id '.$url_id_where.' AND scan_id = %d '.$where, $scan_id),
|
1716 |
+
'fields' => '*',
|
1717 |
+
'order_by' => 'detected_at ASC',
|
1718 |
+
'calc_rows' => wplnst_get_bsetting('mysql_calc_rows'),
|
1719 |
+
'no_cache' => false,
|
1720 |
+
));
|
1721 |
+
}
|
1722 |
+
|
1723 |
+
|
1724 |
+
|
1725 |
+
/**
|
1726 |
+
* Retrieve single scan location
|
1727 |
+
*/
|
1728 |
+
public function get_scan_location_by_id($loc_id) {
|
1729 |
+
|
1730 |
+
// Global
|
1731 |
+
global $wpdb;
|
1732 |
+
|
1733 |
+
// Cast param
|
1734 |
+
$loc_id = (int) $loc_id;
|
1735 |
+
|
1736 |
+
// Perform query and return result
|
1737 |
+
$locations = $wpdb->get_results($wpdb->prepare('SELECT * FROM '.$wpdb->prefix.'wplnst_urls_locations WHERE loc_id = %d', $loc_id));
|
1738 |
+
return (!empty($locations) && is_array($locations) && 1 == count($locations))? $locations[0] : false;
|
1739 |
+
}
|
1740 |
+
|
1741 |
+
|
1742 |
+
|
1743 |
+
/**
|
1744 |
+
* Retrieve multiple scan locations
|
1745 |
+
*/
|
1746 |
+
public function get_scan_locations_by_ids($loc_ids) {
|
1747 |
+
|
1748 |
+
// Global
|
1749 |
+
global $wpdb;
|
1750 |
+
|
1751 |
+
// Perform query and return result
|
1752 |
+
$locations = $wpdb->get_results('SELECT * FROM '.$wpdb->prefix.'wplnst_urls_locations WHERE loc_id IN ('.implode(', ', array_map('intval', $loc_ids)).')');
|
1753 |
+
return (empty($locations) || !is_array($locations))? false : $locations;
|
1754 |
+
}
|
1755 |
+
|
1756 |
+
|
1757 |
+
|
1758 |
+
/**
|
1759 |
+
* Retrieve array info of location marks
|
1760 |
+
*/
|
1761 |
+
public function get_scan_location_marks($scan_id, $loc_id) {
|
1762 |
+
|
1763 |
+
// Global
|
1764 |
+
global $wpdb;
|
1765 |
+
|
1766 |
+
// Default
|
1767 |
+
$marks = array(
|
1768 |
+
'url' => '',
|
1769 |
+
'relative' => false,
|
1770 |
+
'absolute' => false,
|
1771 |
+
'spaced' => false,
|
1772 |
+
'malformed' => false,
|
1773 |
+
'https' => false,
|
1774 |
+
'protorel' => false,
|
1775 |
+
'redirs' => false,
|
1776 |
+
'redirs_count' => '1 redirect',
|
1777 |
+
);
|
1778 |
+
|
1779 |
+
// Retrieve row
|
1780 |
+
$row = $wpdb->get_row($wpdb->prepare('SELECT u.url, u.scheme, l.relative, l.absolute, l.spaced, l.malformed, l.protorel, s.status_level, s.redirect_url_id, s.redirect_url, s.redirect_steps FROM '.$wpdb->prefix.'wplnst_urls AS u, '.$wpdb->prefix.'wplnst_urls_locations AS l, '.$wpdb->prefix.'wplnst_urls_status AS s WHERE l.loc_id = %d AND l.scan_id = %d AND u.url_id = l.url_id AND s.url_id = l.url_id AND s.scan_id = %d LIMIT 1', $loc_id, $scan_id, $scan_id));
|
1781 |
+
if (!empty($row) && is_object($row)) {
|
1782 |
+
|
1783 |
+
// Copy URL
|
1784 |
+
$marks['url'] = esc_html($row->url);
|
1785 |
+
|
1786 |
+
// Check HTTPS
|
1787 |
+
$marks['https'] = ('https' == $row->scheme);
|
1788 |
+
|
1789 |
+
// Link form
|
1790 |
+
$marks['relative'] = (1 == $row->relative);
|
1791 |
+
$marks['absolute'] = (1 == $row->absolute);
|
1792 |
+
$marks['spaced'] = (1 == $row->spaced);
|
1793 |
+
$marks['malformed'] = (1 == $row->malformed);
|
1794 |
+
$marks['protorel'] = (1 == $row->protorel);
|
1795 |
+
|
1796 |
+
// Redirs
|
1797 |
+
$marks['redirs'] = ('3' == $row->status_level && $row->redirect_url_id > 0 && !empty($row->redirect_url));
|
1798 |
+
if ($marks['redirs']) {
|
1799 |
+
$redirs_steps = @json_decode($row->redirect_steps, true);
|
1800 |
+
if (!empty($redirs_steps) && is_array($redirs_steps) && count($redirs_steps) > 1)
|
1801 |
+
$marks['redirs_count'] = count($redirs_steps).' redirects';
|
1802 |
+
}
|
1803 |
+
}
|
1804 |
+
|
1805 |
+
// Done
|
1806 |
+
return $marks;
|
1807 |
+
}
|
1808 |
+
|
1809 |
+
|
1810 |
+
|
1811 |
+
/**
|
1812 |
+
* Execute and extract pagination data
|
1813 |
+
* - paged
|
1814 |
+
* - per_page
|
1815 |
+
* - sql
|
1816 |
+
* - fields
|
1817 |
+
* - order_by
|
1818 |
+
* - calc_rows
|
1819 |
+
* - no_cache
|
1820 |
+
*/
|
1821 |
+
public function pagination($args) {
|
1822 |
+
|
1823 |
+
// Globals
|
1824 |
+
global $wpdb;
|
1825 |
+
|
1826 |
+
// Check arguments
|
1827 |
+
if (empty($args) || !is_array($args))
|
1828 |
+
return false;
|
1829 |
+
|
1830 |
+
// Extract parameters
|
1831 |
+
extract($args);
|
1832 |
+
|
1833 |
+
// Check basic params
|
1834 |
+
if (empty($sql) || empty($fields))
|
1835 |
+
return false;
|
1836 |
+
|
1837 |
+
// Totals method and cache
|
1838 |
+
$calc_rows = !empty($calc_rows) && (true === $calc_rows);
|
1839 |
+
$no_cache = !empty($no_cache) && (true === $no_cache);
|
1840 |
+
|
1841 |
+
// Calculating offset
|
1842 |
+
$paged = empty($paged)? 1 : (int) $paged;
|
1843 |
+
$per_page = empty($per_page)? 10 : (int) $per_page;
|
1844 |
+
$offset = (int) (($paged - 1) * $per_page);
|
1845 |
+
|
1846 |
+
// Default
|
1847 |
+
$results = array(
|
1848 |
+
'paged' => $paged,
|
1849 |
+
'per_page' => $per_page,
|
1850 |
+
'total_pages' => 0,
|
1851 |
+
'rows_page' => 0,
|
1852 |
+
'rows_start' => $offset + 1,
|
1853 |
+
'rows_end' => 0,
|
1854 |
+
'total_rows' => 0,
|
1855 |
+
'calc_rows' => $calc_rows,
|
1856 |
+
'no_cache' => $no_cache,
|
1857 |
+
'rows' => array(),
|
1858 |
+
);
|
1859 |
+
|
1860 |
+
// Timer
|
1861 |
+
$time_start = microtime(true);
|
1862 |
+
|
1863 |
+
// Count rows method
|
1864 |
+
if (!$calc_rows) {
|
1865 |
+
|
1866 |
+
// Prepare COUNT sql
|
1867 |
+
$sql_count = str_replace('$$$fields$$$', 'COUNT(*)', $sql);
|
1868 |
+
if ($no_cache)
|
1869 |
+
$sql_count = str_replace('SELECT ', 'SELECT SQL_NO_CACHE ', $sql_count);
|
1870 |
+
|
1871 |
+
// Obtain totals
|
1872 |
+
$results['total_rows'] = (int) $wpdb->get_var($sql_count);
|
1873 |
+
|
1874 |
+
// Calc
|
1875 |
+
} else {
|
1876 |
+
|
1877 |
+
// Replace SELECT
|
1878 |
+
$sql = str_replace('SELECT ', 'SELECT SQL_CALC_FOUND_ROWS ', $sql);
|
1879 |
+
}
|
1880 |
+
|
1881 |
+
// Check NO CACHE
|
1882 |
+
if ($no_cache)
|
1883 |
+
$sql = str_replace('SELECT ', 'SELECT SQL_NO_CACHE ', $sql);
|
1884 |
+
|
1885 |
+
// Set fields
|
1886 |
+
$sql = str_replace('$$$fields$$$', $fields, $sql);
|
1887 |
+
|
1888 |
+
// Add ORDER and LIMIT
|
1889 |
+
$sql .= (empty($order_by)? '' : ' ORDER BY '.$order_by).' LIMIT '.$offset.', '.$per_page;
|
1890 |
+
//echo $sql;
|
1891 |
+
// Perform query
|
1892 |
+
$results['rows'] = $wpdb->get_results($sql);
|
1893 |
+
|
1894 |
+
// Calc rows
|
1895 |
+
if ($calc_rows)
|
1896 |
+
$results['total_rows'] = (int) $wpdb->get_var('SELECT FOUND_ROWS()');
|
1897 |
+
|
1898 |
+
// End timer
|
1899 |
+
$results['time'] = microtime(true) - $time_start;
|
1900 |
+
//echo '<br />'.$results['time'].' s';
|
1901 |
+
// Total pages
|
1902 |
+
$results['total_pages'] = empty($results['total_rows'])? 0 : ceil($results['total_rows'] / $per_page);
|
1903 |
+
|
1904 |
+
// Queried rows
|
1905 |
+
if (!empty($results['rows']) && is_array($results['rows'])) {
|
1906 |
+
|
1907 |
+
// Total rows in page
|
1908 |
+
$results['rows_page'] = count($results['rows']);
|
1909 |
+
$results['rows_end'] = $results['rows_start'] + $results['rows_page'] - 1;
|
1910 |
+
}
|
1911 |
+
|
1912 |
+
// Done
|
1913 |
+
return (object) $results;
|
1914 |
+
}
|
1915 |
+
|
1916 |
+
|
1917 |
+
|
1918 |
+
}
|
core/scheme.php
ADDED
@@ -0,0 +1,288 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Scheme class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Scheme {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Tables used by this plugin
|
15 |
+
*/
|
16 |
+
public static function get_tables() {
|
17 |
+
return array(
|
18 |
+
'urls',
|
19 |
+
'urls_locations',
|
20 |
+
'urls_locations_att',
|
21 |
+
'urls_status',
|
22 |
+
'scans',
|
23 |
+
'scans_objects',
|
24 |
+
);
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Remove all plugin tables
|
31 |
+
*/
|
32 |
+
public static function drop_tables() {
|
33 |
+
|
34 |
+
// Globals
|
35 |
+
global $wpdb;
|
36 |
+
|
37 |
+
// Plugin tables
|
38 |
+
$tables = self::get_tables();
|
39 |
+
|
40 |
+
// Remove each one
|
41 |
+
foreach ($tables as $name)
|
42 |
+
$wpdb->query('DROP TABLE '.$wpdb->prefix.'wplnst_'.esc_sql($name));
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Check plugin custom tables
|
49 |
+
*/
|
50 |
+
public static function check_tables() {
|
51 |
+
|
52 |
+
// Globals
|
53 |
+
global $wpdb;
|
54 |
+
|
55 |
+
// Initialize
|
56 |
+
$create = array();
|
57 |
+
|
58 |
+
// Plugin tables
|
59 |
+
$tables = self::get_tables();
|
60 |
+
|
61 |
+
// Check each table
|
62 |
+
foreach ($tables as $name) {
|
63 |
+
$result = $wpdb->get_var('SHOW TABLES LIKE "'.$wpdb->prefix.'wplnst_'.esc_sql($name).'"');
|
64 |
+
if (empty($result))
|
65 |
+
$create[] = $name;
|
66 |
+
}
|
67 |
+
|
68 |
+
// Done
|
69 |
+
return empty($create)? false : $create;
|
70 |
+
}
|
71 |
+
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Create custom plugin tables
|
76 |
+
*/
|
77 |
+
public static function create_tables($tables = array()) {
|
78 |
+
|
79 |
+
// Globals
|
80 |
+
global $wpdb;
|
81 |
+
|
82 |
+
// Compose charset
|
83 |
+
$charset = (empty($wpdb->charset)? '' : ' DEFAULT CHARACTER SET '.$wpdb->charset).(empty($wpdb->collate)? '' : ' COLLATE '.$wpdb->collate);
|
84 |
+
|
85 |
+
// URLs table
|
86 |
+
if (in_array('urls', $tables)) {
|
87 |
+
$wpdb->query('CREATE TABLE IF NOT EXISTS `'.$wpdb->prefix.'wplnst_urls` (
|
88 |
+
`url_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
89 |
+
`url` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT "",
|
90 |
+
`hash` VARCHAR(64) NOT NULL DEFAULT "",
|
91 |
+
`scheme` VARCHAR(20) NOT NULL DEFAULT "",
|
92 |
+
`host` VARCHAR(255) NOT NULL DEFAULT "",
|
93 |
+
`path` VARCHAR(255) NOT NULL DEFAULT "",
|
94 |
+
`query` VARCHAR(255) NOT NULL DEFAULT "",
|
95 |
+
`scope` VARCHAR(10) NOT NULL DEFAULT "",
|
96 |
+
`created_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
97 |
+
`last_scan_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
98 |
+
`last_status_level` VARCHAR(1) NOT NULL DEFAULT "",
|
99 |
+
`last_status_code` VARCHAR(3) NOT NULL DEFAULT "",
|
100 |
+
`last_curl_errno` INT(3) UNSIGNED NOT NULL DEFAULT 0,
|
101 |
+
`last_request_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
102 |
+
PRIMARY KEY (`url_id`),
|
103 |
+
KEY `url` (`url`(255)),
|
104 |
+
UNIQUE KEY `hash` (`hash`),
|
105 |
+
KEY `scheme` (`scheme`),
|
106 |
+
KEY `host` (`host`),
|
107 |
+
KEY `path` (`path`),
|
108 |
+
KEY `query` (`query`),
|
109 |
+
KEY `scope` (`scope`),
|
110 |
+
KEY `last_scan_id` (`last_scan_id`),
|
111 |
+
KEY `last_status_level` (`last_status_level`),
|
112 |
+
KEY `last_status_code` (`last_status_code`),
|
113 |
+
KEY `last_curl_errno` (`last_curl_errno`),
|
114 |
+
KEY `last_request_at` (`last_request_at`)
|
115 |
+
)'.$charset);
|
116 |
+
}
|
117 |
+
|
118 |
+
// URLs and locations relationship table
|
119 |
+
if (in_array('urls_locations', $tables)) {
|
120 |
+
$wpdb->query('CREATE TABLE IF NOT EXISTS `'.$wpdb->prefix.'wplnst_urls_locations` (
|
121 |
+
`loc_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
122 |
+
`url_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
123 |
+
`scan_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
124 |
+
`link_type` VARCHAR(25) NOT NULL DEFAULT "",
|
125 |
+
`object_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
126 |
+
`object_type` VARCHAR(50) NOT NULL DEFAULT "",
|
127 |
+
`object_post_type` VARCHAR(20) NOT NULL DEFAULT "",
|
128 |
+
`object_field` VARCHAR(100) NOT NULL DEFAULT "",
|
129 |
+
`object_date_gmt` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
130 |
+
`detected_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
131 |
+
`chunk` TEXT NOT NULL DEFAULT "",
|
132 |
+
`anchor` TEXT NOT NULL DEFAULT "",
|
133 |
+
`raw_url` TEXT NOT NULL DEFAULT "",
|
134 |
+
`fragment` TEXT NOT NULL DEFAULT "",
|
135 |
+
`spaced` TINYINT(1) NOT NULL DEFAULT 0,
|
136 |
+
`malformed` TINYINT(1) NOT NULL DEFAULT 0,
|
137 |
+
`absolute` TINYINT(1) NOT NULL DEFAULT 0,
|
138 |
+
`protorel` TINYINT(1) NOT NULL DEFAULT 0,
|
139 |
+
`relative` TINYINT(1) NOT NULL DEFAULT 0,
|
140 |
+
`nofollow` TINYINT(1) NOT NULL DEFAULT 0,
|
141 |
+
`ignored` TINYINT(1) NOT NULL DEFAULT 0,
|
142 |
+
`unlinked` TINYINT(1) NOT NULL DEFAULT 0,
|
143 |
+
`modified` TINYINT(1) NOT NULL DEFAULT 0,
|
144 |
+
`anchored` TINYINT(1) NOT NULL DEFAULT 0,
|
145 |
+
`attributed` TINYINT(1) NOT NULL DEFAULT 0,
|
146 |
+
PRIMARY KEY (`loc_id`),
|
147 |
+
KEY `url_id` (`url_id`),
|
148 |
+
KEY `scan_id` (`scan_id`),
|
149 |
+
KEY `link_type` (`link_type`),
|
150 |
+
KEY `object_id` (`object_id`),
|
151 |
+
KEY `object_type` (`object_type`),
|
152 |
+
KEY `object_date_gmt` (`object_date_gmt`),
|
153 |
+
KEY `anchor` (`anchor`(255)),
|
154 |
+
KEY `spaced` (`spaced`),
|
155 |
+
KEY `malformed` (`malformed`),
|
156 |
+
KEY `absolute` (`absolute`),
|
157 |
+
KEY `protorel` (`protorel`),
|
158 |
+
KEY `relative` (`relative`),
|
159 |
+
KEY `nofollow` (`nofollow`),
|
160 |
+
KEY `ignored` (`ignored`),
|
161 |
+
KEY `unlinked` (`unlinked`),
|
162 |
+
KEY `modified` (`modified`),
|
163 |
+
KEY `anchored` (`anchored`),
|
164 |
+
KEY `attributed` (`attributed`)
|
165 |
+
)'.$charset);
|
166 |
+
}
|
167 |
+
|
168 |
+
// URLs locations and attributes relationship table
|
169 |
+
if (in_array('urls_locations_att', $tables)) {
|
170 |
+
$wpdb->query('CREATE TABLE IF NOT EXISTS `'.$wpdb->prefix.'wplnst_urls_locations_att` (
|
171 |
+
`att_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
172 |
+
`loc_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
173 |
+
`scan_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
174 |
+
`attribute` VARCHAR(255) NOT NULL DEFAULT "",
|
175 |
+
`value` VARCHAR(255) NOT NULL DEFAULT "",
|
176 |
+
PRIMARY KEY (`att_id`),
|
177 |
+
KEY `loc_id` (`loc_id`),
|
178 |
+
KEY `scan_id` (`scan_id`),
|
179 |
+
KEY `attribute` (`attribute`),
|
180 |
+
KEY `value` (`value`)
|
181 |
+
)'.$charset);
|
182 |
+
}
|
183 |
+
|
184 |
+
// URLs status and scans relationship table
|
185 |
+
if (in_array('urls_status', $tables)) {
|
186 |
+
$wpdb->query('CREATE TABLE IF NOT EXISTS `'.$wpdb->prefix.'wplnst_urls_status` (
|
187 |
+
`url_id` BIGINT(20) UNSIGNED NOT NULL,
|
188 |
+
`scan_id` BIGINT(20) UNSIGNED NOT NULL,
|
189 |
+
`status_level` VARCHAR(1) NOT NULL DEFAULT "",
|
190 |
+
`status_code` VARCHAR(3) NOT NULL DEFAULT "",
|
191 |
+
`curl_errno` INT(3) UNSIGNED NOT NULL DEFAULT 0,
|
192 |
+
`redirect_url` TEXT NOT NULL DEFAULT "",
|
193 |
+
`redirect_steps` TEXT NOT NULL DEFAULT "",
|
194 |
+
`redirect_url_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
195 |
+
`redirect_url_status` VARCHAR(3) NOT NULL DEFAULT "",
|
196 |
+
`redirect_curl_errno` INT(3) UNSIGNED NOT NULL DEFAULT 0,
|
197 |
+
`headers` TEXT NOT NULL DEFAULT "",
|
198 |
+
`headers_request` TEXT NOT NULL DEFAULT "",
|
199 |
+
`body` TEXT NOT NULL DEFAULT "",
|
200 |
+
`phase` VARCHAR(20) NOT NULL DEFAULT "",
|
201 |
+
`created_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
202 |
+
`started_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
203 |
+
`request_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
204 |
+
`total_objects` INT(9) UNSIGNED NOT NULL DEFAULT 0,
|
205 |
+
`total_posts` INT(9) UNSIGNED NOT NULL DEFAULT 0,
|
206 |
+
`total_comments` INT(9) UNSIGNED NOT NULL DEFAULT 0,
|
207 |
+
`total_blogroll` INT(9) UNSIGNED NOT NULL DEFAULT 0,
|
208 |
+
`total_time` DECIMAL(3,3) UNSIGNED NOT NULL DEFAULT 0,
|
209 |
+
`total_bytes` BIGINT(20) UNSIGNED NOT NULL,
|
210 |
+
`requests` INT(4) UNSIGNED NOT NULL DEFAULT 0,
|
211 |
+
`rechecked` TINYINT(1) NOT NULL DEFAULT 0,
|
212 |
+
PRIMARY KEY (`url_id`, `scan_id`),
|
213 |
+
KEY `url_id` (`url_id`),
|
214 |
+
KEY `scan_id` (`scan_id`),
|
215 |
+
KEY `status_level` (`status_level`),
|
216 |
+
KEY `status_code` (`status_code`),
|
217 |
+
KEY `curl_errno` (`curl_errno`),
|
218 |
+
KEY `redirect_url_id` (`redirect_url_id`),
|
219 |
+
KEY `redirect_url_status` (`redirect_url_status`),
|
220 |
+
KEY `phase` (`phase`),
|
221 |
+
KEY `total_objects` (`total_objects`),
|
222 |
+
KEY `total_posts` (`total_posts`),
|
223 |
+
KEY `total_comments` (`total_comments`),
|
224 |
+
KEY `total_blogroll` (`total_blogroll`),
|
225 |
+
KEY `total_time` (`total_time`),
|
226 |
+
KEY `total_bytes` (`total_bytes`),
|
227 |
+
KEY `rechecked` (`rechecked`)
|
228 |
+
)'.$charset);
|
229 |
+
}
|
230 |
+
|
231 |
+
// Scans table
|
232 |
+
if (in_array('scans', $tables)) {
|
233 |
+
$wpdb->query('CREATE TABLE IF NOT EXISTS `'.$wpdb->prefix.'wplnst_scans` (
|
234 |
+
`scan_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
235 |
+
`type` VARCHAR(20) NOT NULL DEFAULT "scan",
|
236 |
+
`name` VARCHAR(255) NOT NULL DEFAULT "",
|
237 |
+
`status` VARCHAR(20) NOT NULL DEFAULT "",
|
238 |
+
`ready` TINYINT(1) NOT NULL DEFAULT 0,
|
239 |
+
`hash` VARCHAR(32) NOT NULL DEFAULT "",
|
240 |
+
`created_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
241 |
+
`modified_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
242 |
+
`modified_by` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
243 |
+
`started_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
244 |
+
`enqueued_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
245 |
+
`stopped_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
246 |
+
`continued_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
247 |
+
`finished_at` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
248 |
+
`config` TEXT NOT NULL DEFAULT "",
|
249 |
+
`summary` TEXT NOT NULL DEFAULT "",
|
250 |
+
`trace` TEXT NOT NULL DEFAULT "",
|
251 |
+
`threads` TEXT NOT NULL DEFAULT "",
|
252 |
+
`max_threads` INT(3) UNSIGNED NOT NULL DEFAULT 0,
|
253 |
+
`connect_timeout` INT(4) UNSIGNED NOT NULL DEFAULT 0,
|
254 |
+
`request_timeout` INT(4) UNSIGNED NOT NULL DEFAULT 0,
|
255 |
+
PRIMARY KEY (`scan_id`),
|
256 |
+
KEY `type` (`type`),
|
257 |
+
KEY `name` (`name`),
|
258 |
+
KEY `status` (`status`),
|
259 |
+
UNIQUE KEY `hash` (`hash`),
|
260 |
+
KEY `config` (`config`(255))
|
261 |
+
)'.$charset);
|
262 |
+
}
|
263 |
+
|
264 |
+
// Scans objects
|
265 |
+
if (in_array('scans_objects', $tables)) {
|
266 |
+
$wpdb->query('CREATE TABLE IF NOT EXISTS `'.$wpdb->prefix.'wplnst_scans_objects` (
|
267 |
+
`scan_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
268 |
+
`object_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
269 |
+
`object_type` VARCHAR(50) NOT NULL DEFAULT "",
|
270 |
+
`object_date_gmt` DATETIME NOT NULL DEFAULT "0000-00-00 00:00:00",
|
271 |
+
PRIMARY KEY (`scan_id`, `object_id`, `object_type`),
|
272 |
+
KEY `scan_id` (`scan_id`),
|
273 |
+
KEY `object_type` (`object_type`),
|
274 |
+
KEY `object_date_gmt` (`object_date_gmt`)
|
275 |
+
)'.$charset);
|
276 |
+
}
|
277 |
+
}
|
278 |
+
|
279 |
+
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Upgrade table schemes
|
283 |
+
*/
|
284 |
+
public static function upgrade() {}
|
285 |
+
|
286 |
+
|
287 |
+
|
288 |
+
}
|
core/settings.php
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Settings class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Settings {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Return a numeric setting
|
15 |
+
*/
|
16 |
+
public static function get_nsetting($name, $value = 0) {
|
17 |
+
|
18 |
+
// Load settings
|
19 |
+
static $settings;
|
20 |
+
if (!isset($settings))
|
21 |
+
$settings = self::get_default_nsettings();
|
22 |
+
|
23 |
+
// Check available
|
24 |
+
if (!isset($settings[$name]))
|
25 |
+
return false;
|
26 |
+
|
27 |
+
// Check boundary
|
28 |
+
if ('min' === $value || 'max' === $value)
|
29 |
+
return $settings[$name][$value];
|
30 |
+
|
31 |
+
// Check input value
|
32 |
+
$value = (int) $value;
|
33 |
+
if (empty($value))
|
34 |
+
$value = (int) get_option('wplnst_'.$name);
|
35 |
+
|
36 |
+
// Check return value
|
37 |
+
$setting = $settings[$name];
|
38 |
+
return (empty($value) || $value < $setting['min'] || $value > $setting['max'])? $setting['default'] : $value;
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Return an array of default numeric settings
|
45 |
+
*/
|
46 |
+
private static function get_default_nsettings() {
|
47 |
+
return array(
|
48 |
+
'max_threads' => array('min' => 1, 'max' => 999, 'default' => 1),
|
49 |
+
'max_scans' => array('min' => 1, 'max' => 999, 'default' => 1),
|
50 |
+
'max_pack' => array('min' => 1, 'max' => 999, 'default' => 25),
|
51 |
+
'max_requests' => array('min' => 1, 'max' => 999, 'default' => 3),
|
52 |
+
'max_redirs' => array('min' => 1, 'max' => 999, 'default' => 5),
|
53 |
+
'max_download' => array('min' => 32, 'max' => 10240, 'default' => 2048),
|
54 |
+
'connect_timeout' => array('min' => 1, 'max' => 999, 'default' => 10),
|
55 |
+
'request_timeout' => array('min' => 1, 'max' => 999, 'default' => 30),
|
56 |
+
'extra_timeout' => array('min' => 5, 'max' => 999, 'default' => 5),
|
57 |
+
'crawler_alive' => array('min' => 3, 'max' => 999, 'default' => 30),
|
58 |
+
'total_objects' => array('min' => 30, 'max' => 300, 'default' => 120),
|
59 |
+
'summary_status' => array('min' => 10, 'max' => 999, 'default' => 30),
|
60 |
+
'summary_phases' => array('min' => 10, 'max' => 999, 'default' => 30),
|
61 |
+
'summary_objects' => array('min' => 10, 'max' => 999, 'default' => 30),
|
62 |
+
'recursion_limit' => array('min' => 10, 'max' => 99999, 'default' => 99),
|
63 |
+
);
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Return a boolean setting
|
70 |
+
*/
|
71 |
+
public static function get_bsetting($name, $use_default_if_empty = true) {
|
72 |
+
|
73 |
+
// Check stored value
|
74 |
+
$value = ''.get_option('wplnst_'.$name);
|
75 |
+
if ('' !== $value || !$use_default_if_empty)
|
76 |
+
return ('on' == $value);
|
77 |
+
|
78 |
+
// Load settings
|
79 |
+
static $settings;
|
80 |
+
if (!isset($settings))
|
81 |
+
$settings = self::get_default_bsettings();
|
82 |
+
|
83 |
+
// Return default setting or false
|
84 |
+
return isset($settings[$name])? ('on' == $settings[$name]) : false;
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Return an array of default boolean settings
|
91 |
+
*/
|
92 |
+
private static function get_default_bsettings() {
|
93 |
+
return array(
|
94 |
+
'mysql_calc_rows' => 'off',
|
95 |
+
'uninstall_data' => 'off',
|
96 |
+
);
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Return a text setting
|
103 |
+
*/
|
104 |
+
public static function get_tsetting($name, $use_default_if_empty = true) {
|
105 |
+
|
106 |
+
// Check stored value
|
107 |
+
$value = ''.get_option('wplnst_'.$name);
|
108 |
+
if ('' !== $value || !$use_default_if_empty)
|
109 |
+
return $value;
|
110 |
+
|
111 |
+
// Load settings
|
112 |
+
static $settings;
|
113 |
+
if (!isset($settings))
|
114 |
+
$settings = self::get_default_tsettings();
|
115 |
+
|
116 |
+
// Return default setting or false
|
117 |
+
return isset($settings[$name])? $settings[$name] : false;
|
118 |
+
}
|
119 |
+
|
120 |
+
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Return an array of default string settings
|
124 |
+
*/
|
125 |
+
private static function get_default_tsettings() {
|
126 |
+
return array(
|
127 |
+
'user_agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0',
|
128 |
+
);
|
129 |
+
}
|
130 |
+
|
131 |
+
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Remove all plugin options
|
135 |
+
*/
|
136 |
+
public static function delete_all_options() {
|
137 |
+
|
138 |
+
// Collect numeric, text, and crawler options
|
139 |
+
$options = array_merge(
|
140 |
+
array_keys(self::get_default_nsettings()),
|
141 |
+
array_keys(self::get_default_tsettings()),
|
142 |
+
array_keys(self::get_default_bsettings()),
|
143 |
+
self::get_crawler_options_names()
|
144 |
+
);
|
145 |
+
|
146 |
+
// Remove all plugin settings
|
147 |
+
foreach ($options as $name)
|
148 |
+
delete_option('wplnst_'.$name);
|
149 |
+
}
|
150 |
+
|
151 |
+
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Remove custom options
|
155 |
+
*/
|
156 |
+
public static function delete_crawler_options() {
|
157 |
+
$options = self::get_crawler_options_names();
|
158 |
+
foreach ($options as $name)
|
159 |
+
delete_option('wplnst_'.$name);
|
160 |
+
}
|
161 |
+
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Retrive custom options names
|
166 |
+
*/
|
167 |
+
private static function get_crawler_options_names() {
|
168 |
+
return array('crawler_timestamp', 'crawler_slug', 'crawler_notifications');
|
169 |
+
}
|
170 |
+
|
171 |
+
|
172 |
+
|
173 |
+
}
|
core/status.php
ADDED
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Status class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Status {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Input data
|
15 |
+
*/
|
16 |
+
public $data;
|
17 |
+
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Pairs name/value
|
22 |
+
*/
|
23 |
+
public $headers = array();
|
24 |
+
public $headers_request = array();
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Status code, description and level
|
30 |
+
*/
|
31 |
+
public $code = 0;
|
32 |
+
public $code_desc = '';
|
33 |
+
public $level = 0;
|
34 |
+
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Redirect URL
|
39 |
+
*/
|
40 |
+
public $redirect_url = '';
|
41 |
+
public $redirect_url_id = 0;
|
42 |
+
public $redirect_url_level = 0;
|
43 |
+
public $redirect_url_status = '';
|
44 |
+
public $redirect_url_status_desc = '';
|
45 |
+
public $redirect_curl_errno = 0;
|
46 |
+
public $redirect_curl_err_title = '';
|
47 |
+
public $redirect_curl_err_desc = '';
|
48 |
+
public $redirect_steps = '';
|
49 |
+
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* cURL error number and desc
|
54 |
+
*/
|
55 |
+
public $curl_errno = 0;
|
56 |
+
public $curl_err_title = '';
|
57 |
+
public $curl_err_desc = '';
|
58 |
+
|
59 |
+
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Exact request timestamp
|
63 |
+
*/
|
64 |
+
public $timestamp = 0;
|
65 |
+
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Timestamp to datetime
|
70 |
+
*/
|
71 |
+
public $request_at = '0000-00-00 00:00:00';
|
72 |
+
|
73 |
+
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Total request time
|
77 |
+
*/
|
78 |
+
public $total_time = 0;
|
79 |
+
|
80 |
+
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Total bytes and size
|
84 |
+
*/
|
85 |
+
public $total_size = '';
|
86 |
+
public $total_bytes = 0;
|
87 |
+
|
88 |
+
|
89 |
+
|
90 |
+
// Initialization
|
91 |
+
// ---------------------------------------------------------------------------------------------------
|
92 |
+
|
93 |
+
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Constructor
|
97 |
+
*/
|
98 |
+
public function __construct($data = null) {
|
99 |
+
if (!empty($data) && is_array($data))
|
100 |
+
$this->process_data($data);
|
101 |
+
}
|
102 |
+
|
103 |
+
|
104 |
+
|
105 |
+
// Data extract and validation
|
106 |
+
// ---------------------------------------------------------------------------------------------------
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Process request data
|
112 |
+
*/
|
113 |
+
public function process_data($data) {
|
114 |
+
|
115 |
+
// Copy var
|
116 |
+
$this->data = $data;
|
117 |
+
|
118 |
+
// Process headers
|
119 |
+
if (!empty($data['headers']))
|
120 |
+
$this->extract_headers($data['headers']);
|
121 |
+
|
122 |
+
// Process request headers
|
123 |
+
if (!empty($data['headers_request']))
|
124 |
+
$this->extract_headers_request($data['headers_request']);
|
125 |
+
|
126 |
+
// Check cURL error
|
127 |
+
if (!empty($data['curl_errno']))
|
128 |
+
$this->curl_errno = (int) $data['curl_errno'];
|
129 |
+
|
130 |
+
// Timestamp and DateTime
|
131 |
+
if (!empty($data['timestamp'])) {
|
132 |
+
$this->timestamp = (int) $data['timestamp'];
|
133 |
+
if (!empty($this->timestamp) && false !== ($datetime = @gmdate('Y-m-d H:i:s', $this->timestamp)))
|
134 |
+
$this->request_at = $datetime;
|
135 |
+
}
|
136 |
+
|
137 |
+
// Total time
|
138 |
+
if (!empty($data['total_time']))
|
139 |
+
$this->total_time = (float) $data['total_time'];
|
140 |
+
|
141 |
+
// Total bytes
|
142 |
+
if (!empty($data['total_bytes']))
|
143 |
+
$this->total_bytes = (int) $data['total_bytes'];
|
144 |
+
}
|
145 |
+
|
146 |
+
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Parse and extract headers data
|
150 |
+
*/
|
151 |
+
private function extract_headers($headers) {
|
152 |
+
|
153 |
+
// Parse headers
|
154 |
+
$headers_raw = explode("\n", str_replace("\n\r", "\n", $headers));
|
155 |
+
foreach ($headers_raw as $header) {
|
156 |
+
|
157 |
+
// Clean line
|
158 |
+
$header = trim($header);
|
159 |
+
if (empty($header))
|
160 |
+
continue;
|
161 |
+
|
162 |
+
// Check redirection in status code
|
163 |
+
if (!isset($status_code) && 0 === stripos($header, 'HTTP/')) {
|
164 |
+
$line = trim(preg_replace('/\s+/', ' ', $header));
|
165 |
+
$line = explode(' ', $line);
|
166 |
+
if (count($line) > 1) {
|
167 |
+
$status_code = (int) mb_substr(trim($line[1]), 0, 3);
|
168 |
+
$this->headers['status'] = $header;
|
169 |
+
}
|
170 |
+
|
171 |
+
// Parse other headers
|
172 |
+
} elseif (false !== ($pos = strpos($header, ':')) && $pos > 0) {
|
173 |
+
$name = trim(mb_substr($header, 0, $pos));
|
174 |
+
$this->headers[$name] = trim(mb_substr($header, $pos + 1));
|
175 |
+
if ('location' == strtolower($name))
|
176 |
+
$this->redirect_url = $this->headers[$name];
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
// Check status
|
181 |
+
if (isset($status_code)) {
|
182 |
+
$this->code = $status_code;
|
183 |
+
$this->level = (int) mb_substr($status_code, 0 , 1);
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Parse and extract request headers data
|
191 |
+
*/
|
192 |
+
private function extract_headers_request($headers) {
|
193 |
+
|
194 |
+
// Parse headers
|
195 |
+
$headers_raw = explode("\n", str_replace("\n\r", "\n", $headers));
|
196 |
+
foreach ($headers_raw as $header) {
|
197 |
+
|
198 |
+
// Check GET method
|
199 |
+
if (0 === strpos($header, 'GET ')) {
|
200 |
+
$this->headers_request['GET'] = mb_substr($header, 4);
|
201 |
+
|
202 |
+
// Check property
|
203 |
+
} elseif ((false !== ($pos = strpos($header, ':')) && $pos > 0)) {
|
204 |
+
$name = trim(mb_substr($header, 0, $pos));
|
205 |
+
$this->headers_request[$name] = trim(mb_substr($header, $pos + 1));
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
|
211 |
+
|
212 |
+
}
|
core/text.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Text class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Text {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Translate on the fly (not stored) by name
|
15 |
+
*/
|
16 |
+
public static function get_text($name) {
|
17 |
+
|
18 |
+
// Static
|
19 |
+
static $names = array();
|
20 |
+
|
21 |
+
// Check cache
|
22 |
+
if (isset($names[$name]))
|
23 |
+
return $names[$name];
|
24 |
+
|
25 |
+
// Initialize
|
26 |
+
$text = false;
|
27 |
+
|
28 |
+
// Check key
|
29 |
+
switch($name) {
|
30 |
+
|
31 |
+
case 'scans':
|
32 |
+
$text = __('Scans', 'wplnst');
|
33 |
+
break;
|
34 |
+
|
35 |
+
case 'scan_new':
|
36 |
+
$text = __('New scan', 'wplnst');
|
37 |
+
break;
|
38 |
+
|
39 |
+
case 'scan_new_add':
|
40 |
+
$text = __('Add new scan', 'wplnst');
|
41 |
+
break;
|
42 |
+
|
43 |
+
case 'scan_edit':
|
44 |
+
$text = __('Edit scan', 'wplnst');
|
45 |
+
break;
|
46 |
+
|
47 |
+
case 'scan_delete':
|
48 |
+
$text = __('Delete scan', 'wplnst');
|
49 |
+
break;
|
50 |
+
|
51 |
+
case 'scan_delete_confirm':
|
52 |
+
$text = __('Do you want to remove this scan?', 'wplnst');
|
53 |
+
break;
|
54 |
+
|
55 |
+
case 'crawler_action':
|
56 |
+
$text = __('Crawler action', 'wplnst');
|
57 |
+
break;
|
58 |
+
|
59 |
+
case 'crawler_results':
|
60 |
+
$text = __('Crawler results', 'wplnst');
|
61 |
+
break;
|
62 |
+
|
63 |
+
case 'settings':
|
64 |
+
$text = __('Settings', 'wplnst');
|
65 |
+
break;
|
66 |
+
|
67 |
+
case 'max_scans':
|
68 |
+
$text = sprintf(__('Sorry, maximum of <strong>%d running scans</strong> achieved and the scan has been enqueued, it will be launched as soon as possible.', 'wplnst'), wplnst_get_nsetting('max_scans'));
|
69 |
+
break;
|
70 |
+
|
71 |
+
case 'scan_not_found':
|
72 |
+
$text = sprintf(__('Sorry, scan not found. Please go to the <a href="%s">scans list screen</a> and select another scan.', 'wplnst'), esc_url(WPLNST_Core_Plugin::get_url_scans()));
|
73 |
+
break;
|
74 |
+
|
75 |
+
case 'invalid_data':
|
76 |
+
$text = __('Sorry, <strong>invalid form data</strong>. Please, <a href="javascript:history.back();">go back</a>, reload the last page and try again.', 'wplnst');
|
77 |
+
break;
|
78 |
+
|
79 |
+
case 'invalid_nonce':
|
80 |
+
$text = __('Sorry, <strong>invalid security data</strong>. Please, <a href="javascript:history.back();">go back</a>, reload the last page and try again.', 'wplnst');
|
81 |
+
break;
|
82 |
+
|
83 |
+
case 'server_comm_error':
|
84 |
+
$text = __('Server communication error', 'wplnst');
|
85 |
+
break;
|
86 |
+
|
87 |
+
case 'unknown_error':
|
88 |
+
$text = __('Unknown error', 'wplnst');
|
89 |
+
break;
|
90 |
+
|
91 |
+
case 'no_salt':
|
92 |
+
$text = __('Unable to create the salt file needed to improve crawler security. Please check your <strong>wp content directory permissions</strong> allowing to save files.', 'wplnst');
|
93 |
+
break;
|
94 |
+
}
|
95 |
+
|
96 |
+
// Save
|
97 |
+
$names[$name] = $text;
|
98 |
+
|
99 |
+
// Done
|
100 |
+
return $text;
|
101 |
+
}
|
102 |
+
|
103 |
+
|
104 |
+
|
105 |
+
}
|
core/types-curl.php
ADDED
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Types CURL class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Types_CURL {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Retrieve info for a given error code
|
15 |
+
*/
|
16 |
+
public static function get_code_info($num) {
|
17 |
+
$codes = self::get_codes();
|
18 |
+
return isset($codes[$num])? $codes[$num] : false;
|
19 |
+
}
|
20 |
+
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Retrieve all error codes
|
25 |
+
*/
|
26 |
+
public static function get_codes() {
|
27 |
+
static $codes;
|
28 |
+
if (!isset($codes))
|
29 |
+
$codes = self::get_codes_array();
|
30 |
+
return $codes;
|
31 |
+
}
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Retrieve array of error codes and descriptions
|
37 |
+
* http://curl.haxx.se/libcurl/c/libcurl-errors.html
|
38 |
+
*/
|
39 |
+
private static function get_codes_array() {
|
40 |
+
return array(
|
41 |
+
0 => array("code" => "CURLE_OK", "title" => __("Ok", "wplnst"), "desc" => __("All fine. Proceed as usual.", "wplnst")),
|
42 |
+
1 => array("code" => "CURLE_UNSUPPORTED_PROTOCOL", "title" => __("Unsupported protocol", "wplnst"), "desc" => __("The URL you passed to libcurl used a protocol that this libcurl does not support. The support might be a compile-time option that you didn't use, it can be a misspelled protocol string or just a protocol libcurl has no code for.", "wplnst")),
|
43 |
+
2 => array("code" => "CURLE_FAILED_INIT", "title" => __("Failed initialization", "wplnst"), "desc" => __("Very early initialization code failed. This is likely to be an internal error or problem, or a resource problem where something fundamental couldn't get done at init time.", "wplnst")),
|
44 |
+
3 => array("code" => "CURLE_URL_MALFORMAT", "title" => __("URL malformat", "wplnst"), "desc" => __("The URL was not properly formatted.", "wplnst")),
|
45 |
+
4 => array("code" => "CURLE_NOT_BUILT_IN", "title" => __("Not built-in", "wplnst"), "desc" => __("A requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision. This means that a feature or option was not enabled or explicitly disabled when libcurl was built and in order to get it to function you have to get a rebuilt libcurl.", "wplnst")),
|
46 |
+
5 => array("code" => "CURLE_COULDNT_RESOLVE_PROXY", "title" => __("Couldn't resolve proxy", "wplnst"), "desc" => __("The given proxy host could not be resolved. ", "wplnst")),
|
47 |
+
6 => array("code" => "CURLE_COULDNT_RESOLVE_HOST", "title" => __("Couldn't resolve host", "wplnst"), "desc" => __("The given remote host was not resolved.", "wplnst")),
|
48 |
+
7 => array("code" => "CURLE_COULDNT_CONNECT", "title" => __("Couldn't connect", "wplnst"), "desc" => __("Failed to connect() to host or proxy.", "wplnst")),
|
49 |
+
8 => array("code" => "CURLE_FTP_WEIRD_SERVER_REPLY", "title" => __("FTP weird server reply", "wplnst"), "desc" => __("After connecting to a FTP server, libcurl expects to get a certain reply back. This error code implies that it got a strange or bad reply. The given remote server is probably not an OK FTP server.", "wplnst")),
|
50 |
+
9 => array("code" => "CURLE_REMOTE_ACCESS_DENIED", "title" => __("Remote access denied", "wplnst"), "desc" => __("We were denied access to the resource given in the URL. For FTP, this occurs while trying to change to the remote directory.", "wplnst")),
|
51 |
+
10 => array("code" => "CURLE_FTP_ACCEPT_FAILED", "title" => __("FTP access failed", "wplnst"), "desc" => __("While waiting for the server to connect back when an active FTP session is used, an error code was sent over the control connection or similar.", "wplnst")),
|
52 |
+
11 => array("code" => "CURLE_FTP_WEIRD_PASS_REPLY", "title" => __("FTP weird pass reply", "wplnst"), "desc" => __("After having sent the FTP password to the server, libcurl expects a proper reply. This error code indicates that an unexpected code was returned.", "wplnst")),
|
53 |
+
12 => array("code" => "CURLE_FTP_ACCEPT_TIMEOUT", "title" => __("FTP accept timeout", "wplnst"), "desc" => __("During an active FTP session while waiting for the server to connect, the CURLOPT_ACCEPTTIMEOUT_MS (or the internal default) timeout expired.", "wplnst")),
|
54 |
+
13 => array("code" => "CURLE_FTP_WEIRD_PASV_REPLY", "title" => __("FTP weird pasv reply", "wplnst"), "desc" => __("libcurl failed to get a sensible result back from the server as a response to either a PASV or a EPSV command. The server is flawed.", "wplnst")),
|
55 |
+
14 => array("code" => "CURLE_FTP_WEIRD_227_FORMAT", "title" => __("FTP weird 227 format", "wplnst"), "desc" => __("FTP servers return a 227-line as a response to a PASV command. If libcurl fails to parse that line, this return code is passed back.", "wplnst")),
|
56 |
+
15 => array("code" => "CURLE_FTP_CANT_GET_HOST", "title" => __("FTP can't get host", "wplnst"), "desc" => __("An internal failure to lookup the host used for the new connection.", "wplnst")),
|
57 |
+
16 => array("code" => "CURLE_HTTP2", "title" => __("HTTP2 framing layer problem", "wplnst"), "desc" => __("A problem was detected in the HTTP2 framing layer. This is somewhat generic and can be one out of several problems, see the error buffer for details.", "wplnst")),
|
58 |
+
17 => array("code" => "CURLE_FTP_COULDNT_SET_TYPE", "title" => __("FTP couldn't set type", "wplnst"), "desc" => __("Received an error when trying to set the transfer mode to binary or ASCII.", "wplnst")),
|
59 |
+
18 => array("code" => "CURLE_PARTIAL_FILE", "title" => __("Partial file", "wplnst"), "desc" => __("A file transfer was shorter or larger than expected. This happens when the server first reports an expected transfer size, and then delivers data that doesn't match the previously given size.", "wplnst")),
|
60 |
+
19 => array("code" => "CURLE_FTP_COULDNT_RETR_FILE", "title" => __("FTP couldn't retrieve file", "wplnst"), "desc" => __("This was either a weird reply to a 'RETR' command or a zero byte transfer complete.", "wplnst")),
|
61 |
+
21 => array("code" => "CURLE_QUOTE_ERROR", "title" => __("Quote error", "wplnst"), "desc" => __("When sending custom 'QUOTE' commands to the remote server, one of the commands returned an error code that was 400 or higher (for FTP) or otherwise indicated unsuccessful completion of the command.", "wplnst")),
|
62 |
+
22 => array("code" => "CURLE_HTTP_RETURNED_ERROR", "title" => __("HTTP returned error", "wplnst"), "desc" => __("This is returned if CURLOPT_FAILONERROR is set TRUE and the HTTP server returns an error code that is >= 400.", "wplnst")),
|
63 |
+
23 => array("code" => "CURLE_WRITE_ERROR", "title" => __("Write error", "wplnst"), "desc" => __("An error occurred when writing received data to a local file, or an error was returned to libcurl from a write callback.", "wplnst")),
|
64 |
+
25 => array("code" => "CURLE_UPLOAD_FAILED", "title" => __("Upload failed", "wplnst"), "desc" => __("Failed starting the upload. For FTP, the server typically denied the STOR command. The error buffer usually contains the server's explanation for this.", "wplnst")),
|
65 |
+
26 => array("code" => "CURLE_READ_ERROR", "title" => __("Read error", "wplnst"), "desc" => __("There was a problem reading a local file or an error returned by the read callback.", "wplnst")),
|
66 |
+
27 => array("code" => "CURLE_OUT_OF_MEMORY", "title" => __("Out of memory", "wplnst"), "desc" => __("A memory allocation request failed. This is serious badness and things are severely screwed up if this ever occurs.", "wplnst")),
|
67 |
+
28 => array("code" => "CURLE_OPERATION_TIMEDOUT", "title" => __("Operation timedout", "wplnst"), "desc" => __("The specified time-out period was reached according to the conditions.", "wplnst")),
|
68 |
+
30 => array("code" => "CURLE_FTP_PORT_FAILED", "title" => __("FTP port failed", "wplnst"), "desc" => __("The FTP PORT command returned error. This mostly happens when you haven't specified a good enough address for libcurl to use. See CURLOPT_FTPPORT.", "wplnst")),
|
69 |
+
31 => array("code" => "CURLE_FTP_COULDNT_USE_REST", "title" => __("FTP couldn't use REST", "wplnst"), "desc" => __("The FTP REST command returned error. This should never happen if the server is sane.", "wplnst")),
|
70 |
+
33 => array("code" => "CURLE_RANGE_ERROR", "title" => __("Range error", "wplnst"), "desc" => __("The server does not support or accept range requests.", "wplnst")),
|
71 |
+
34 => array("code" => "CURLE_HTTP_POST_ERROR", "title" => __("HTTP post error", "wplnst"), "desc" => __("This is an odd error that mainly occurs due to internal confusion.", "wplnst")),
|
72 |
+
35 => array("code" => "CURLE_SSL_CONNECT_ERROR", "title" => __("SSL connect error", "wplnst"), "desc" => __("A problem occurred somewhere in the SSL/TLS handshake. You really want the error buffer and read the message there as it pinpoints the problem slightly more. Could be certificates (file formats, paths, permissions), passwords, and others.", "wplnst")),
|
73 |
+
36 => array("code" => "CURLE_BAD_DOWNLOAD_RESUME", "title" => __("Bad download resume", "wplnst"), "desc" => __("The download could not be resumed because the specified offset was out of the file boundary.", "wplnst")),
|
74 |
+
37 => array("code" => "CURLE_FILE_COULDNT_READ_FILE", "title" => __("File couldn't read file", "wplnst"), "desc" => __("A file given with FILE:// couldn't be opened. Most likely because the file path doesn't identify an existing file. Did you check file permissions?", "wplnst")),
|
75 |
+
38 => array("code" => "CURLE_LDAP_CANNOT_BIND", "title" => __("LDAP cannot bind", "wplnst"), "desc" => __("LDAP cannot bind. LDAP bind operation failed.", "wplnst")),
|
76 |
+
39 => array("code" => "CURLE_LDAP_SEARCH_FAILED", "title" => __("LDAP search failed", "wplnst"), "desc" => __("LDAP search failed.", "wplnst")),
|
77 |
+
41 => array("code" => "CURLE_FUNCTION_NOT_FOUND", "title" => __("Function not found", "wplnst"), "desc" => __("Function not found. A required zlib function was not found.", "wplnst")),
|
78 |
+
42 => array("code" => "CURLE_ABORTED_BY_CALLBACK", "title" => __("Aborted by callback", "wplnst"), "desc" => __("Aborted by callback. A callback returned 'abort' to libcurl.", "wplnst")),
|
79 |
+
43 => array("code" => "CURLE_BAD_FUNCTION_ARGUMENT", "title" => __("Bad function argument", "wplnst"), "desc" => __("Internal error. A function was called with a bad parameter.", "wplnst")),
|
80 |
+
45 => array("code" => "CURLE_INTERFACE_FAILED", "title" => __("Interface failed", "wplnst"), "desc" => __("Interface error. A specified outgoing interface could not be used. Set which interface to use for outgoing connections source IP address with CURLOPT_INTERFACE.", "wplnst")),
|
81 |
+
47 => array("code" => "CURLE_TOO_MANY_REDIRECTS", "title" => __("Too many redirections", "wplnst"), "desc" => __("Too many redirects. When following redirects, libcurl hit the maximum amount. Set your limit with CURLOPT_MAXREDIRS.", "wplnst")),
|
82 |
+
48 => array("code" => "CURLE_UNKNOWN_OPTION", "title" => __("Unknown option", "wplnst"), "desc" => __("An option passed to libcurl is not recognized/known. Refer to the appropriate documentation. This is most likely a problem in the program that uses libcurl. The error buffer might contain more specific information about which exact option it concerns.", "wplnst")),
|
83 |
+
49 => array("code" => "CURLE_TELNET_OPTION_SYNTAX", "title" => __("Telnet option syntax", "wplnst"), "desc" => __("A telnet option string was Illegally formatted.", "wplnst")),
|
84 |
+
51 => array("code" => "CURLE_PEER_FAILED_VERIFICATION", "title" => __("Peer failed verification", "wplnst"), "desc" => __("The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK.", "wplnst")),
|
85 |
+
52 => array("code" => "CURLE_GOT_NOTHING", "title" => __("Got nothing", "wplnst"), "desc" => __("Nothing was returned from the server, and under the circumstances, getting nothing is considered an error.", "wplnst")),
|
86 |
+
53 => array("code" => "CURLE_SSL_ENGINE_NOTFOUND", "title" => __("SSL engine not found", "wplnst"), "desc" => __("The specified crypto engine wasn't found.", "wplnst")),
|
87 |
+
54 => array("code" => "CURLE_SSL_ENGINE_SETFAILED", "title" => __("SSL engine set failed", "wplnst"), "desc" => __("Failed setting the selected SSL crypto engine as default!", "wplnst")),
|
88 |
+
55 => array("code" => "CURLE_SEND_ERROR", "title" => __("Send error", "wplnst"), "desc" => __("Failed sending network data.", "wplnst")),
|
89 |
+
56 => array("code" => "CURLE_RECV_ERROR", "title" => __("Receive error", "wplnst"), "desc" => __("Failure with receiving network data.", "wplnst")),
|
90 |
+
58 => array("code" => "CURLE_SSL_CERTPROBLEM", "title" => __("Certificate problem", "wplnst"), "desc" => __("Problem with the local client certificate. ", "wplnst")),
|
91 |
+
59 => array("code" => "CURLE_SSL_CIPHER", "title" => __("SSL cipher", "wplnst"), "desc" => __("Couldn't use specified cipher.", "wplnst")),
|
92 |
+
60 => array("code" => "CURLE_SSL_CACERT", "title" => __("SSL CA certificate", "wplnst"), "desc" => __("Peer certificate cannot be authenticated with known CA certificates.", "wplnst")),
|
93 |
+
61 => array("code" => "CURLE_BAD_CONTENT_ENCODING", "title" => __("Bad content encoding", "wplnst"), "desc" => __("Unrecognized transfer encoding.", "wplnst")),
|
94 |
+
62 => array("code" => "CURLE_LDAP_INVALID_URL", "title" => __("LDAP invalid URL", "wplnst"), "desc" => __("Invalid LDAP URL.", "wplnst")),
|
95 |
+
63 => array("code" => "CURLE_FILESIZE_EXCEEDED", "title" => __("File size exceeded", "wplnst"), "desc" => __("Maximum file size exceeded.", "wplnst")),
|
96 |
+
64 => array("code" => "CURLE_USE_SSL_FAILED", "title" => __("Use SSL failed", "wplnst"), "desc" => __("Requested FTP SSL level failed. ", "wplnst")),
|
97 |
+
65 => array("code" => "CURLE_SEND_FAIL_REWIND", "title" => __("Send fail rewind", "wplnst"), "desc" => __("When doing a send operation curl had to rewind the data to retransmit, but the rewinding operation failed.", "wplnst")),
|
98 |
+
66 => array("code" => "CURLE_SSL_ENGINE_INITFAILED", "title" => __("SSL initialization failed", "wplnst"), "desc" => __("Initiating the SSL Engine failed.", "wplnst")),
|
99 |
+
67 => array("code" => "CURLE_LOGIN_DENIED", "title" => __("Login denied", "wplnst"), "desc" => __("The remote server denied curl to login (Added in 7.13.1)", "wplnst")),
|
100 |
+
68 => array("code" => "CURLE_TFTP_NOTFOUND", "title" => __("TFTP file not found", "wplnst"), "desc" => __("File not found on TFTP server.", "wplnst")),
|
101 |
+
69 => array("code" => "CURLE_TFTP_PERM", "title" => __("TFTP permission", "wplnst"), "desc" => __("Permission problem on TFTP server.", "wplnst")),
|
102 |
+
70 => array("code" => "CURLE_REMOTE_DISK_FULL", "title" => __("Remote disk full", "wplnst"), "desc" => __("Out of disk space on the server.", "wplnst")),
|
103 |
+
71 => array("code" => "CURLE_TFTP_ILLEGAL", "title" => __("TFTP illegal", "wplnst"), "desc" => __("Illegal TFTP operation.", "wplnst")),
|
104 |
+
72 => array("code" => "CURLE_TFTP_UNKNOWNID", "title" => __("FTP unknown ID", "wplnst"), "desc" => __("Unknown TFTP transfer ID.", "wplnst")),
|
105 |
+
73 => array("code" => "CURLE_REMOTE_FILE_EXISTS", "title" => __("Remote file exists", "wplnst"), "desc" => __("File already exists and will not be overwritten.", "wplnst")),
|
106 |
+
74 => array("code" => "CURLE_TFTP_NOSUCHUSER", "title" => __("TFTP no such user", "wplnst"), "desc" => __("This error should never be returned by a properly functioning TFTP server.", "wplnst")),
|
107 |
+
75 => array("code" => "CURLE_CONV_FAILED", "title" => __("Conversion failed", "wplnst"), "desc" => __("Character conversion failed.", "wplnst")),
|
108 |
+
76 => array("code" => "CURLE_CONV_REQD", "title" => __("Conversion callbacks", "wplnst"), "desc" => __("Caller must register conversion callbacks.", "wplnst")),
|
109 |
+
77 => array("code" => "CURLE_SSL_CACERT_BADFILE", "title" => __("SSL CA certificate bad file", "wplnst"), "desc" => __("Problem with reading the SSL CA cert (path? access rights?)", "wplnst")),
|
110 |
+
78 => array("code" => "CURLE_REMOTE_FILE_NOT_FOUND", "title" => __("Remote file not found", "wplnst"), "desc" => __("The resource referenced in the URL does not exist.", "wplnst")),
|
111 |
+
79 => array("code" => "CURLE_SSH", "title" => __("SSH error", "wplnst"), "desc" => __("An unspecified error occurred during the SSH session.", "wplnst")),
|
112 |
+
80 => array("code" => "CURLE_SSL_SHUTDOWN_FAILED", "title" => __("SSL shutdown failed", "wplnst"), "desc" => __("Failed to shut down the SSL connection.", "wplnst")),
|
113 |
+
81 => array("code" => "CURLE_AGAIN", "title" => __("Socket not ready", "wplnst"), "desc" => __("Socket is not ready for send/recv wait till it's ready and try again. This return code is only returned from curl_easy_recv and curl_easy_send (Added in 7.18.2)", "wplnst")),
|
114 |
+
82 => array("code" => "CURLE_SSL_CRL_BADFILE", "title" => __("SSL CRL bad file", "wplnst"), "desc" => __("Failed to load CRL file (Added in 7.19.0)", "wplnst")),
|
115 |
+
83 => array("code" => "CURLE_SSL_ISSUER_ERROR", "title" => __("SSL issue error", "wplnst"), "desc" => __("Issuer check failed (Added in 7.19.0)", "wplnst")),
|
116 |
+
84 => array("code" => "CURLE_FTP_PRET_FAILED", "title" => __("FTP PRET failed", "wplnst"), "desc" => __("The FTP server does not understand the PRET command at all or does not support the given argument. Be careful when using CURLOPT_CUSTOMREQUEST, a custom LIST command will be sent with PRET CMD before PASV as well. (Added in 7.20.0)", "wplnst")),
|
117 |
+
85 => array("code" => "CURLE_RTSP_CSEQ_ERROR", "title" => __("RTSP CSEQ error", "wplnst"), "desc" => __("Mismatch of RTSP CSeq numbers.", "wplnst")),
|
118 |
+
86 => array("code" => "CURLE_RTSP_SESSION_ERROR", "title" => __("RTSP session error", "wplnst"), "desc" => __("Mismatch of RTSP Session Identifiers.", "wplnst")),
|
119 |
+
87 => array("code" => "CURLE_FTP_BAD_FILE_LIST", "title" => __("FTP bad file list", "wplnst"), "desc" => __("Unable to parse FTP file list (during FTP wildcard downloading).", "wplnst")),
|
120 |
+
88 => array("code" => "CURLE_CHUNK_FAILED", "title" => __("Chunk failed", "wplnst"), "desc" => __("Chunk callback reported error.", "wplnst")),
|
121 |
+
89 => array("code" => "CURLE_NO_CONNECTION_AVAILABLE", "title" => __("No connection available", "wplnst"), "desc" => __("(For internal use only, will never be returned by libcurl) No connection available, the session will be queued. (added in 7.30.0)", "wplnst")),
|
122 |
+
);
|
123 |
+
}
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
}
|
core/types.php
ADDED
@@ -0,0 +1,752 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Types class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_Types {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
// Constants
|
14 |
+
// ---------------------------------------------------------------------------------------------------
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Post types avoided
|
20 |
+
*/
|
21 |
+
const post_types_avoid = 'attachment, nav_menu_item, revision';
|
22 |
+
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Post status allowed
|
27 |
+
*/
|
28 |
+
const post_status_allow = 'publish, future, draft, pending, private, trash';
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Default scans and results per page
|
34 |
+
*/
|
35 |
+
const scans_per_page = 5;
|
36 |
+
const scans_results_per_page = 25;
|
37 |
+
|
38 |
+
|
39 |
+
|
40 |
+
// Data types
|
41 |
+
// ---------------------------------------------------------------------------------------------------
|
42 |
+
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Post types allowed
|
47 |
+
*/
|
48 |
+
public static function get_post_types($output = 'keys-names') {
|
49 |
+
|
50 |
+
// Current avoid post types
|
51 |
+
$avoid_post_types = apply_filters('wplnst_avoid_post_types', array_map('trim', explode(',', self::post_types_avoid)));
|
52 |
+
if (empty($avoid_post_types) || !is_array($avoid_post_types))
|
53 |
+
return false;
|
54 |
+
|
55 |
+
// Compute allowed post types
|
56 |
+
$post_types = get_post_types(array(), 'objects');
|
57 |
+
$allowed_post_types = array_diff_key($post_types, array_fill_keys($avoid_post_types, true));
|
58 |
+
|
59 |
+
// Return key-name values
|
60 |
+
if ('keys-names' == $output) {
|
61 |
+
$keys_names = array();
|
62 |
+
foreach ($allowed_post_types as $key => $post_type)
|
63 |
+
$keys_names[$key] = $post_type->labels->name;
|
64 |
+
return $keys_names;
|
65 |
+
|
66 |
+
// Return keys
|
67 |
+
} elseif ('keys' == $output) {
|
68 |
+
return array_keys($allowed_post_types);
|
69 |
+
|
70 |
+
// Return names
|
71 |
+
} elseif ('names' == $output) {
|
72 |
+
$names = array();
|
73 |
+
foreach ($allowed_post_types as $key => $post_type)
|
74 |
+
$names[] = $post_type->labels->name;
|
75 |
+
return $names;
|
76 |
+
}
|
77 |
+
|
78 |
+
// Default
|
79 |
+
return $allowed_post_types;
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Post status allowed
|
86 |
+
*/
|
87 |
+
public static function get_post_status() {
|
88 |
+
$post_status_allowed = array_map('trim', explode(',', self::post_status_allow));
|
89 |
+
$post_status = apply_filters('wplnst_allow_post_status', $post_status_allowed);
|
90 |
+
return (empty($post_status) && !is_array($post_status))? false : array_intersect($post_status, $post_status_allowed);
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Return an array of tipified objects
|
97 |
+
*/
|
98 |
+
public static function get_objects_types() {
|
99 |
+
return array(
|
100 |
+
'posts' => __('Entries', 'wplnst'),
|
101 |
+
'comments' => __('Comments', 'wplnst'),
|
102 |
+
'blogroll' => __('Blogroll', 'wplnst'),
|
103 |
+
);
|
104 |
+
}
|
105 |
+
|
106 |
+
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Return an array of possible scan status
|
110 |
+
*/
|
111 |
+
public static function get_scan_statuses() {
|
112 |
+
return array(
|
113 |
+
'wait' => __('Waiting', 'wplnst'),
|
114 |
+
'queued' => __('Queued', 'wplnst'),
|
115 |
+
'play' => __('Running', 'wplnst'),
|
116 |
+
'stop' => __('Stopped', 'wplnst'),
|
117 |
+
'end' => __('Completed', 'wplnst'),
|
118 |
+
);
|
119 |
+
}
|
120 |
+
|
121 |
+
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Return link destination types
|
125 |
+
*/
|
126 |
+
public static function get_destination_types() {
|
127 |
+
return array(
|
128 |
+
'all' => __('All URLs', 'wplnst'),
|
129 |
+
'internal' => __('Internal URLs', 'wplnst'),
|
130 |
+
'external' => __('External URLs', 'wplnst'),
|
131 |
+
);
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Return available time scopes
|
138 |
+
*/
|
139 |
+
public static function get_time_scopes() {
|
140 |
+
return array(
|
141 |
+
'anytime' => __('Anytime content', 'wplnst'),
|
142 |
+
'yesterday' => __('From yesterday', 'wplnst'),
|
143 |
+
'7days' => __('Last 7 days', 'wplnst'),
|
144 |
+
'15days' => __('Last 15 days', 'wplnst'),
|
145 |
+
'month' => __('One month', 'wplnst'),
|
146 |
+
'3months' => __('Last 3 months', 'wplnst'),
|
147 |
+
'6months' => __('Last 6 months', 'wplnst'),
|
148 |
+
'year' => __('One year', 'wplnst'),
|
149 |
+
/* 'custom' => 'Custom' */
|
150 |
+
);
|
151 |
+
}
|
152 |
+
|
153 |
+
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Return link types
|
157 |
+
*/
|
158 |
+
public static function get_link_types() {
|
159 |
+
return array(
|
160 |
+
'links' => __('Links', 'wplnst'),
|
161 |
+
'images' => __('Images', 'wplnst'),
|
162 |
+
);
|
163 |
+
}
|
164 |
+
|
165 |
+
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Return crawl order values
|
169 |
+
*/
|
170 |
+
public static function get_crawl_order() {
|
171 |
+
return array(
|
172 |
+
'desc' => __('Most recent content', 'wplnst'),
|
173 |
+
'asc' => __('Oldest content first', 'wplnst'),
|
174 |
+
);
|
175 |
+
}
|
176 |
+
|
177 |
+
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Return custom fields types array
|
181 |
+
*/
|
182 |
+
public static function get_custom_fields() {
|
183 |
+
return array(
|
184 |
+
'url' => 'URL',
|
185 |
+
'html' => 'HTML',
|
186 |
+
);
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Return allowed comment types
|
193 |
+
*/
|
194 |
+
public static function get_comment_types() {
|
195 |
+
return array(
|
196 |
+
'approved' => __('Approved', 'wplnst'),
|
197 |
+
'pending' => __('Pending', 'wplnst'),
|
198 |
+
);
|
199 |
+
}
|
200 |
+
|
201 |
+
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Return database values for comment types keys
|
205 |
+
*/
|
206 |
+
public static function get_comment_types_values($comment_types) {
|
207 |
+
$comment_types_values = array();
|
208 |
+
$eq = array('approved' => '1', 'pending' => '0');
|
209 |
+
foreach ($comment_types as $comment_type) {
|
210 |
+
if (isset($eq[$comment_type]))
|
211 |
+
$comment_types_values[] = $eq[$comment_type];
|
212 |
+
}
|
213 |
+
return $comment_types_values;
|
214 |
+
}
|
215 |
+
|
216 |
+
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Return anchor filters types array
|
220 |
+
*/
|
221 |
+
public static function get_anchor_filters() {
|
222 |
+
return array(
|
223 |
+
'contains' => __('Contains', 'wplnst'),
|
224 |
+
'not-contains' => __('Not contains', 'wplnst'),
|
225 |
+
'equal-to' => __('Is equal to', 'wplnst'),
|
226 |
+
'not-equal-to' => __('Not equal to', 'wplnst'),
|
227 |
+
'begins-with' => __('Starts with', 'wplnst'),
|
228 |
+
'ends-by' => __('Ends by', 'wplnst'),
|
229 |
+
'empty' => __('Empty', 'wplnst'),
|
230 |
+
);
|
231 |
+
}
|
232 |
+
|
233 |
+
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Return filters for Anchor text search
|
237 |
+
*/
|
238 |
+
public static function get_anchor_search_filters() {
|
239 |
+
return array(
|
240 |
+
'm' => __('Matched string', 'wplnst'),
|
241 |
+
'p' => __('Starts with', 'wplnst'),
|
242 |
+
's' => __('Ends by', 'wplnst'),
|
243 |
+
'f' => __('Full anchor', 'wplnst'),
|
244 |
+
);
|
245 |
+
}
|
246 |
+
|
247 |
+
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Return filters for URL inclusion and exclusion
|
251 |
+
*/
|
252 |
+
public static function get_url_filters() {
|
253 |
+
return array(
|
254 |
+
'matched-string' => __('Matched string', 'wplnst'),
|
255 |
+
'url-prefix' => __('URL prefix', 'wplnst'),
|
256 |
+
'url-suffix' => __('URL suffix', 'wplnst'),
|
257 |
+
'full-url' => __('Full URL', 'wplnst'),
|
258 |
+
);
|
259 |
+
}
|
260 |
+
|
261 |
+
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Return filters for URL search
|
265 |
+
*/
|
266 |
+
public static function get_url_search_filters() {
|
267 |
+
return array(
|
268 |
+
'm' => __('Matched string', 'wplnst'),
|
269 |
+
'p' => __('URL prefix', 'wplnst'),
|
270 |
+
's' => __('URL suffix', 'wplnst'),
|
271 |
+
'r' => __('URL fragment #', 'wplnst'),
|
272 |
+
'f' => __('Full URL', 'wplnst'),
|
273 |
+
);
|
274 |
+
}
|
275 |
+
|
276 |
+
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Return array of HTML elements having options
|
280 |
+
*/
|
281 |
+
public static function get_html_attributes_having() {
|
282 |
+
return array(
|
283 |
+
'have' => __('Has', 'wplnst'),
|
284 |
+
'not-have' => __('Not have', 'wplnst'),
|
285 |
+
);
|
286 |
+
}
|
287 |
+
|
288 |
+
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Return array of HTML elements operation
|
292 |
+
*/
|
293 |
+
public static function get_html_attributes_operators() {
|
294 |
+
return array(
|
295 |
+
'contains' => __('Contains', 'wplnst'),
|
296 |
+
'not-contains' => __('Not contains', 'wplnst'),
|
297 |
+
'equal' => __('Is equal to', 'wplnst'),
|
298 |
+
'not-equal' => __('Not equal to', 'wplnst'),
|
299 |
+
'not-empty' => __('Not empty', 'wplnst'),
|
300 |
+
'empty' => __('Empty', 'wplnst'),
|
301 |
+
);
|
302 |
+
}
|
303 |
+
|
304 |
+
|
305 |
+
|
306 |
+
/**
|
307 |
+
* All status levels
|
308 |
+
*/
|
309 |
+
public static function get_status_levels() {
|
310 |
+
return array(
|
311 |
+
'2' => __('Success', 'wplnst'),
|
312 |
+
'3' => __('Redirections', 'wplnst'),
|
313 |
+
'4' => __('Errors', 'wplnst'),
|
314 |
+
'5' => __('Server Error', 'wplnst'),
|
315 |
+
);
|
316 |
+
}
|
317 |
+
|
318 |
+
|
319 |
+
|
320 |
+
/**
|
321 |
+
* All status codes
|
322 |
+
*/
|
323 |
+
public static function get_status_codes() {
|
324 |
+
return array(
|
325 |
+
'2' => array(
|
326 |
+
'200' => __('OK', 'wplnst'),
|
327 |
+
'201' => __('Created', 'wplnst'),
|
328 |
+
'202' => __('Accepted', 'wplnst'),
|
329 |
+
'203' => __('Non-Authoritative Information', 'wplnst'),
|
330 |
+
'204' => __('No Content', 'wplnst'),
|
331 |
+
'205' => __('Reset Content', 'wplnst'),
|
332 |
+
'206' => __('Partial Content', 'wplnst'),
|
333 |
+
),
|
334 |
+
'3' => array(
|
335 |
+
'300' => __('Multiple Choices', 'wplnst'),
|
336 |
+
'301' => __('Moved Permanently', 'wplnst'),
|
337 |
+
'302' => __('Found', 'wplnst'),
|
338 |
+
'303' => __('See Other', 'wplnst'),
|
339 |
+
'304' => __('Not Modified', 'wplnst'),
|
340 |
+
'305' => __('Use Proxy', 'wplnst'),
|
341 |
+
'307' => __('Temporary Redirect', 'wplnst'),
|
342 |
+
),
|
343 |
+
'4' => array(
|
344 |
+
'400' => __('Bad Request', 'wplnst'),
|
345 |
+
'401' => __('Unauthorized', 'wplnst'),
|
346 |
+
'402' => __('Payment Required', 'wplnst'),
|
347 |
+
'403' => __('Forbidden', 'wplnst'),
|
348 |
+
'404' => __('Not Found', 'wplnst'),
|
349 |
+
'405' => __('Method Not Allowed', 'wplnst'),
|
350 |
+
'406' => __('Not Acceptable', 'wplnst'),
|
351 |
+
'407' => __('Proxy Authentication Required', 'wplnst'),
|
352 |
+
'408' => __('Request Timeout', 'wplnst'),
|
353 |
+
'409' => __('Conflict', 'wplnst'),
|
354 |
+
'410' => __('Gone', 'wplnst'),
|
355 |
+
'411' => __('Length Required', 'wplnst'),
|
356 |
+
'412' => __('Precondition Failed', 'wplnst'),
|
357 |
+
'413' => __('Request Entity Too Large', 'wplnst'),
|
358 |
+
'414' => __('Request-URI Too Long', 'wplnst'),
|
359 |
+
'415' => __('Unsupported Media Type', 'wplnst'),
|
360 |
+
'416' => __('Requested Range Not Satisfiable', 'wplnst'),
|
361 |
+
'417' => __('Expectation Failed', 'wplnst'),
|
362 |
+
),
|
363 |
+
'5' => array(
|
364 |
+
'500' => __('Internal Server Error', 'wplnst'),
|
365 |
+
'501' => __('Not Implemented', 'wplnst'),
|
366 |
+
'502' => __('Bad Gateway', 'wplnst'),
|
367 |
+
'503' => __('Service Unavailable', 'wplnst'),
|
368 |
+
'504' => __('Gateway Timeout', 'wplnst'),
|
369 |
+
'505' => __('HTTP Version Not Supported', 'wplnst'),
|
370 |
+
)
|
371 |
+
);
|
372 |
+
}
|
373 |
+
|
374 |
+
|
375 |
+
|
376 |
+
/**
|
377 |
+
* Return only codes in one-dimensional array
|
378 |
+
*/
|
379 |
+
public static function get_status_codes_raw() {
|
380 |
+
$raw = array();
|
381 |
+
$codes = self::get_status_codes();
|
382 |
+
foreach ($codes as $level => $status) {
|
383 |
+
foreach ($status as $code => $description)
|
384 |
+
$raw[$code] = $description;
|
385 |
+
}
|
386 |
+
return $raw;
|
387 |
+
}
|
388 |
+
|
389 |
+
|
390 |
+
|
391 |
+
/**
|
392 |
+
* Return SEO link types
|
393 |
+
*/
|
394 |
+
public static function get_seo_link_types() {
|
395 |
+
return array(
|
396 |
+
'nf' => __('NoFollow', 'wplnst'),
|
397 |
+
'df' => __('DoFollow', 'wplnst'),
|
398 |
+
);
|
399 |
+
}
|
400 |
+
|
401 |
+
|
402 |
+
|
403 |
+
/**
|
404 |
+
* Return protocol filters
|
405 |
+
*/
|
406 |
+
public static function get_protocol_types() {
|
407 |
+
return array(
|
408 |
+
'http' => 'HTTP',
|
409 |
+
'https' => 'HTTPS',
|
410 |
+
'rel' => 'Relative //',
|
411 |
+
);
|
412 |
+
}
|
413 |
+
|
414 |
+
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Return special types of URLs
|
418 |
+
*/
|
419 |
+
public static function get_special_types() {
|
420 |
+
return array(
|
421 |
+
'rel' => __('Relative', 'wplnst'),
|
422 |
+
'abs' => __('Absolute', 'wplnst'),
|
423 |
+
'spa' => __('Spaced', 'wplnst'),
|
424 |
+
'mal' => __('Malformed', 'wplnst'),
|
425 |
+
);
|
426 |
+
}
|
427 |
+
|
428 |
+
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Return actions performed
|
432 |
+
*/
|
433 |
+
public static function get_action_types() {
|
434 |
+
return array(
|
435 |
+
'unl' => __('Unlinked', 'wplnst'),
|
436 |
+
'mod' => __('Modified', 'wplnst'),
|
437 |
+
'umd' => __('Unmodified', 'wplnst'),
|
438 |
+
'rec' => __('Rechecked', 'wplnst'),
|
439 |
+
);
|
440 |
+
}
|
441 |
+
|
442 |
+
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Return filter for ignored results
|
446 |
+
*/
|
447 |
+
public static function get_ignored_types() {
|
448 |
+
return array(
|
449 |
+
'oir' => __('Only ignored results', 'wplnst'),
|
450 |
+
'ian' => __('Ignored and not ignored', 'wplnst'),
|
451 |
+
);
|
452 |
+
}
|
453 |
+
|
454 |
+
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Return allowed order by
|
458 |
+
*/
|
459 |
+
public static function get_order_types() {
|
460 |
+
return array(
|
461 |
+
'dma' => __('Domain name ASC', 'wplnst'),
|
462 |
+
'dmd' => __('Domain name DESC', 'wplnst'),
|
463 |
+
'dta' => __('Download time ASC', 'wplnst'),
|
464 |
+
'dtd' => __('Download time DESC', 'wplnst'),
|
465 |
+
'dsa' => __('Download size ASC', 'wplnst'),
|
466 |
+
'dsd' => __('Download size DESC', 'wplnst'),
|
467 |
+
);
|
468 |
+
}
|
469 |
+
|
470 |
+
|
471 |
+
|
472 |
+
// Selected types name
|
473 |
+
// ---------------------------------------------------------------------------------------------------
|
474 |
+
|
475 |
+
|
476 |
+
|
477 |
+
/**
|
478 |
+
* Resolve Destination Type name from value
|
479 |
+
*/
|
480 |
+
public static function get_destination_type_name($value, $default = false) {
|
481 |
+
return self::get_field_value_name(self::get_destination_types(), $value, $default);
|
482 |
+
}
|
483 |
+
|
484 |
+
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Resolve Time Scope name from value
|
488 |
+
*/
|
489 |
+
public static function get_time_scope_name($value, $default = false) {
|
490 |
+
return self::get_field_value_name(self::get_time_scopes(), $value, $default);
|
491 |
+
}
|
492 |
+
|
493 |
+
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Resolve Links Types from values
|
497 |
+
*/
|
498 |
+
public static function get_link_types_names($value, $default = false) {
|
499 |
+
return self::get_field_values_names(self::get_link_types(), $value, $default);
|
500 |
+
}
|
501 |
+
|
502 |
+
|
503 |
+
|
504 |
+
/**
|
505 |
+
* Resolve Crawl Order name from value
|
506 |
+
*/
|
507 |
+
public static function get_crawl_order_name($value, $default = false) {
|
508 |
+
return self::get_field_value_name(self::get_crawl_order(), $value, $default);
|
509 |
+
}
|
510 |
+
|
511 |
+
|
512 |
+
|
513 |
+
/**
|
514 |
+
* Resolve post types from values
|
515 |
+
*/
|
516 |
+
public static function get_post_types_names($value, $default = false) {
|
517 |
+
return self::get_field_values_names(self::get_post_types(), $value, $default);
|
518 |
+
}
|
519 |
+
|
520 |
+
|
521 |
+
|
522 |
+
/**
|
523 |
+
* Resolve post status from values
|
524 |
+
*/
|
525 |
+
public static function get_post_status_names($value, $default = false) {
|
526 |
+
return self::get_field_values_names(self::get_post_status(), $value, $default);
|
527 |
+
}
|
528 |
+
|
529 |
+
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Resolve Comments Types from values
|
533 |
+
*/
|
534 |
+
public static function get_comment_types_names($value, $default = false) {
|
535 |
+
return self::get_field_values_names(self::get_comment_types(), $value, $default);
|
536 |
+
}
|
537 |
+
|
538 |
+
|
539 |
+
|
540 |
+
/**
|
541 |
+
* Resolve links level status
|
542 |
+
*/
|
543 |
+
public static function get_links_status_levels_names($value, $default = false) {
|
544 |
+
return self::get_field_values_names(self::get_status_levels(), $value, $default);
|
545 |
+
}
|
546 |
+
|
547 |
+
|
548 |
+
|
549 |
+
/**
|
550 |
+
* Resolve links codes status
|
551 |
+
*/
|
552 |
+
public static function get_links_status_codes_names($value, $default = false) {
|
553 |
+
return self::get_field_values_names(self::get_status_codes_raw(), $value, $default);
|
554 |
+
}
|
555 |
+
|
556 |
+
|
557 |
+
|
558 |
+
/**
|
559 |
+
* Resolve names, combined with levels and codes
|
560 |
+
*/
|
561 |
+
public static function get_links_status_names_combined($status_levels_values, $status_codes_values) {
|
562 |
+
|
563 |
+
// Initialize
|
564 |
+
$names = array();
|
565 |
+
|
566 |
+
// Resolve levels
|
567 |
+
$status_codes = self::get_status_codes();
|
568 |
+
$status_levels = self::get_status_levels();
|
569 |
+
foreach ($status_levels as $key => $level_name) {
|
570 |
+
if (in_array($key, $status_levels_values))
|
571 |
+
$names[] = $key.'00s '.$level_name;
|
572 |
+
if (isset($status_codes[$key])) {
|
573 |
+
foreach ($status_codes[$key] as $code => $code_name) {
|
574 |
+
if (in_array($code, $status_codes_values))
|
575 |
+
$names[] = $code.' '.$code_name;
|
576 |
+
}
|
577 |
+
}
|
578 |
+
}
|
579 |
+
|
580 |
+
// Donde
|
581 |
+
return $names;
|
582 |
+
}
|
583 |
+
|
584 |
+
|
585 |
+
|
586 |
+
/**
|
587 |
+
* Resolve a name from key value
|
588 |
+
*/
|
589 |
+
public static function get_field_value_name($array, $value, $default = false) {
|
590 |
+
|
591 |
+
// Check name value
|
592 |
+
if (isset($array[$value]))
|
593 |
+
return $array[$value];
|
594 |
+
|
595 |
+
// Check default value
|
596 |
+
if (false !== $default && isset($array[$default]))
|
597 |
+
return $array[$default];
|
598 |
+
|
599 |
+
// Nothing
|
600 |
+
return '';
|
601 |
+
}
|
602 |
+
|
603 |
+
|
604 |
+
|
605 |
+
/**
|
606 |
+
* Resolve an array of names from an array of key values
|
607 |
+
*/
|
608 |
+
public static function get_field_values_names($array, $values, $default = false) {
|
609 |
+
|
610 |
+
// Initialize
|
611 |
+
$names = array();
|
612 |
+
|
613 |
+
// Enum values
|
614 |
+
foreach ($values as $key) {
|
615 |
+
if (isset($array[$key]))
|
616 |
+
$names[] = $array[$key];
|
617 |
+
}
|
618 |
+
|
619 |
+
// Check default for empty names
|
620 |
+
if (empty($names) && false !== $default) {
|
621 |
+
if (!is_array($default)) {
|
622 |
+
if (isset($array[$default]))
|
623 |
+
$names[] = $array[$default];
|
624 |
+
} else {
|
625 |
+
foreach ($default as $key) {
|
626 |
+
if (isset($array[$key]))
|
627 |
+
$names[] = $array[$key];
|
628 |
+
}
|
629 |
+
}
|
630 |
+
}
|
631 |
+
|
632 |
+
// Done
|
633 |
+
return $names;
|
634 |
+
}
|
635 |
+
|
636 |
+
|
637 |
+
|
638 |
+
// Validation
|
639 |
+
// ---------------------------------------------------------------------------------------------------
|
640 |
+
|
641 |
+
|
642 |
+
|
643 |
+
/**
|
644 |
+
* Check submit POST value
|
645 |
+
*/
|
646 |
+
public static function check_post_value($param, $allowed, $default = null) {
|
647 |
+
return (!empty($_POST) && is_array($_POST) && isset($_POST[$param]))? self::check_allowed_value($_POST[$param], $allowed, $default) : $default;
|
648 |
+
}
|
649 |
+
|
650 |
+
|
651 |
+
|
652 |
+
/**
|
653 |
+
* Check submitted elist and rearrange indexes
|
654 |
+
*/
|
655 |
+
public static function check_post_elist($param, $default = array()) {
|
656 |
+
|
657 |
+
// Decode value
|
658 |
+
$elist = isset($_POST[$param])? @json_decode(stripslashes($_POST[$param]), true) : false;
|
659 |
+
|
660 |
+
// Check decoding
|
661 |
+
if (empty($elist) || !is_array($elist))
|
662 |
+
return $default;
|
663 |
+
|
664 |
+
// Arrange index
|
665 |
+
$index = -1;
|
666 |
+
foreach ($elist as &$value) {
|
667 |
+
if (is_array($value))
|
668 |
+
$value['index'] = ++$index;
|
669 |
+
}
|
670 |
+
|
671 |
+
// Done
|
672 |
+
return @json_encode($elist);
|
673 |
+
}
|
674 |
+
|
675 |
+
|
676 |
+
|
677 |
+
/**
|
678 |
+
* Safe retrieve array value
|
679 |
+
*/
|
680 |
+
public static function get_array_value($array, $param, $default = null) {
|
681 |
+
return (!empty($array) && is_array($array) && isset($array[$param]))? $array[$param] : $default;
|
682 |
+
}
|
683 |
+
|
684 |
+
|
685 |
+
|
686 |
+
/**
|
687 |
+
* Check array value
|
688 |
+
*/
|
689 |
+
public static function check_array_value($array, $param, $allowed, $default = null) {
|
690 |
+
return (!empty($array) && is_array($array) && isset($array[$param]))? self::check_allowed_value($array[$param], $allowed, $default) : $default;
|
691 |
+
}
|
692 |
+
|
693 |
+
|
694 |
+
|
695 |
+
/**
|
696 |
+
* Check numeric array value
|
697 |
+
*/
|
698 |
+
public static function check_array_numeric_value($array, $param, $default = 0) {
|
699 |
+
return empty($array[$param])? $default : (int) $array[$param];
|
700 |
+
}
|
701 |
+
|
702 |
+
|
703 |
+
|
704 |
+
/**
|
705 |
+
* Check a json array value
|
706 |
+
*/
|
707 |
+
public static function check_array_json($array, $param, $default = array()) {
|
708 |
+
$value = (!empty($array) && is_array($array) && isset($array[$param]))? @json_decode($array[$param], true) : array();
|
709 |
+
return (empty($value) || !is_array($value))? $default : $value;
|
710 |
+
}
|
711 |
+
|
712 |
+
|
713 |
+
|
714 |
+
/**
|
715 |
+
* Check a value in array
|
716 |
+
*/
|
717 |
+
public static function check_allowed_value($test, $allowed, $default = null) {
|
718 |
+
|
719 |
+
// Is an array
|
720 |
+
if (is_array($allowed)) {
|
721 |
+
|
722 |
+
// Initialize
|
723 |
+
$value = $default;
|
724 |
+
|
725 |
+
// Source value as an array
|
726 |
+
if (is_array($test)) {
|
727 |
+
$value = array();
|
728 |
+
foreach ($test as $key => $name) {
|
729 |
+
$sel = ('on' == $name)? $key : $name;
|
730 |
+
if (in_array($sel, $allowed))
|
731 |
+
$value[] = $sel;
|
732 |
+
}
|
733 |
+
|
734 |
+
// Single value in allowed array
|
735 |
+
} elseif (in_array($test, $allowed)) {
|
736 |
+
$value = $test;
|
737 |
+
}
|
738 |
+
|
739 |
+
// Result value
|
740 |
+
} else {
|
741 |
+
|
742 |
+
// Comparison value
|
743 |
+
$value = ($test === $allowed);
|
744 |
+
}
|
745 |
+
|
746 |
+
// Done
|
747 |
+
return $value;
|
748 |
+
}
|
749 |
+
|
750 |
+
|
751 |
+
|
752 |
+
}
|
core/url.php
ADDED
@@ -0,0 +1,364 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core URL class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
class WPLNST_Core_URL {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
// Properties
|
14 |
+
// ---------------------------------------------------------------------------------------------------
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Current Home URL
|
20 |
+
*/
|
21 |
+
public $home_url;
|
22 |
+
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Current site host and host URL
|
27 |
+
*/
|
28 |
+
public $host;
|
29 |
+
public $host_url;
|
30 |
+
|
31 |
+
|
32 |
+
|
33 |
+
// Initialization
|
34 |
+
// ---------------------------------------------------------------------------------------------------
|
35 |
+
|
36 |
+
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Constructor
|
40 |
+
*/
|
41 |
+
public function __construct() {
|
42 |
+
|
43 |
+
// Blog home URL
|
44 |
+
$this->home_url = rtrim(home_url(), '/');
|
45 |
+
|
46 |
+
// Paranoid mode
|
47 |
+
if (false !== ($pos = strpos($this->home_url, '#')))
|
48 |
+
$this->home_url = mb_substr($this->home_url, 0, $pos);
|
49 |
+
|
50 |
+
// Obtains host URL
|
51 |
+
$home_parts = @parse_url($this->home_url);
|
52 |
+
if (false !== $home_parts && isset($home_parts['host']) && '' !== $home_parts['host']) {
|
53 |
+
|
54 |
+
// Site host
|
55 |
+
$this->host = $home_parts['host'];
|
56 |
+
|
57 |
+
// Check scheme
|
58 |
+
$scheme = 'http';
|
59 |
+
if (!empty($home_parts['scheme']) && in_array(strtolower($home_parts['scheme']), array('http', 'https')))
|
60 |
+
$scheme = $home_parts['scheme'];
|
61 |
+
|
62 |
+
// Define host URL
|
63 |
+
$this->host_url = $scheme.'://'.$this->host;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
|
68 |
+
|
69 |
+
// URL utilities
|
70 |
+
// ---------------------------------------------------------------------------------------------------
|
71 |
+
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* URL analysis and fragmentation
|
76 |
+
*/
|
77 |
+
public function parse($value, $parent_url = false) {
|
78 |
+
|
79 |
+
// Initialize
|
80 |
+
$raw = $value;
|
81 |
+
$url = trim($raw);
|
82 |
+
$fragment = '';
|
83 |
+
$absolute = false;
|
84 |
+
$relative = false;
|
85 |
+
$protorel = false;
|
86 |
+
$malformed = false;
|
87 |
+
|
88 |
+
// Extract fragment
|
89 |
+
$test_url = $url;
|
90 |
+
if (false !== ($pos = strpos($test_url, '#'))) {
|
91 |
+
$url = mb_substr($test_url, 0, $pos);
|
92 |
+
$fragment = mb_substr($test_url, $pos);
|
93 |
+
}
|
94 |
+
|
95 |
+
// Check if begins with double slash
|
96 |
+
if ('//' == mb_substr($url, 0, 2)) {
|
97 |
+
|
98 |
+
// Initialize
|
99 |
+
$protorel = true;
|
100 |
+
$malformed = true;
|
101 |
+
|
102 |
+
// Set full URL
|
103 |
+
$full_url = ((0 === stripos($this->home_url, 'https'))? 'https' : 'http').':'.$url;
|
104 |
+
|
105 |
+
// Check scheme and host
|
106 |
+
if (false !== ($parts = @parse_url($full_url)) && !empty($parts['scheme']) && !empty($parts['host'])) {
|
107 |
+
|
108 |
+
// No malformed
|
109 |
+
$malformed = false;
|
110 |
+
|
111 |
+
// Remove possible fragment
|
112 |
+
$parts['fragment'] = null;
|
113 |
+
|
114 |
+
// Final URL
|
115 |
+
$url = $this->unparse_url($parts);
|
116 |
+
}
|
117 |
+
|
118 |
+
// Check if begins with a single slash (absolute relative)
|
119 |
+
} elseif ('/' == mb_substr($url, 0, 1)) {
|
120 |
+
|
121 |
+
// By default
|
122 |
+
$malformed = true;
|
123 |
+
|
124 |
+
// Execute parent URL filter
|
125 |
+
$parent_url = apply_filters('wplnst_relative_parent_url', $parent_url);
|
126 |
+
|
127 |
+
// Check parent
|
128 |
+
if (false !== $parent_url && !is_array($parent_url)) {
|
129 |
+
|
130 |
+
// Check parent URL
|
131 |
+
$parent_parts = @parse_url($parent_url);
|
132 |
+
if (false !== $parent_parts && isset($parent_parts['host']) && '' !== $parent_parts['host']) {
|
133 |
+
|
134 |
+
// Check scheme
|
135 |
+
$scheme = 'http';
|
136 |
+
if (!empty($parent_parts['scheme']) && in_array(strtolower($parent_parts['scheme']), array('http', 'https')))
|
137 |
+
$scheme = $parent_parts['scheme'];
|
138 |
+
|
139 |
+
// Compose full URL
|
140 |
+
$url = $scheme.'://'.trim($parent_parts['host'], '/').'/'.ltrim($url, '/');
|
141 |
+
|
142 |
+
// No malfomed
|
143 |
+
$malformed = false;
|
144 |
+
|
145 |
+
// Is absolute
|
146 |
+
$absolute = true;
|
147 |
+
|
148 |
+
// Extract parts again
|
149 |
+
$parts = @parse_url($url);
|
150 |
+
}
|
151 |
+
|
152 |
+
// This site
|
153 |
+
} else {
|
154 |
+
|
155 |
+
// Set full URL
|
156 |
+
$home_url = isset($this->host_url)? $this->host_url : $this->home_url;
|
157 |
+
$full_url = rtrim($home_url, '/').$url;
|
158 |
+
|
159 |
+
// Check scheme and host
|
160 |
+
if (false !== ($parts = @parse_url($full_url)) && !empty($parts['scheme']) && !empty($parts['host'])) {
|
161 |
+
|
162 |
+
// No malfomed
|
163 |
+
$malformed = false;
|
164 |
+
|
165 |
+
// Is absolute
|
166 |
+
$absolute = true;
|
167 |
+
|
168 |
+
// Remove possible fragment
|
169 |
+
$parts['fragment'] = null;
|
170 |
+
|
171 |
+
// Final URL
|
172 |
+
$url = $this->unparse_url($parts);
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
// Other
|
177 |
+
} else {
|
178 |
+
|
179 |
+
// Split parts
|
180 |
+
$parts = @parse_url($url);
|
181 |
+
if (false === $parts) {
|
182 |
+
|
183 |
+
// Malformed URL
|
184 |
+
$malformed = true;
|
185 |
+
|
186 |
+
// First relative check
|
187 |
+
} elseif (empty($parts['scheme'])) {
|
188 |
+
|
189 |
+
// Relative URL
|
190 |
+
$relative = true;
|
191 |
+
|
192 |
+
// Execute parent URL filter
|
193 |
+
$parent_url = apply_filters('wplnst_relative_parent_url', $parent_url);
|
194 |
+
|
195 |
+
// Try to compose
|
196 |
+
if (false !== $parent_url && !is_array($parent_url)) {
|
197 |
+
|
198 |
+
// Absolutize
|
199 |
+
$url = $this->absolutize($url, $parent_url);
|
200 |
+
|
201 |
+
// Extract parts again
|
202 |
+
$parts = @parse_url($url);
|
203 |
+
|
204 |
+
// This host
|
205 |
+
} else {
|
206 |
+
|
207 |
+
// Absolutize
|
208 |
+
$url = $this->absolutize($url, $this->home_url);
|
209 |
+
|
210 |
+
// Extract parts again
|
211 |
+
$parts = @parse_url($url);
|
212 |
+
}
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
// Check scheme, host, path and query
|
217 |
+
$scheme = isset($parts['scheme'])? $parts['scheme'] : null;
|
218 |
+
$host = isset($parts['host'])? $parts['host'] : null;
|
219 |
+
$path = isset($parts['path'])? $parts['path'] : null;
|
220 |
+
$query = isset($parts['query'])? $parts['query'] : null;
|
221 |
+
|
222 |
+
// Check link scope
|
223 |
+
$scope = (isset($host) && isset($scheme))? $this->get_scope($host, $scheme) : null;
|
224 |
+
|
225 |
+
// Check link fragment
|
226 |
+
$fragment = isset($fragment)? $fragment : (isset($parts['fragment'])? $parts['fragment'] : null);
|
227 |
+
|
228 |
+
// Done
|
229 |
+
return array(
|
230 |
+
'url' => $url,
|
231 |
+
'raw' => $raw,
|
232 |
+
'scheme' => $scheme,
|
233 |
+
'host' => $host,
|
234 |
+
'path' => $path,
|
235 |
+
'query' => $query,
|
236 |
+
'fragment' => $fragment,
|
237 |
+
'scope' => $scope,
|
238 |
+
'spaced' => (trim($raw) != $raw),
|
239 |
+
'malformed' => $malformed,
|
240 |
+
'absolute' => $absolute,
|
241 |
+
'protorel' => $protorel,
|
242 |
+
'relative' => $relative,
|
243 |
+
'nofollow' => false,
|
244 |
+
);
|
245 |
+
}
|
246 |
+
|
247 |
+
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Unparse a parsed URL
|
251 |
+
* http://php.net/manual/es/function.parse-url.php#106731
|
252 |
+
*/
|
253 |
+
public function unparse_url($parsed_url) {
|
254 |
+
$scheme = isset($parsed_url['scheme'])? $parsed_url['scheme'].'://' : '';
|
255 |
+
$host = isset($parsed_url['host'])? $parsed_url['host'] : '';
|
256 |
+
$port = isset($parsed_url['port'])? ':'.$parsed_url['port'] : '';
|
257 |
+
$user = isset($parsed_url['user'])? $parsed_url['user'] : '';
|
258 |
+
$pass = isset($parsed_url['pass'])? ':'.$parsed_url['pass'] : '';
|
259 |
+
$pass = ($user || $pass)? "$pass@" : '';
|
260 |
+
$path = isset($parsed_url['path'])? $parsed_url['path'] : '';
|
261 |
+
$query = isset($parsed_url['query'])? '?'.$parsed_url['query'] : '';
|
262 |
+
$fragment = (isset($parsed_url['fragment']) && '' != $parsed_url['fragment'])? '#'.ltrim($parsed_url['fragment'], '#') : '';
|
263 |
+
return "$scheme$user$pass$host$port$path$query$fragment";
|
264 |
+
}
|
265 |
+
|
266 |
+
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Absolutize relative URL from a given permalink
|
270 |
+
*/
|
271 |
+
public function absolutize($relative_url, $permalink) {
|
272 |
+
|
273 |
+
// Parse permalink
|
274 |
+
$permalink_parts = @parse_url($permalink);
|
275 |
+
if (false === $permalink_parts)
|
276 |
+
return false;
|
277 |
+
|
278 |
+
// Relative with arguments
|
279 |
+
if ('?' == mb_substr($relative_url, 0, 1)) {
|
280 |
+
|
281 |
+
// Remove permalink fragment
|
282 |
+
if (($pos = strpos($permalink, '#')) > 0)
|
283 |
+
$permalink = mb_substr($permalink, 0, $pos);
|
284 |
+
|
285 |
+
// Concatenation
|
286 |
+
return $permalink.$relative_url;
|
287 |
+
|
288 |
+
// Explode
|
289 |
+
} else {
|
290 |
+
|
291 |
+
// Initialize
|
292 |
+
$path = array();
|
293 |
+
$base = empty($permalink_parts['path'])? '/' : $permalink_parts['path'];
|
294 |
+
|
295 |
+
// Check last file
|
296 |
+
if ('/' != mb_substr($base, -1))
|
297 |
+
$base = dirname($base);
|
298 |
+
|
299 |
+
// URL parts
|
300 |
+
$parts = explode('/', $relative_url);
|
301 |
+
foreach ($parts as $part) {
|
302 |
+
if (empty($path) && '..' == $part) {
|
303 |
+
$base = dirname($base);
|
304 |
+
} elseif ('' !== $part && '.' != $part) {
|
305 |
+
$path[] = $part;
|
306 |
+
}
|
307 |
+
}
|
308 |
+
|
309 |
+
// Compose new path
|
310 |
+
$permalink_parts['path'] = rtrim($base, '/').'/'.implode('/', $path).(('/' == mb_substr($relative_url, -1))? '/' : '');
|
311 |
+
|
312 |
+
// Remove permalink parts fragment
|
313 |
+
$permalink_parts['fragment'] = null;
|
314 |
+
|
315 |
+
// Done
|
316 |
+
return $this->unparse_url($permalink_parts);
|
317 |
+
}
|
318 |
+
}
|
319 |
+
|
320 |
+
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Extract attributes, original RegExp: (\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?
|
324 |
+
* http://stackoverflow.com/questions/317053/regular-expression-for-extracting-tag-attributes
|
325 |
+
*/
|
326 |
+
public function extract_attributes($tag) {
|
327 |
+
$attr = array();
|
328 |
+
if (preg_match_all('/(\S+)=["'."'".']?((?:.(?!["'."'".']?\s+(?:\S+)=|[>"'."'".']))+.)["'."'".']?/', $tag, $matches, PREG_SET_ORDER) > 0) {
|
329 |
+
foreach ($matches as $match)
|
330 |
+
$attr[strtolower($match[1])] = $match[2];
|
331 |
+
}
|
332 |
+
return $attr;
|
333 |
+
}
|
334 |
+
|
335 |
+
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Check if URL is allowed for request
|
339 |
+
*/
|
340 |
+
public function is_crawleable($urlinfo) {
|
341 |
+
return ('' !== $urlinfo['url'] && false !== $urlinfo['url'] && !$urlinfo['malformed'] && isset($urlinfo['scheme']) && in_array($urlinfo['scheme'], array('http', 'https')) && isset($urlinfo['host']));
|
342 |
+
}
|
343 |
+
|
344 |
+
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Check host and scheme and compare from blog host
|
348 |
+
*/
|
349 |
+
public function get_scope($host, $scheme) {
|
350 |
+
|
351 |
+
// Check scheme
|
352 |
+
if (isset($this->host) && in_array(strtolower($scheme), array('http', 'https', 'ftp'))) {
|
353 |
+
$test_host = (0 === stripos($host, 'www.'))? mb_substr($host, 4) : $host;
|
354 |
+
$test_this_host = (0 === stripos($this->host, 'www.'))? mb_substr($this->host, 4) : $this->host;
|
355 |
+
return (strtolower($test_host) == strtolower($test_this_host))? 'internal' : 'external';
|
356 |
+
}
|
357 |
+
|
358 |
+
// No valid
|
359 |
+
return null;
|
360 |
+
}
|
361 |
+
|
362 |
+
|
363 |
+
|
364 |
+
}
|
core/util-math.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Util Math functions
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Format size from bytes to KB, MB, GB or TB
|
14 |
+
*/
|
15 |
+
function wplnst_format_bytes($bytes, $precision = 3, $number_format = true) {
|
16 |
+
|
17 |
+
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
18 |
+
|
19 |
+
$bytes = max($bytes, 0);
|
20 |
+
$pow = floor(($bytes? log($bytes) : 0) / log(1024));
|
21 |
+
$pow = min($pow, count($units) - 1);
|
22 |
+
|
23 |
+
// Uncomment one of the following alternatives
|
24 |
+
$bytes /= pow(1024, $pow);
|
25 |
+
if (0 == $pow) {
|
26 |
+
$pow = 1;
|
27 |
+
if ($bytes > 0)
|
28 |
+
$bytes /= 1024;
|
29 |
+
}
|
30 |
+
|
31 |
+
$value = round($bytes, $precision);
|
32 |
+
if ($number_format && function_exists('number_format_i18n'))
|
33 |
+
$value = number_format_i18n($value, $precision);
|
34 |
+
|
35 |
+
return $value . ' ' . $units[$pow];
|
36 |
+
}
|
core/util-string.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Util String functions
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Text cropping
|
14 |
+
*/
|
15 |
+
function wplnst_crop_text($text, $chars, $dots = '...') {
|
16 |
+
|
17 |
+
// Remove HTML tags
|
18 |
+
$text = strip_tags(preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', '', $text));
|
19 |
+
|
20 |
+
// All text
|
21 |
+
$text = trim($text);
|
22 |
+
if (strlen($text) <= $chars)
|
23 |
+
return $text;
|
24 |
+
|
25 |
+
// Crop text
|
26 |
+
$text = substr($text, 0, $chars);
|
27 |
+
|
28 |
+
// Remove punctuation
|
29 |
+
$text = rtrim($text, '.');
|
30 |
+
$text = rtrim($text, ',');
|
31 |
+
$text = rtrim($text, ';');
|
32 |
+
$text = rtrim($text, ':');
|
33 |
+
|
34 |
+
// Check last char
|
35 |
+
if (mb_substr($text, -1) != ' ') {
|
36 |
+
$pos = strrpos($text, ' ');
|
37 |
+
if ($pos > 0)
|
38 |
+
$text = substr($text, 0, $pos);
|
39 |
+
}
|
40 |
+
|
41 |
+
// Last chars
|
42 |
+
$text = rtrim($text, '.');
|
43 |
+
$text = rtrim($text, ',');
|
44 |
+
$text = rtrim($text, ';');
|
45 |
+
$text = rtrim($text, ':');
|
46 |
+
|
47 |
+
// Done
|
48 |
+
return $text.$dots;
|
49 |
+
}
|
core/util.php
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Core Util functions
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Core
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
|
12 |
+
// Load dependencies
|
13 |
+
require_once(dirname(__FILE__).'/settings.php');
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Requires a plugin file
|
19 |
+
*/
|
20 |
+
function wplnst_require($section, $filename) {
|
21 |
+
require_once(WPLNST_PATH.'/'.$section.'/'.$filename.'.php');
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Requires multiple files for the same section
|
28 |
+
*/
|
29 |
+
function wplnst_require_section($section, $filenames) {
|
30 |
+
foreach ($filenames as $filename)
|
31 |
+
wplnst_require($section, $filename);
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Return a numeric setting
|
38 |
+
*/
|
39 |
+
function wplnst_get_nsetting($name, $value = 0) {
|
40 |
+
return WPLNST_Core_Settings::get_nsetting($name, $value);
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Return a boolean setting
|
47 |
+
*/
|
48 |
+
function wplnst_get_bsetting($name, $default = false) {
|
49 |
+
return WPLNST_Core_Settings::get_bsetting($name, $default);
|
50 |
+
}
|
51 |
+
|
52 |
+
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Return a text setting
|
56 |
+
*/
|
57 |
+
function wplnst_get_tsetting($name, $default = true) {
|
58 |
+
return WPLNST_Core_Settings::get_tsetting($name, $default);
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Check if cURL is enabled in this system
|
65 |
+
*/
|
66 |
+
function wplnst_is_curl_enabled() {
|
67 |
+
|
68 |
+
// Last status
|
69 |
+
static $is_enabled;
|
70 |
+
if (isset($is_enabled))
|
71 |
+
return $is_enabled;
|
72 |
+
|
73 |
+
// Simple check, but it may have been overwritten
|
74 |
+
if (!function_exists('curl_version')) {
|
75 |
+
$is_enabled = false;
|
76 |
+
return false;
|
77 |
+
}
|
78 |
+
|
79 |
+
// Check extension
|
80 |
+
$extensions = @get_loaded_extensions();
|
81 |
+
if (!empty($extensions) && is_array($extensions) && in_array('curl', $extensions)) {
|
82 |
+
$is_enabled = true;
|
83 |
+
return true;
|
84 |
+
}
|
85 |
+
|
86 |
+
// Not found
|
87 |
+
$is_enabled = false;
|
88 |
+
return false;
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Check debug flag
|
95 |
+
*/
|
96 |
+
function wplnst_is_debug() {
|
97 |
+
return (defined('WPLNST_DEBUG') && WPLNST_DEBUG);
|
98 |
+
}
|
99 |
+
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Output plugin debug
|
104 |
+
*/
|
105 |
+
function wplnst_debug($message, $tag = '') {
|
106 |
+
|
107 |
+
// Check debug
|
108 |
+
if (!wplnst_is_debug())
|
109 |
+
return;
|
110 |
+
|
111 |
+
// Default output
|
112 |
+
if (!defined('WPLNST_DEBUG_OUTPUT') || 'error_log' == WPLNST_DEBUG_OUTPUT)
|
113 |
+
error_log('WPLNST'.(empty($tag)? '' : ' ['.$tag.']').' - '.$message);
|
114 |
+
}
|
languages/wp-link-status.pot
ADDED
@@ -0,0 +1,2821 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: WP Link Status\n"
|
4 |
+
"POT-Creation-Date: 2016-01-21 10:36+0100\n"
|
5 |
+
"PO-Revision-Date: 2016-01-21 10:36+0100\n"
|
6 |
+
"Last-Translator: Pau Iglesias <pauiglesias@gmail.com>\n"
|
7 |
+
"Language-Team: \n"
|
8 |
+
"Language: en_US\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.5.4\n"
|
13 |
+
"X-Poedit-KeywordsList: __;_e;__ngettext;_n;__ngettext_noop;_n_noop;_x;_nx;"
|
14 |
+
"_nx_noop;_ex;esc_attr__;esc_attr_e;esc_attr_x;esc_html__;esc_html_e;"
|
15 |
+
"esc_html_x\n"
|
16 |
+
"X-Poedit-Basepath: .\n"
|
17 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
18 |
+
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
19 |
+
"X-Poedit-SearchPath-0: ..\n"
|
20 |
+
|
21 |
+
#: ../admin-pro/scans.php:51
|
22 |
+
#, php-format
|
23 |
+
msgid "Processing <b>%s</b>"
|
24 |
+
msgstr ""
|
25 |
+
|
26 |
+
#: ../admin-pro/scans.php:59 ../admin-pro/scans.php:67
|
27 |
+
msgid "Close"
|
28 |
+
msgstr ""
|
29 |
+
|
30 |
+
#: ../admin-pro/scans.php:76
|
31 |
+
msgid "Update URL"
|
32 |
+
msgstr ""
|
33 |
+
|
34 |
+
#: ../admin-pro/scans.php:77 ../admin-pro/scans.php:88
|
35 |
+
#: ../admin-pro/scans.php:99 ../admin-pro/scans.php:110
|
36 |
+
#: ../admin-pro/scans.php:121 ../admin-pro/scans.php:132
|
37 |
+
#: ../admin-pro/scans.php:143 ../admin-pro/scans.php:154
|
38 |
+
#: ../admin-pro/scans.php:165 ../admin-pro/scans.php:176
|
39 |
+
#: ../admin-pro/scans.php:187 ../admin-pro/scans.php:198
|
40 |
+
#: ../admin-pro/scans.php:209 ../admin-pro/scans.php:220
|
41 |
+
#: ../admin-pro/scans.php:231 ../views-pro/tools-url.php:21
|
42 |
+
msgid "Cancel"
|
43 |
+
msgstr ""
|
44 |
+
|
45 |
+
#: ../admin-pro/scans.php:85
|
46 |
+
msgid "Confirm <b>Unlink this URL</b>"
|
47 |
+
msgstr ""
|
48 |
+
|
49 |
+
#: ../admin-pro/scans.php:87 ../admin-pro/scans.php:98
|
50 |
+
#: ../admin-pro/scans.php:282 ../views-pro/scans-results.php:42
|
51 |
+
msgid "Unlink"
|
52 |
+
msgstr ""
|
53 |
+
|
54 |
+
#: ../admin-pro/scans.php:96
|
55 |
+
msgid "Confirm <b>Unlink selected URLs</b>"
|
56 |
+
msgstr ""
|
57 |
+
|
58 |
+
#: ../admin-pro/scans.php:107
|
59 |
+
msgid "Confirm <b>Ignore this link</b>"
|
60 |
+
msgstr ""
|
61 |
+
|
62 |
+
#: ../admin-pro/scans.php:109 ../admin-pro/scans.php:120
|
63 |
+
#: ../admin-pro/scans.php:291 ../views-pro/scans-results.php:43
|
64 |
+
msgid "Ignore"
|
65 |
+
msgstr ""
|
66 |
+
|
67 |
+
#: ../admin-pro/scans.php:118
|
68 |
+
msgid "Confirm <b>Ignore selected results</b>"
|
69 |
+
msgstr ""
|
70 |
+
|
71 |
+
#: ../admin-pro/scans.php:129
|
72 |
+
msgid "Confirm <b>Undo Ignore this link</b>"
|
73 |
+
msgstr ""
|
74 |
+
|
75 |
+
#: ../admin-pro/scans.php:131 ../admin-pro/scans.php:142
|
76 |
+
#: ../admin-pro/scans.php:292 ../views-pro/scans-results.php:44
|
77 |
+
msgid "Undo Ignore"
|
78 |
+
msgstr ""
|
79 |
+
|
80 |
+
#: ../admin-pro/scans.php:140
|
81 |
+
msgid "Confirm <b>Undo Ignore selected results</b>"
|
82 |
+
msgstr ""
|
83 |
+
|
84 |
+
#: ../admin-pro/scans.php:151
|
85 |
+
msgid "Confirm <b>Apply Redirection</b>"
|
86 |
+
msgstr ""
|
87 |
+
|
88 |
+
#: ../admin-pro/scans.php:153
|
89 |
+
msgid "Set Redirection"
|
90 |
+
msgstr ""
|
91 |
+
|
92 |
+
#: ../admin-pro/scans.php:162
|
93 |
+
msgid "Confirm <b>Bulk apply redirections</b>"
|
94 |
+
msgstr ""
|
95 |
+
|
96 |
+
#: ../admin-pro/scans.php:164
|
97 |
+
msgid "Set Redirections"
|
98 |
+
msgstr ""
|
99 |
+
|
100 |
+
#: ../admin-pro/scans.php:173
|
101 |
+
msgid "Confirm <b>Add nofollow</b>"
|
102 |
+
msgstr ""
|
103 |
+
|
104 |
+
#: ../admin-pro/scans.php:175 ../admin-pro/scans.php:186
|
105 |
+
#: ../admin-pro/scans.php:286 ../views-pro/scans-results.php:48
|
106 |
+
msgid "Add nofollow"
|
107 |
+
msgstr ""
|
108 |
+
|
109 |
+
#: ../admin-pro/scans.php:184
|
110 |
+
msgid "Confirm <b>Bulk add nofollow</b>"
|
111 |
+
msgstr ""
|
112 |
+
|
113 |
+
#: ../admin-pro/scans.php:195
|
114 |
+
msgid "Confirm <b>Remove nofollow</b>"
|
115 |
+
msgstr ""
|
116 |
+
|
117 |
+
#: ../admin-pro/scans.php:197 ../admin-pro/scans.php:208
|
118 |
+
#: ../admin-pro/scans.php:287 ../views-pro/scans-results.php:49
|
119 |
+
msgid "Remove nofollow"
|
120 |
+
msgstr ""
|
121 |
+
|
122 |
+
#: ../admin-pro/scans.php:206
|
123 |
+
msgid "Confirm <b>Bulk remove nofollow</b>"
|
124 |
+
msgstr ""
|
125 |
+
|
126 |
+
#: ../admin-pro/scans.php:219
|
127 |
+
msgid "Update anchor text"
|
128 |
+
msgstr ""
|
129 |
+
|
130 |
+
#: ../admin-pro/scans.php:228
|
131 |
+
msgid "Confirm <b>Recheck URL status</b>"
|
132 |
+
msgstr ""
|
133 |
+
|
134 |
+
#: ../admin-pro/scans.php:230 ../admin-pro/scans.php:312
|
135 |
+
#: ../views-pro/scans-results.php:46
|
136 |
+
msgid "Recheck status"
|
137 |
+
msgstr ""
|
138 |
+
|
139 |
+
#: ../admin-pro/scans.php:237
|
140 |
+
msgid "Link headers"
|
141 |
+
msgstr ""
|
142 |
+
|
143 |
+
#: ../admin-pro/scans.php:243
|
144 |
+
msgid "Response headers"
|
145 |
+
msgstr ""
|
146 |
+
|
147 |
+
#: ../admin-pro/scans.php:245
|
148 |
+
msgid "Request headers"
|
149 |
+
msgstr ""
|
150 |
+
|
151 |
+
#: ../admin-pro/scans.php:274 ../views-pro/scans-results.php:41
|
152 |
+
msgid "Edit URL"
|
153 |
+
msgstr ""
|
154 |
+
|
155 |
+
#: ../admin-pro/scans.php:278 ../views-pro/scans-results.php:47
|
156 |
+
#: ../views/scans-results.php:910
|
157 |
+
msgid "Apply Redirection"
|
158 |
+
msgstr ""
|
159 |
+
|
160 |
+
#: ../admin-pro/scans.php:282 ../views-pro/tools-url.php:38
|
161 |
+
msgid "Remove link but leave anchor text"
|
162 |
+
msgstr ""
|
163 |
+
|
164 |
+
#: ../admin-pro/scans.php:282
|
165 |
+
msgid "Remove image from content"
|
166 |
+
msgstr ""
|
167 |
+
|
168 |
+
#: ../admin-pro/scans.php:282
|
169 |
+
msgid "Remove"
|
170 |
+
msgstr ""
|
171 |
+
|
172 |
+
#: ../admin-pro/scans.php:295 ../admin/scans.php:387
|
173 |
+
#: ../views/scans-results.php:844
|
174 |
+
msgid "Visit"
|
175 |
+
msgstr ""
|
176 |
+
|
177 |
+
#: ../admin-pro/scans.php:315
|
178 |
+
msgid "Show headers"
|
179 |
+
msgstr ""
|
180 |
+
|
181 |
+
#: ../admin-pro/scans.php:332
|
182 |
+
msgid "Edit anchor text"
|
183 |
+
msgstr ""
|
184 |
+
|
185 |
+
#: ../admin-pro/tools-url.php:23 ../admin-pro/admin.php:57
|
186 |
+
msgid "URL Tools"
|
187 |
+
msgstr ""
|
188 |
+
|
189 |
+
#: ../core/text.php:32
|
190 |
+
msgid "Scans"
|
191 |
+
msgstr ""
|
192 |
+
|
193 |
+
#: ../core/text.php:36
|
194 |
+
msgid "New scan"
|
195 |
+
msgstr ""
|
196 |
+
|
197 |
+
#: ../core/text.php:40
|
198 |
+
msgid "Add new scan"
|
199 |
+
msgstr ""
|
200 |
+
|
201 |
+
#: ../core/text.php:44 ../views/scans.php:434
|
202 |
+
msgid "Edit scan"
|
203 |
+
msgstr ""
|
204 |
+
|
205 |
+
#: ../core/text.php:48
|
206 |
+
msgid "Delete scan"
|
207 |
+
msgstr ""
|
208 |
+
|
209 |
+
#: ../core/text.php:52
|
210 |
+
msgid "Do you want to remove this scan?"
|
211 |
+
msgstr ""
|
212 |
+
|
213 |
+
#: ../core/text.php:56
|
214 |
+
msgid "Crawler action"
|
215 |
+
msgstr ""
|
216 |
+
|
217 |
+
#: ../core/text.php:60
|
218 |
+
msgid "Crawler results"
|
219 |
+
msgstr ""
|
220 |
+
|
221 |
+
#: ../core/text.php:64
|
222 |
+
msgid "Settings"
|
223 |
+
msgstr ""
|
224 |
+
|
225 |
+
#: ../core/text.php:68
|
226 |
+
#, php-format
|
227 |
+
msgid ""
|
228 |
+
"Sorry, maximum of <strong>%d running scans</strong> achieved and the scan "
|
229 |
+
"has been enqueued, it will be launched as soon as possible."
|
230 |
+
msgstr ""
|
231 |
+
|
232 |
+
#: ../core/text.php:72
|
233 |
+
#, php-format
|
234 |
+
msgid ""
|
235 |
+
"Sorry, scan not found. Please go to the <a href=\"%s\">scans list screen</a> "
|
236 |
+
"and select another scan."
|
237 |
+
msgstr ""
|
238 |
+
|
239 |
+
#: ../core/text.php:76
|
240 |
+
msgid ""
|
241 |
+
"Sorry, <strong>invalid form data</strong>. Please, <a href=\"javascript:"
|
242 |
+
"history.back();\">go back</a>, reload the last page and try again."
|
243 |
+
msgstr ""
|
244 |
+
|
245 |
+
#: ../core/text.php:80
|
246 |
+
msgid ""
|
247 |
+
"Sorry, <strong>invalid security data</strong>. Please, <a href=\"javascript:"
|
248 |
+
"history.back();\">go back</a>, reload the last page and try again."
|
249 |
+
msgstr ""
|
250 |
+
|
251 |
+
#: ../core/text.php:84
|
252 |
+
msgid "Server communication error"
|
253 |
+
msgstr ""
|
254 |
+
|
255 |
+
#: ../core/text.php:88
|
256 |
+
msgid "Unknown error"
|
257 |
+
msgstr ""
|
258 |
+
|
259 |
+
#: ../core/scans.php:236
|
260 |
+
#, php-format
|
261 |
+
msgid "%s comments"
|
262 |
+
msgstr ""
|
263 |
+
|
264 |
+
#: ../core/scans.php:238
|
265 |
+
#, php-format
|
266 |
+
msgid "%s and %s comments"
|
267 |
+
msgstr ""
|
268 |
+
|
269 |
+
#: ../core/scans.php:244 ../core/types.php:102
|
270 |
+
msgid "Blogroll"
|
271 |
+
msgstr ""
|
272 |
+
|
273 |
+
#: ../core/scans.php:362
|
274 |
+
msgid ""
|
275 |
+
"There is not any <strong>link type</strong> selected, you need to select one "
|
276 |
+
"or more."
|
277 |
+
msgstr ""
|
278 |
+
|
279 |
+
#: ../core/scans.php:371
|
280 |
+
msgid ""
|
281 |
+
"Need to select any <strong>post status</strong> value for the selected post "
|
282 |
+
"types."
|
283 |
+
msgstr ""
|
284 |
+
|
285 |
+
#: ../core/scans.php:377
|
286 |
+
msgid ""
|
287 |
+
"There is not any kind of <strong>post type</strong>, <strong>comments</"
|
288 |
+
"strong> or <strong>blogroll</strong> selected."
|
289 |
+
msgstr ""
|
290 |
+
|
291 |
+
#: ../core/scans.php:383
|
292 |
+
msgid ""
|
293 |
+
"Missing selection of any <strong>links status</strong> level or status code."
|
294 |
+
msgstr ""
|
295 |
+
|
296 |
+
#: ../core/types-curl.php:41
|
297 |
+
msgid "Ok"
|
298 |
+
msgstr ""
|
299 |
+
|
300 |
+
#: ../core/types-curl.php:41
|
301 |
+
msgid "All fine. Proceed as usual."
|
302 |
+
msgstr ""
|
303 |
+
|
304 |
+
#: ../core/types-curl.php:42
|
305 |
+
msgid "Unsupported protocol"
|
306 |
+
msgstr ""
|
307 |
+
|
308 |
+
#: ../core/types-curl.php:42
|
309 |
+
msgid ""
|
310 |
+
"The URL you passed to libcurl used a protocol that this libcurl does not "
|
311 |
+
"support. The support might be a compile-time option that you didn't use, it "
|
312 |
+
"can be a misspelled protocol string or just a protocol libcurl has no code "
|
313 |
+
"for."
|
314 |
+
msgstr ""
|
315 |
+
|
316 |
+
#: ../core/types-curl.php:43
|
317 |
+
msgid "Failed initialization"
|
318 |
+
msgstr ""
|
319 |
+
|
320 |
+
#: ../core/types-curl.php:43
|
321 |
+
msgid ""
|
322 |
+
"Very early initialization code failed. This is likely to be an internal "
|
323 |
+
"error or problem, or a resource problem where something fundamental couldn't "
|
324 |
+
"get done at init time."
|
325 |
+
msgstr ""
|
326 |
+
|
327 |
+
#: ../core/types-curl.php:44
|
328 |
+
msgid "URL malformat"
|
329 |
+
msgstr ""
|
330 |
+
|
331 |
+
#: ../core/types-curl.php:44
|
332 |
+
msgid "The URL was not properly formatted."
|
333 |
+
msgstr ""
|
334 |
+
|
335 |
+
#: ../core/types-curl.php:45
|
336 |
+
msgid "Not built-in"
|
337 |
+
msgstr ""
|
338 |
+
|
339 |
+
#: ../core/types-curl.php:45
|
340 |
+
msgid ""
|
341 |
+
"A requested feature, protocol or option was not found built-in in this "
|
342 |
+
"libcurl due to a build-time decision. This means that a feature or option "
|
343 |
+
"was not enabled or explicitly disabled when libcurl was built and in order "
|
344 |
+
"to get it to function you have to get a rebuilt libcurl."
|
345 |
+
msgstr ""
|
346 |
+
|
347 |
+
#: ../core/types-curl.php:46
|
348 |
+
msgid "Couldn't resolve proxy"
|
349 |
+
msgstr ""
|
350 |
+
|
351 |
+
#: ../core/types-curl.php:46
|
352 |
+
msgid "The given proxy host could not be resolved. "
|
353 |
+
msgstr ""
|
354 |
+
|
355 |
+
#: ../core/types-curl.php:47
|
356 |
+
msgid "Couldn't resolve host"
|
357 |
+
msgstr ""
|
358 |
+
|
359 |
+
#: ../core/types-curl.php:47
|
360 |
+
msgid "The given remote host was not resolved."
|
361 |
+
msgstr ""
|
362 |
+
|
363 |
+
#: ../core/types-curl.php:48
|
364 |
+
msgid "Couldn't connect"
|
365 |
+
msgstr ""
|
366 |
+
|
367 |
+
#: ../core/types-curl.php:48
|
368 |
+
msgid "Failed to connect() to host or proxy."
|
369 |
+
msgstr ""
|
370 |
+
|
371 |
+
#: ../core/types-curl.php:49
|
372 |
+
msgid "FTP weird server reply"
|
373 |
+
msgstr ""
|
374 |
+
|
375 |
+
#: ../core/types-curl.php:49
|
376 |
+
msgid ""
|
377 |
+
"After connecting to a FTP server, libcurl expects to get a certain reply "
|
378 |
+
"back. This error code implies that it got a strange or bad reply. The given "
|
379 |
+
"remote server is probably not an OK FTP server."
|
380 |
+
msgstr ""
|
381 |
+
|
382 |
+
#: ../core/types-curl.php:50
|
383 |
+
msgid "Remote access denied"
|
384 |
+
msgstr ""
|
385 |
+
|
386 |
+
#: ../core/types-curl.php:50
|
387 |
+
msgid ""
|
388 |
+
"We were denied access to the resource given in the URL. For FTP, this occurs "
|
389 |
+
"while trying to change to the remote directory."
|
390 |
+
msgstr ""
|
391 |
+
|
392 |
+
#: ../core/types-curl.php:51
|
393 |
+
msgid "FTP access failed"
|
394 |
+
msgstr ""
|
395 |
+
|
396 |
+
#: ../core/types-curl.php:51
|
397 |
+
msgid ""
|
398 |
+
"While waiting for the server to connect back when an active FTP session is "
|
399 |
+
"used, an error code was sent over the control connection or similar."
|
400 |
+
msgstr ""
|
401 |
+
|
402 |
+
#: ../core/types-curl.php:52
|
403 |
+
msgid "FTP weird pass reply"
|
404 |
+
msgstr ""
|
405 |
+
|
406 |
+
#: ../core/types-curl.php:52
|
407 |
+
msgid ""
|
408 |
+
"After having sent the FTP password to the server, libcurl expects a proper "
|
409 |
+
"reply. This error code indicates that an unexpected code was returned."
|
410 |
+
msgstr ""
|
411 |
+
|
412 |
+
#: ../core/types-curl.php:53
|
413 |
+
msgid "FTP accept timeout"
|
414 |
+
msgstr ""
|
415 |
+
|
416 |
+
#: ../core/types-curl.php:53
|
417 |
+
msgid ""
|
418 |
+
"During an active FTP session while waiting for the server to connect, the "
|
419 |
+
"CURLOPT_ACCEPTTIMEOUT_MS (or the internal default) timeout expired."
|
420 |
+
msgstr ""
|
421 |
+
|
422 |
+
#: ../core/types-curl.php:54
|
423 |
+
msgid "FTP weird pasv reply"
|
424 |
+
msgstr ""
|
425 |
+
|
426 |
+
#: ../core/types-curl.php:54
|
427 |
+
msgid ""
|
428 |
+
"libcurl failed to get a sensible result back from the server as a response "
|
429 |
+
"to either a PASV or a EPSV command. The server is flawed."
|
430 |
+
msgstr ""
|
431 |
+
|
432 |
+
#: ../core/types-curl.php:55
|
433 |
+
msgid "FTP weird 227 format"
|
434 |
+
msgstr ""
|
435 |
+
|
436 |
+
#: ../core/types-curl.php:55
|
437 |
+
msgid ""
|
438 |
+
"FTP servers return a 227-line as a response to a PASV command. If libcurl "
|
439 |
+
"fails to parse that line, this return code is passed back."
|
440 |
+
msgstr ""
|
441 |
+
|
442 |
+
#: ../core/types-curl.php:56
|
443 |
+
msgid "FTP can't get host"
|
444 |
+
msgstr ""
|
445 |
+
|
446 |
+
#: ../core/types-curl.php:56
|
447 |
+
msgid "An internal failure to lookup the host used for the new connection."
|
448 |
+
msgstr ""
|
449 |
+
|
450 |
+
#: ../core/types-curl.php:57
|
451 |
+
msgid "HTTP2 framing layer problem"
|
452 |
+
msgstr ""
|
453 |
+
|
454 |
+
#: ../core/types-curl.php:57
|
455 |
+
msgid ""
|
456 |
+
"A problem was detected in the HTTP2 framing layer. This is somewhat generic "
|
457 |
+
"and can be one out of several problems, see the error buffer for details."
|
458 |
+
msgstr ""
|
459 |
+
|
460 |
+
#: ../core/types-curl.php:58
|
461 |
+
msgid "FTP couldn't set type"
|
462 |
+
msgstr ""
|
463 |
+
|
464 |
+
#: ../core/types-curl.php:58
|
465 |
+
msgid ""
|
466 |
+
"Received an error when trying to set the transfer mode to binary or ASCII."
|
467 |
+
msgstr ""
|
468 |
+
|
469 |
+
#: ../core/types-curl.php:59
|
470 |
+
msgid "Partial file"
|
471 |
+
msgstr ""
|
472 |
+
|
473 |
+
#: ../core/types-curl.php:59
|
474 |
+
msgid ""
|
475 |
+
"A file transfer was shorter or larger than expected. This happens when the "
|
476 |
+
"server first reports an expected transfer size, and then delivers data that "
|
477 |
+
"doesn't match the previously given size."
|
478 |
+
msgstr ""
|
479 |
+
|
480 |
+
#: ../core/types-curl.php:60
|
481 |
+
msgid "FTP couldn't retrieve file"
|
482 |
+
msgstr ""
|
483 |
+
|
484 |
+
#: ../core/types-curl.php:60
|
485 |
+
msgid ""
|
486 |
+
"This was either a weird reply to a 'RETR' command or a zero byte transfer "
|
487 |
+
"complete."
|
488 |
+
msgstr ""
|
489 |
+
|
490 |
+
#: ../core/types-curl.php:61
|
491 |
+
msgid "Quote error"
|
492 |
+
msgstr ""
|
493 |
+
|
494 |
+
#: ../core/types-curl.php:61
|
495 |
+
msgid ""
|
496 |
+
"When sending custom 'QUOTE' commands to the remote server, one of the "
|
497 |
+
"commands returned an error code that was 400 or higher (for FTP) or "
|
498 |
+
"otherwise indicated unsuccessful completion of the command."
|
499 |
+
msgstr ""
|
500 |
+
|
501 |
+
#: ../core/types-curl.php:62
|
502 |
+
msgid "HTTP returned error"
|
503 |
+
msgstr ""
|
504 |
+
|
505 |
+
#: ../core/types-curl.php:62
|
506 |
+
msgid ""
|
507 |
+
"This is returned if CURLOPT_FAILONERROR is set TRUE and the HTTP server "
|
508 |
+
"returns an error code that is >= 400."
|
509 |
+
msgstr ""
|
510 |
+
|
511 |
+
#: ../core/types-curl.php:63
|
512 |
+
msgid "Write error"
|
513 |
+
msgstr ""
|
514 |
+
|
515 |
+
#: ../core/types-curl.php:63
|
516 |
+
msgid ""
|
517 |
+
"An error occurred when writing received data to a local file, or an error "
|
518 |
+
"was returned to libcurl from a write callback."
|
519 |
+
msgstr ""
|
520 |
+
|
521 |
+
#: ../core/types-curl.php:64
|
522 |
+
msgid "Upload failed"
|
523 |
+
msgstr ""
|
524 |
+
|
525 |
+
#: ../core/types-curl.php:64
|
526 |
+
msgid ""
|
527 |
+
"Failed starting the upload. For FTP, the server typically denied the STOR "
|
528 |
+
"command. The error buffer usually contains the server's explanation for this."
|
529 |
+
msgstr ""
|
530 |
+
|
531 |
+
#: ../core/types-curl.php:65
|
532 |
+
msgid "Read error"
|
533 |
+
msgstr ""
|
534 |
+
|
535 |
+
#: ../core/types-curl.php:65
|
536 |
+
msgid ""
|
537 |
+
"There was a problem reading a local file or an error returned by the read "
|
538 |
+
"callback."
|
539 |
+
msgstr ""
|
540 |
+
|
541 |
+
#: ../core/types-curl.php:66
|
542 |
+
msgid "Out of memory"
|
543 |
+
msgstr ""
|
544 |
+
|
545 |
+
#: ../core/types-curl.php:66
|
546 |
+
msgid ""
|
547 |
+
"A memory allocation request failed. This is serious badness and things are "
|
548 |
+
"severely screwed up if this ever occurs."
|
549 |
+
msgstr ""
|
550 |
+
|
551 |
+
#: ../core/types-curl.php:67
|
552 |
+
msgid "Operation timedout"
|
553 |
+
msgstr ""
|
554 |
+
|
555 |
+
#: ../core/types-curl.php:67
|
556 |
+
msgid "The specified time-out period was reached according to the conditions."
|
557 |
+
msgstr ""
|
558 |
+
|
559 |
+
#: ../core/types-curl.php:68
|
560 |
+
msgid "FTP port failed"
|
561 |
+
msgstr ""
|
562 |
+
|
563 |
+
#: ../core/types-curl.php:68
|
564 |
+
msgid ""
|
565 |
+
"The FTP PORT command returned error. This mostly happens when you haven't "
|
566 |
+
"specified a good enough address for libcurl to use. See CURLOPT_FTPPORT."
|
567 |
+
msgstr ""
|
568 |
+
|
569 |
+
#: ../core/types-curl.php:69
|
570 |
+
msgid "FTP couldn't use REST"
|
571 |
+
msgstr ""
|
572 |
+
|
573 |
+
#: ../core/types-curl.php:69
|
574 |
+
msgid ""
|
575 |
+
"The FTP REST command returned error. This should never happen if the server "
|
576 |
+
"is sane."
|
577 |
+
msgstr ""
|
578 |
+
|
579 |
+
#: ../core/types-curl.php:70
|
580 |
+
msgid "Range error"
|
581 |
+
msgstr ""
|
582 |
+
|
583 |
+
#: ../core/types-curl.php:70
|
584 |
+
msgid "The server does not support or accept range requests."
|
585 |
+
msgstr ""
|
586 |
+
|
587 |
+
#: ../core/types-curl.php:71
|
588 |
+
msgid "HTTP post error"
|
589 |
+
msgstr ""
|
590 |
+
|
591 |
+
#: ../core/types-curl.php:71
|
592 |
+
msgid "This is an odd error that mainly occurs due to internal confusion."
|
593 |
+
msgstr ""
|
594 |
+
|
595 |
+
#: ../core/types-curl.php:72
|
596 |
+
msgid "SSL connect error"
|
597 |
+
msgstr ""
|
598 |
+
|
599 |
+
#: ../core/types-curl.php:72
|
600 |
+
msgid ""
|
601 |
+
"A problem occurred somewhere in the SSL/TLS handshake. You really want the "
|
602 |
+
"error buffer and read the message there as it pinpoints the problem slightly "
|
603 |
+
"more. Could be certificates (file formats, paths, permissions), passwords, "
|
604 |
+
"and others."
|
605 |
+
msgstr ""
|
606 |
+
|
607 |
+
#: ../core/types-curl.php:73
|
608 |
+
msgid "Bad download resume"
|
609 |
+
msgstr ""
|
610 |
+
|
611 |
+
#: ../core/types-curl.php:73
|
612 |
+
msgid ""
|
613 |
+
"The download could not be resumed because the specified offset was out of "
|
614 |
+
"the file boundary."
|
615 |
+
msgstr ""
|
616 |
+
|
617 |
+
#: ../core/types-curl.php:74
|
618 |
+
msgid "File couldn't read file"
|
619 |
+
msgstr ""
|
620 |
+
|
621 |
+
#: ../core/types-curl.php:74
|
622 |
+
msgid ""
|
623 |
+
"A file given with FILE:// couldn't be opened. Most likely because the file "
|
624 |
+
"path doesn't identify an existing file. Did you check file permissions?"
|
625 |
+
msgstr ""
|
626 |
+
|
627 |
+
#: ../core/types-curl.php:75
|
628 |
+
msgid "LDAP cannot bind"
|
629 |
+
msgstr ""
|
630 |
+
|
631 |
+
#: ../core/types-curl.php:75
|
632 |
+
msgid "LDAP cannot bind. LDAP bind operation failed."
|
633 |
+
msgstr ""
|
634 |
+
|
635 |
+
#: ../core/types-curl.php:76
|
636 |
+
msgid "LDAP search failed"
|
637 |
+
msgstr ""
|
638 |
+
|
639 |
+
#: ../core/types-curl.php:76
|
640 |
+
msgid "LDAP search failed."
|
641 |
+
msgstr ""
|
642 |
+
|
643 |
+
#: ../core/types-curl.php:77
|
644 |
+
msgid "Function not found"
|
645 |
+
msgstr ""
|
646 |
+
|
647 |
+
#: ../core/types-curl.php:77
|
648 |
+
msgid "Function not found. A required zlib function was not found."
|
649 |
+
msgstr ""
|
650 |
+
|
651 |
+
#: ../core/types-curl.php:78
|
652 |
+
msgid "Aborted by callback"
|
653 |
+
msgstr ""
|
654 |
+
|
655 |
+
#: ../core/types-curl.php:78
|
656 |
+
msgid "Aborted by callback. A callback returned 'abort' to libcurl."
|
657 |
+
msgstr ""
|
658 |
+
|
659 |
+
#: ../core/types-curl.php:79
|
660 |
+
msgid "Bad function argument"
|
661 |
+
msgstr ""
|
662 |
+
|
663 |
+
#: ../core/types-curl.php:79
|
664 |
+
msgid "Internal error. A function was called with a bad parameter."
|
665 |
+
msgstr ""
|
666 |
+
|
667 |
+
#: ../core/types-curl.php:80
|
668 |
+
msgid "Interface failed"
|
669 |
+
msgstr ""
|
670 |
+
|
671 |
+
#: ../core/types-curl.php:80
|
672 |
+
msgid ""
|
673 |
+
"Interface error. A specified outgoing interface could not be used. Set which "
|
674 |
+
"interface to use for outgoing connections source IP address with "
|
675 |
+
"CURLOPT_INTERFACE."
|
676 |
+
msgstr ""
|
677 |
+
|
678 |
+
#: ../core/types-curl.php:81
|
679 |
+
msgid "Too many redirections"
|
680 |
+
msgstr ""
|
681 |
+
|
682 |
+
#: ../core/types-curl.php:81
|
683 |
+
msgid ""
|
684 |
+
"Too many redirects. When following redirects, libcurl hit the maximum "
|
685 |
+
"amount. Set your limit with CURLOPT_MAXREDIRS."
|
686 |
+
msgstr ""
|
687 |
+
|
688 |
+
#: ../core/types-curl.php:82
|
689 |
+
msgid "Unknown option"
|
690 |
+
msgstr ""
|
691 |
+
|
692 |
+
#: ../core/types-curl.php:82
|
693 |
+
msgid ""
|
694 |
+
"An option passed to libcurl is not recognized/known. Refer to the "
|
695 |
+
"appropriate documentation. This is most likely a problem in the program that "
|
696 |
+
"uses libcurl. The error buffer might contain more specific information about "
|
697 |
+
"which exact option it concerns."
|
698 |
+
msgstr ""
|
699 |
+
|
700 |
+
#: ../core/types-curl.php:83
|
701 |
+
msgid "Telnet option syntax"
|
702 |
+
msgstr ""
|
703 |
+
|
704 |
+
#: ../core/types-curl.php:83
|
705 |
+
msgid "A telnet option string was Illegally formatted."
|
706 |
+
msgstr ""
|
707 |
+
|
708 |
+
#: ../core/types-curl.php:84
|
709 |
+
msgid "Peer failed verification"
|
710 |
+
msgstr ""
|
711 |
+
|
712 |
+
#: ../core/types-curl.php:84
|
713 |
+
msgid ""
|
714 |
+
"The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK."
|
715 |
+
msgstr ""
|
716 |
+
|
717 |
+
#: ../core/types-curl.php:85
|
718 |
+
msgid "Got nothing"
|
719 |
+
msgstr ""
|
720 |
+
|
721 |
+
#: ../core/types-curl.php:85
|
722 |
+
msgid ""
|
723 |
+
"Nothing was returned from the server, and under the circumstances, getting "
|
724 |
+
"nothing is considered an error."
|
725 |
+
msgstr ""
|
726 |
+
|
727 |
+
#: ../core/types-curl.php:86
|
728 |
+
msgid "SSL engine not found"
|
729 |
+
msgstr ""
|
730 |
+
|
731 |
+
#: ../core/types-curl.php:86
|
732 |
+
msgid "The specified crypto engine wasn't found."
|
733 |
+
msgstr ""
|
734 |
+
|
735 |
+
#: ../core/types-curl.php:87
|
736 |
+
msgid "SSL engine set failed"
|
737 |
+
msgstr ""
|
738 |
+
|
739 |
+
#: ../core/types-curl.php:87
|
740 |
+
msgid "Failed setting the selected SSL crypto engine as default!"
|
741 |
+
msgstr ""
|
742 |
+
|
743 |
+
#: ../core/types-curl.php:88
|
744 |
+
msgid "Send error"
|
745 |
+
msgstr ""
|
746 |
+
|
747 |
+
#: ../core/types-curl.php:88
|
748 |
+
msgid "Failed sending network data."
|
749 |
+
msgstr ""
|
750 |
+
|
751 |
+
#: ../core/types-curl.php:89
|
752 |
+
msgid "Receive error"
|
753 |
+
msgstr ""
|
754 |
+
|
755 |
+
#: ../core/types-curl.php:89
|
756 |
+
msgid "Failure with receiving network data."
|
757 |
+
msgstr ""
|
758 |
+
|
759 |
+
#: ../core/types-curl.php:90
|
760 |
+
msgid "Certificate problem"
|
761 |
+
msgstr ""
|
762 |
+
|
763 |
+
#: ../core/types-curl.php:90
|
764 |
+
msgid "Problem with the local client certificate. "
|
765 |
+
msgstr ""
|
766 |
+
|
767 |
+
#: ../core/types-curl.php:91
|
768 |
+
msgid "SSL cipher"
|
769 |
+
msgstr ""
|
770 |
+
|
771 |
+
#: ../core/types-curl.php:91
|
772 |
+
msgid "Couldn't use specified cipher."
|
773 |
+
msgstr ""
|
774 |
+
|
775 |
+
#: ../core/types-curl.php:92
|
776 |
+
msgid "SSL CA certificate"
|
777 |
+
msgstr ""
|
778 |
+
|
779 |
+
#: ../core/types-curl.php:92
|
780 |
+
msgid "Peer certificate cannot be authenticated with known CA certificates."
|
781 |
+
msgstr ""
|
782 |
+
|
783 |
+
#: ../core/types-curl.php:93
|
784 |
+
msgid "Bad content encoding"
|
785 |
+
msgstr ""
|
786 |
+
|
787 |
+
#: ../core/types-curl.php:93
|
788 |
+
msgid "Unrecognized transfer encoding."
|
789 |
+
msgstr ""
|
790 |
+
|
791 |
+
#: ../core/types-curl.php:94
|
792 |
+
msgid "LDAP invalid URL"
|
793 |
+
msgstr ""
|
794 |
+
|
795 |
+
#: ../core/types-curl.php:94
|
796 |
+
msgid "Invalid LDAP URL."
|
797 |
+
msgstr ""
|
798 |
+
|
799 |
+
#: ../core/types-curl.php:95
|
800 |
+
msgid "File size exceeded"
|
801 |
+
msgstr ""
|
802 |
+
|
803 |
+
#: ../core/types-curl.php:95
|
804 |
+
msgid "Maximum file size exceeded."
|
805 |
+
msgstr ""
|
806 |
+
|
807 |
+
#: ../core/types-curl.php:96
|
808 |
+
msgid "Use SSL failed"
|
809 |
+
msgstr ""
|
810 |
+
|
811 |
+
#: ../core/types-curl.php:96
|
812 |
+
msgid "Requested FTP SSL level failed. "
|
813 |
+
msgstr ""
|
814 |
+
|
815 |
+
#: ../core/types-curl.php:97
|
816 |
+
msgid "Send fail rewind"
|
817 |
+
msgstr ""
|
818 |
+
|
819 |
+
#: ../core/types-curl.php:97
|
820 |
+
msgid ""
|
821 |
+
"When doing a send operation curl had to rewind the data to retransmit, but "
|
822 |
+
"the rewinding operation failed."
|
823 |
+
msgstr ""
|
824 |
+
|
825 |
+
#: ../core/types-curl.php:98
|
826 |
+
msgid "SSL initialization failed"
|
827 |
+
msgstr ""
|
828 |
+
|
829 |
+
#: ../core/types-curl.php:98
|
830 |
+
msgid "Initiating the SSL Engine failed."
|
831 |
+
msgstr ""
|
832 |
+
|
833 |
+
#: ../core/types-curl.php:99
|
834 |
+
msgid "Login denied"
|
835 |
+
msgstr ""
|
836 |
+
|
837 |
+
#: ../core/types-curl.php:99
|
838 |
+
msgid "The remote server denied curl to login (Added in 7.13.1)"
|
839 |
+
msgstr ""
|
840 |
+
|
841 |
+
#: ../core/types-curl.php:100
|
842 |
+
msgid "TFTP file not found"
|
843 |
+
msgstr ""
|
844 |
+
|
845 |
+
#: ../core/types-curl.php:100
|
846 |
+
msgid "File not found on TFTP server."
|
847 |
+
msgstr ""
|
848 |
+
|
849 |
+
#: ../core/types-curl.php:101
|
850 |
+
msgid "TFTP permission"
|
851 |
+
msgstr ""
|
852 |
+
|
853 |
+
#: ../core/types-curl.php:101
|
854 |
+
msgid "Permission problem on TFTP server."
|
855 |
+
msgstr ""
|
856 |
+
|
857 |
+
#: ../core/types-curl.php:102
|
858 |
+
msgid "Remote disk full"
|
859 |
+
msgstr ""
|
860 |
+
|
861 |
+
#: ../core/types-curl.php:102
|
862 |
+
msgid "Out of disk space on the server."
|
863 |
+
msgstr ""
|
864 |
+
|
865 |
+
#: ../core/types-curl.php:103
|
866 |
+
msgid "TFTP illegal"
|
867 |
+
msgstr ""
|
868 |
+
|
869 |
+
#: ../core/types-curl.php:103
|
870 |
+
msgid "Illegal TFTP operation."
|
871 |
+
msgstr ""
|
872 |
+
|
873 |
+
#: ../core/types-curl.php:104
|
874 |
+
msgid "FTP unknown ID"
|
875 |
+
msgstr ""
|
876 |
+
|
877 |
+
#: ../core/types-curl.php:104
|
878 |
+
msgid "Unknown TFTP transfer ID."
|
879 |
+
msgstr ""
|
880 |
+
|
881 |
+
#: ../core/types-curl.php:105
|
882 |
+
msgid "Remote file exists"
|
883 |
+
msgstr ""
|
884 |
+
|
885 |
+
#: ../core/types-curl.php:105
|
886 |
+
msgid "File already exists and will not be overwritten."
|
887 |
+
msgstr ""
|
888 |
+
|
889 |
+
#: ../core/types-curl.php:106
|
890 |
+
msgid "TFTP no such user"
|
891 |
+
msgstr ""
|
892 |
+
|
893 |
+
#: ../core/types-curl.php:106
|
894 |
+
msgid ""
|
895 |
+
"This error should never be returned by a properly functioning TFTP server."
|
896 |
+
msgstr ""
|
897 |
+
|
898 |
+
#: ../core/types-curl.php:107
|
899 |
+
msgid "Conversion failed"
|
900 |
+
msgstr ""
|
901 |
+
|
902 |
+
#: ../core/types-curl.php:107
|
903 |
+
msgid "Character conversion failed."
|
904 |
+
msgstr ""
|
905 |
+
|
906 |
+
#: ../core/types-curl.php:108
|
907 |
+
msgid "Conversion callbacks"
|
908 |
+
msgstr ""
|
909 |
+
|
910 |
+
#: ../core/types-curl.php:108
|
911 |
+
msgid "Caller must register conversion callbacks."
|
912 |
+
msgstr ""
|
913 |
+
|
914 |
+
#: ../core/types-curl.php:109
|
915 |
+
msgid "SSL CA certificate bad file"
|
916 |
+
msgstr ""
|
917 |
+
|
918 |
+
#: ../core/types-curl.php:109
|
919 |
+
msgid "Problem with reading the SSL CA cert (path? access rights?)"
|
920 |
+
msgstr ""
|
921 |
+
|
922 |
+
#: ../core/types-curl.php:110
|
923 |
+
msgid "Remote file not found"
|
924 |
+
msgstr ""
|
925 |
+
|
926 |
+
#: ../core/types-curl.php:110
|
927 |
+
msgid "The resource referenced in the URL does not exist."
|
928 |
+
msgstr ""
|
929 |
+
|
930 |
+
#: ../core/types-curl.php:111
|
931 |
+
msgid "SSH error"
|
932 |
+
msgstr ""
|
933 |
+
|
934 |
+
#: ../core/types-curl.php:111
|
935 |
+
msgid "An unspecified error occurred during the SSH session."
|
936 |
+
msgstr ""
|
937 |
+
|
938 |
+
#: ../core/types-curl.php:112
|
939 |
+
msgid "SSL shutdown failed"
|
940 |
+
msgstr ""
|
941 |
+
|
942 |
+
#: ../core/types-curl.php:112
|
943 |
+
msgid "Failed to shut down the SSL connection."
|
944 |
+
msgstr ""
|
945 |
+
|
946 |
+
#: ../core/types-curl.php:113
|
947 |
+
msgid "Socket not ready"
|
948 |
+
msgstr ""
|
949 |
+
|
950 |
+
#: ../core/types-curl.php:113
|
951 |
+
msgid ""
|
952 |
+
"Socket is not ready for send/recv wait till it's ready and try again. This "
|
953 |
+
"return code is only returned from curl_easy_recv and curl_easy_send (Added "
|
954 |
+
"in 7.18.2)"
|
955 |
+
msgstr ""
|
956 |
+
|
957 |
+
#: ../core/types-curl.php:114
|
958 |
+
msgid "SSL CRL bad file"
|
959 |
+
msgstr ""
|
960 |
+
|
961 |
+
#: ../core/types-curl.php:114
|
962 |
+
msgid "Failed to load CRL file (Added in 7.19.0)"
|
963 |
+
msgstr ""
|
964 |
+
|
965 |
+
#: ../core/types-curl.php:115
|
966 |
+
msgid "SSL issue error"
|
967 |
+
msgstr ""
|
968 |
+
|
969 |
+
#: ../core/types-curl.php:115
|
970 |
+
msgid "Issuer check failed (Added in 7.19.0)"
|
971 |
+
msgstr ""
|
972 |
+
|
973 |
+
#: ../core/types-curl.php:116
|
974 |
+
msgid "FTP PRET failed"
|
975 |
+
msgstr ""
|
976 |
+
|
977 |
+
#: ../core/types-curl.php:116
|
978 |
+
msgid ""
|
979 |
+
"The FTP server does not understand the PRET command at all or does not "
|
980 |
+
"support the given argument. Be careful when using CURLOPT_CUSTOMREQUEST, a "
|
981 |
+
"custom LIST command will be sent with PRET CMD before PASV as well. (Added "
|
982 |
+
"in 7.20.0)"
|
983 |
+
msgstr ""
|
984 |
+
|
985 |
+
#: ../core/types-curl.php:117
|
986 |
+
msgid "RTSP CSEQ error"
|
987 |
+
msgstr ""
|
988 |
+
|
989 |
+
#: ../core/types-curl.php:117
|
990 |
+
msgid "Mismatch of RTSP CSeq numbers."
|
991 |
+
msgstr ""
|
992 |
+
|
993 |
+
#: ../core/types-curl.php:118
|
994 |
+
msgid "RTSP session error"
|
995 |
+
msgstr ""
|
996 |
+
|
997 |
+
#: ../core/types-curl.php:118
|
998 |
+
msgid "Mismatch of RTSP Session Identifiers."
|
999 |
+
msgstr ""
|
1000 |
+
|
1001 |
+
#: ../core/types-curl.php:119
|
1002 |
+
msgid "FTP bad file list"
|
1003 |
+
msgstr ""
|
1004 |
+
|
1005 |
+
#: ../core/types-curl.php:119
|
1006 |
+
msgid "Unable to parse FTP file list (during FTP wildcard downloading)."
|
1007 |
+
msgstr ""
|
1008 |
+
|
1009 |
+
#: ../core/types-curl.php:120
|
1010 |
+
msgid "Chunk failed"
|
1011 |
+
msgstr ""
|
1012 |
+
|
1013 |
+
#: ../core/types-curl.php:120
|
1014 |
+
msgid "Chunk callback reported error."
|
1015 |
+
msgstr ""
|
1016 |
+
|
1017 |
+
#: ../core/types-curl.php:121
|
1018 |
+
msgid "No connection available"
|
1019 |
+
msgstr ""
|
1020 |
+
|
1021 |
+
#: ../core/types-curl.php:121
|
1022 |
+
msgid ""
|
1023 |
+
"(For internal use only, will never be returned by libcurl) No connection "
|
1024 |
+
"available, the session will be queued. (added in 7.30.0)"
|
1025 |
+
msgstr ""
|
1026 |
+
|
1027 |
+
#: ../core/boot.php:14
|
1028 |
+
msgid ""
|
1029 |
+
"Detected another version of WP Link Status already active. Please deactivate "
|
1030 |
+
"it before and try again to activate this plugin."
|
1031 |
+
msgstr ""
|
1032 |
+
|
1033 |
+
#: ../core/boot.php:20
|
1034 |
+
msgid "Sorry, this version of WP Link Status requires WordPress 3.3 or later."
|
1035 |
+
msgstr ""
|
1036 |
+
|
1037 |
+
#: ../core/notify.php:91
|
1038 |
+
msgid "WP Link Status scan completed"
|
1039 |
+
msgstr ""
|
1040 |
+
|
1041 |
+
#: ../core/notify.php:92
|
1042 |
+
#, php-format
|
1043 |
+
msgid ""
|
1044 |
+
"\n"
|
1045 |
+
"\n"
|
1046 |
+
"Your scan is completed, you can see the results here:\n"
|
1047 |
+
"\n"
|
1048 |
+
"%s\n"
|
1049 |
+
"%s\n"
|
1050 |
+
"\n"
|
1051 |
+
msgstr ""
|
1052 |
+
|
1053 |
+
#: ../core/notify.php:99 ../views/scans.php:375
|
1054 |
+
msgid "(no name)"
|
1055 |
+
msgstr ""
|
1056 |
+
|
1057 |
+
#: ../core/types.php:100
|
1058 |
+
msgid "Entries"
|
1059 |
+
msgstr ""
|
1060 |
+
|
1061 |
+
#: ../core/types.php:101
|
1062 |
+
msgid "Comments"
|
1063 |
+
msgstr ""
|
1064 |
+
|
1065 |
+
#: ../core/types.php:113
|
1066 |
+
msgid "Waiting"
|
1067 |
+
msgstr ""
|
1068 |
+
|
1069 |
+
#: ../core/types.php:114
|
1070 |
+
msgid "Queued"
|
1071 |
+
msgstr ""
|
1072 |
+
|
1073 |
+
#: ../core/types.php:115
|
1074 |
+
msgid "Running"
|
1075 |
+
msgstr ""
|
1076 |
+
|
1077 |
+
#: ../core/types.php:116
|
1078 |
+
msgid "Stopped"
|
1079 |
+
msgstr ""
|
1080 |
+
|
1081 |
+
#: ../core/types.php:117
|
1082 |
+
msgid "Completed"
|
1083 |
+
msgstr ""
|
1084 |
+
|
1085 |
+
#: ../core/types.php:128
|
1086 |
+
msgid "All URLs"
|
1087 |
+
msgstr ""
|
1088 |
+
|
1089 |
+
#: ../core/types.php:129
|
1090 |
+
msgid "Internal URLs"
|
1091 |
+
msgstr ""
|
1092 |
+
|
1093 |
+
#: ../core/types.php:130
|
1094 |
+
msgid "External URLs"
|
1095 |
+
msgstr ""
|
1096 |
+
|
1097 |
+
#: ../core/types.php:141
|
1098 |
+
msgid "Anytime content"
|
1099 |
+
msgstr ""
|
1100 |
+
|
1101 |
+
#: ../core/types.php:142
|
1102 |
+
msgid "From yesterday"
|
1103 |
+
msgstr ""
|
1104 |
+
|
1105 |
+
#: ../core/types.php:143
|
1106 |
+
msgid "Last 7 days"
|
1107 |
+
msgstr ""
|
1108 |
+
|
1109 |
+
#: ../core/types.php:144
|
1110 |
+
msgid "Last 15 days"
|
1111 |
+
msgstr ""
|
1112 |
+
|
1113 |
+
#: ../core/types.php:145
|
1114 |
+
msgid "One month"
|
1115 |
+
msgstr ""
|
1116 |
+
|
1117 |
+
#: ../core/types.php:146
|
1118 |
+
msgid "Last 3 months"
|
1119 |
+
msgstr ""
|
1120 |
+
|
1121 |
+
#: ../core/types.php:147
|
1122 |
+
msgid "Last 6 months"
|
1123 |
+
msgstr ""
|
1124 |
+
|
1125 |
+
#: ../core/types.php:148
|
1126 |
+
msgid "One year"
|
1127 |
+
msgstr ""
|
1128 |
+
|
1129 |
+
#: ../core/types.php:160
|
1130 |
+
msgid "Links"
|
1131 |
+
msgstr ""
|
1132 |
+
|
1133 |
+
#: ../core/types.php:161
|
1134 |
+
msgid "Images"
|
1135 |
+
msgstr ""
|
1136 |
+
|
1137 |
+
#: ../core/types.php:172
|
1138 |
+
msgid "Most recent content"
|
1139 |
+
msgstr ""
|
1140 |
+
|
1141 |
+
#: ../core/types.php:173
|
1142 |
+
msgid "Oldest content first"
|
1143 |
+
msgstr ""
|
1144 |
+
|
1145 |
+
#: ../core/types.php:196
|
1146 |
+
msgid "Approved"
|
1147 |
+
msgstr ""
|
1148 |
+
|
1149 |
+
#: ../core/types.php:197
|
1150 |
+
msgid "Pending"
|
1151 |
+
msgstr ""
|
1152 |
+
|
1153 |
+
#: ../core/types.php:223 ../core/types.php:295
|
1154 |
+
msgid "Contains"
|
1155 |
+
msgstr ""
|
1156 |
+
|
1157 |
+
#: ../core/types.php:224 ../core/types.php:296
|
1158 |
+
msgid "Not contains"
|
1159 |
+
msgstr ""
|
1160 |
+
|
1161 |
+
#: ../core/types.php:225
|
1162 |
+
msgid "Is equal to"
|
1163 |
+
msgstr ""
|
1164 |
+
|
1165 |
+
#: ../core/types.php:226 ../core/types.php:298
|
1166 |
+
msgid "Not equal to"
|
1167 |
+
msgstr ""
|
1168 |
+
|
1169 |
+
#: ../core/types.php:227 ../core/types.php:241
|
1170 |
+
msgid "Starts with"
|
1171 |
+
msgstr ""
|
1172 |
+
|
1173 |
+
#: ../core/types.php:228 ../core/types.php:242
|
1174 |
+
msgid "Ends by"
|
1175 |
+
msgstr ""
|
1176 |
+
|
1177 |
+
#: ../core/types.php:229 ../core/types.php:300
|
1178 |
+
msgid "Empty"
|
1179 |
+
msgstr ""
|
1180 |
+
|
1181 |
+
#: ../core/types.php:240 ../core/types.php:254 ../core/types.php:268
|
1182 |
+
msgid "Matched string"
|
1183 |
+
msgstr ""
|
1184 |
+
|
1185 |
+
#: ../core/types.php:243
|
1186 |
+
msgid "Full anchor"
|
1187 |
+
msgstr ""
|
1188 |
+
|
1189 |
+
#: ../core/types.php:255 ../core/types.php:269
|
1190 |
+
msgid "URL prefix"
|
1191 |
+
msgstr ""
|
1192 |
+
|
1193 |
+
#: ../core/types.php:256 ../core/types.php:270
|
1194 |
+
msgid "URL suffix"
|
1195 |
+
msgstr ""
|
1196 |
+
|
1197 |
+
#: ../core/types.php:257 ../core/types.php:272
|
1198 |
+
msgid "Full URL"
|
1199 |
+
msgstr ""
|
1200 |
+
|
1201 |
+
#: ../core/types.php:271
|
1202 |
+
msgid "URL fragment #"
|
1203 |
+
msgstr ""
|
1204 |
+
|
1205 |
+
#: ../core/types.php:283
|
1206 |
+
msgid "Has"
|
1207 |
+
msgstr ""
|
1208 |
+
|
1209 |
+
#: ../core/types.php:284
|
1210 |
+
msgid "Not have"
|
1211 |
+
msgstr ""
|
1212 |
+
|
1213 |
+
#: ../core/types.php:297
|
1214 |
+
msgid "Equals"
|
1215 |
+
msgstr ""
|
1216 |
+
|
1217 |
+
#: ../core/types.php:299
|
1218 |
+
msgid "Not empty"
|
1219 |
+
msgstr ""
|
1220 |
+
|
1221 |
+
#: ../core/types.php:311
|
1222 |
+
msgid "Success"
|
1223 |
+
msgstr ""
|
1224 |
+
|
1225 |
+
#: ../core/types.php:312
|
1226 |
+
msgid "Redirections"
|
1227 |
+
msgstr ""
|
1228 |
+
|
1229 |
+
#: ../core/types.php:313
|
1230 |
+
msgid "Errors"
|
1231 |
+
msgstr ""
|
1232 |
+
|
1233 |
+
#: ../core/types.php:314
|
1234 |
+
msgid "Server Error"
|
1235 |
+
msgstr ""
|
1236 |
+
|
1237 |
+
#: ../core/types.php:326
|
1238 |
+
msgid "OK"
|
1239 |
+
msgstr ""
|
1240 |
+
|
1241 |
+
#: ../core/types.php:327
|
1242 |
+
msgid "Created"
|
1243 |
+
msgstr ""
|
1244 |
+
|
1245 |
+
#: ../core/types.php:328
|
1246 |
+
msgid "Accepted"
|
1247 |
+
msgstr ""
|
1248 |
+
|
1249 |
+
#: ../core/types.php:329
|
1250 |
+
msgid "Non-Authoritative Information"
|
1251 |
+
msgstr ""
|
1252 |
+
|
1253 |
+
#: ../core/types.php:330
|
1254 |
+
msgid "No Content"
|
1255 |
+
msgstr ""
|
1256 |
+
|
1257 |
+
#: ../core/types.php:331
|
1258 |
+
msgid "Reset Content"
|
1259 |
+
msgstr ""
|
1260 |
+
|
1261 |
+
#: ../core/types.php:332
|
1262 |
+
msgid "Partial Content"
|
1263 |
+
msgstr ""
|
1264 |
+
|
1265 |
+
#: ../core/types.php:335
|
1266 |
+
msgid "Multiple Choices"
|
1267 |
+
msgstr ""
|
1268 |
+
|
1269 |
+
#: ../core/types.php:336
|
1270 |
+
msgid "Moved Permanently"
|
1271 |
+
msgstr ""
|
1272 |
+
|
1273 |
+
#: ../core/types.php:337
|
1274 |
+
msgid "Found"
|
1275 |
+
msgstr ""
|
1276 |
+
|
1277 |
+
#: ../core/types.php:338
|
1278 |
+
msgid "See Other"
|
1279 |
+
msgstr ""
|
1280 |
+
|
1281 |
+
#: ../core/types.php:339
|
1282 |
+
msgid "Not Modified"
|
1283 |
+
msgstr ""
|
1284 |
+
|
1285 |
+
#: ../core/types.php:340
|
1286 |
+
msgid "Use Proxy"
|
1287 |
+
msgstr ""
|
1288 |
+
|
1289 |
+
#: ../core/types.php:341
|
1290 |
+
msgid "Temporary Redirect"
|
1291 |
+
msgstr ""
|
1292 |
+
|
1293 |
+
#: ../core/types.php:344
|
1294 |
+
msgid "Bad Request"
|
1295 |
+
msgstr ""
|
1296 |
+
|
1297 |
+
#: ../core/types.php:345
|
1298 |
+
msgid "Unauthorized"
|
1299 |
+
msgstr ""
|
1300 |
+
|
1301 |
+
#: ../core/types.php:346
|
1302 |
+
msgid "Payment Required"
|
1303 |
+
msgstr ""
|
1304 |
+
|
1305 |
+
#: ../core/types.php:347
|
1306 |
+
msgid "Forbidden"
|
1307 |
+
msgstr ""
|
1308 |
+
|
1309 |
+
#: ../core/types.php:348
|
1310 |
+
msgid "Not Found"
|
1311 |
+
msgstr ""
|
1312 |
+
|
1313 |
+
#: ../core/types.php:349
|
1314 |
+
msgid "Method Not Allowed"
|
1315 |
+
msgstr ""
|
1316 |
+
|
1317 |
+
#: ../core/types.php:350
|
1318 |
+
msgid "Not Acceptable"
|
1319 |
+
msgstr ""
|
1320 |
+
|
1321 |
+
#: ../core/types.php:351
|
1322 |
+
msgid "Proxy Authentication Required"
|
1323 |
+
msgstr ""
|
1324 |
+
|
1325 |
+
#: ../core/types.php:352
|
1326 |
+
msgid "Request Timeout"
|
1327 |
+
msgstr ""
|
1328 |
+
|
1329 |
+
#: ../core/types.php:353
|
1330 |
+
msgid "Conflict"
|
1331 |
+
msgstr ""
|
1332 |
+
|
1333 |
+
#: ../core/types.php:354
|
1334 |
+
msgid "Gone"
|
1335 |
+
msgstr ""
|
1336 |
+
|
1337 |
+
#: ../core/types.php:355
|
1338 |
+
msgid "Length Required"
|
1339 |
+
msgstr ""
|
1340 |
+
|
1341 |
+
#: ../core/types.php:356
|
1342 |
+
msgid "Precondition Failed"
|
1343 |
+
msgstr ""
|
1344 |
+
|
1345 |
+
#: ../core/types.php:357
|
1346 |
+
msgid "Request Entity Too Large"
|
1347 |
+
msgstr ""
|
1348 |
+
|
1349 |
+
#: ../core/types.php:358
|
1350 |
+
msgid "Request-URI Too Long"
|
1351 |
+
msgstr ""
|
1352 |
+
|
1353 |
+
#: ../core/types.php:359
|
1354 |
+
msgid "Unsupported Media Type"
|
1355 |
+
msgstr ""
|
1356 |
+
|
1357 |
+
#: ../core/types.php:360
|
1358 |
+
msgid "Requested Range Not Satisfiable"
|
1359 |
+
msgstr ""
|
1360 |
+
|
1361 |
+
#: ../core/types.php:361
|
1362 |
+
msgid "Expectation Failed"
|
1363 |
+
msgstr ""
|
1364 |
+
|
1365 |
+
#: ../core/types.php:364
|
1366 |
+
msgid "Internal Server Error"
|
1367 |
+
msgstr ""
|
1368 |
+
|
1369 |
+
#: ../core/types.php:365
|
1370 |
+
msgid "Not Implemented"
|
1371 |
+
msgstr ""
|
1372 |
+
|
1373 |
+
#: ../core/types.php:366
|
1374 |
+
msgid "Bad Gateway"
|
1375 |
+
msgstr ""
|
1376 |
+
|
1377 |
+
#: ../core/types.php:367
|
1378 |
+
msgid "Service Unavailable"
|
1379 |
+
msgstr ""
|
1380 |
+
|
1381 |
+
#: ../core/types.php:368
|
1382 |
+
msgid "Gateway Timeout"
|
1383 |
+
msgstr ""
|
1384 |
+
|
1385 |
+
#: ../core/types.php:369
|
1386 |
+
msgid "HTTP Version Not Supported"
|
1387 |
+
msgstr ""
|
1388 |
+
|
1389 |
+
#: ../core/types.php:396
|
1390 |
+
msgid "NoFollow"
|
1391 |
+
msgstr ""
|
1392 |
+
|
1393 |
+
#: ../core/types.php:397
|
1394 |
+
msgid "DoFollow"
|
1395 |
+
msgstr ""
|
1396 |
+
|
1397 |
+
#: ../core/types.php:421 ../views/scans-results.php:265
|
1398 |
+
msgid "Relative"
|
1399 |
+
msgstr ""
|
1400 |
+
|
1401 |
+
#: ../core/types.php:422 ../views/scans-results.php:266
|
1402 |
+
msgid "Absolute"
|
1403 |
+
msgstr ""
|
1404 |
+
|
1405 |
+
#: ../core/types.php:423 ../views/scans-results.php:267
|
1406 |
+
msgid "Spaced"
|
1407 |
+
msgstr ""
|
1408 |
+
|
1409 |
+
#: ../core/types.php:424 ../views/scans.php:396 ../views/scans-results.php:268
|
1410 |
+
msgid "Malformed"
|
1411 |
+
msgstr ""
|
1412 |
+
|
1413 |
+
#: ../core/types.php:435 ../views/scans-results.php:182
|
1414 |
+
msgid "Unlinked"
|
1415 |
+
msgstr ""
|
1416 |
+
|
1417 |
+
#: ../core/types.php:436 ../views/scans-results.php:263
|
1418 |
+
#: ../views/scans-results.php:332
|
1419 |
+
msgid "Modified"
|
1420 |
+
msgstr ""
|
1421 |
+
|
1422 |
+
#: ../core/types.php:437
|
1423 |
+
msgid "Unmodified"
|
1424 |
+
msgstr ""
|
1425 |
+
|
1426 |
+
#: ../core/types.php:438
|
1427 |
+
msgid "Rechecked"
|
1428 |
+
msgstr ""
|
1429 |
+
|
1430 |
+
#: ../core/types.php:449
|
1431 |
+
msgid "Only ignored results"
|
1432 |
+
msgstr ""
|
1433 |
+
|
1434 |
+
#: ../core/types.php:450
|
1435 |
+
msgid "Ignored and not ignored"
|
1436 |
+
msgstr ""
|
1437 |
+
|
1438 |
+
#: ../core/types.php:461
|
1439 |
+
msgid "Domain name ASC"
|
1440 |
+
msgstr ""
|
1441 |
+
|
1442 |
+
#: ../core/types.php:462
|
1443 |
+
msgid "Domain name DESC"
|
1444 |
+
msgstr ""
|
1445 |
+
|
1446 |
+
#: ../core/types.php:463
|
1447 |
+
msgid "Download time ASC"
|
1448 |
+
msgstr ""
|
1449 |
+
|
1450 |
+
#: ../core/types.php:464
|
1451 |
+
msgid "Download time DESC"
|
1452 |
+
msgstr ""
|
1453 |
+
|
1454 |
+
#: ../core/types.php:465
|
1455 |
+
msgid "Download size ASC"
|
1456 |
+
msgstr ""
|
1457 |
+
|
1458 |
+
#: ../core/types.php:466
|
1459 |
+
msgid "Download size DESC"
|
1460 |
+
msgstr ""
|
1461 |
+
|
1462 |
+
#: ../core/module.php:143
|
1463 |
+
msgid "Sorry, current user can`t perform this action"
|
1464 |
+
msgstr ""
|
1465 |
+
|
1466 |
+
#: ../core/module.php:149
|
1467 |
+
msgid ""
|
1468 |
+
"Sorry, security verification error. Please reload this page and try again."
|
1469 |
+
msgstr ""
|
1470 |
+
|
1471 |
+
#: ../views-pro/tools-url.php:21
|
1472 |
+
msgid "WordPress database will be updated, press Ok to continue"
|
1473 |
+
msgstr ""
|
1474 |
+
|
1475 |
+
#: ../views-pro/tools-url.php:21
|
1476 |
+
msgid "Sorry, no links detected. Please enter some URLs."
|
1477 |
+
msgstr ""
|
1478 |
+
|
1479 |
+
#: ../views-pro/tools-url.php:21
|
1480 |
+
msgid "Processing"
|
1481 |
+
msgstr ""
|
1482 |
+
|
1483 |
+
#: ../views-pro/tools-url.php:21
|
1484 |
+
msgid "Updating database"
|
1485 |
+
msgstr ""
|
1486 |
+
|
1487 |
+
#: ../views-pro/tools-url.php:21
|
1488 |
+
msgid "Test mode, no database changes"
|
1489 |
+
msgstr ""
|
1490 |
+
|
1491 |
+
#: ../views-pro/tools-url.php:21
|
1492 |
+
msgid "No found entries"
|
1493 |
+
msgstr ""
|
1494 |
+
|
1495 |
+
#: ../views-pro/tools-url.php:21
|
1496 |
+
msgid "Cancelling"
|
1497 |
+
msgstr ""
|
1498 |
+
|
1499 |
+
#: ../views-pro/tools-url.php:21
|
1500 |
+
msgid "Cancelled"
|
1501 |
+
msgstr ""
|
1502 |
+
|
1503 |
+
#: ../views-pro/tools-url.php:21 ../views-pro/tools-url.php:59
|
1504 |
+
msgid "Finished"
|
1505 |
+
msgstr ""
|
1506 |
+
|
1507 |
+
#: ../views-pro/tools-url.php:21
|
1508 |
+
msgid "Processed"
|
1509 |
+
msgstr ""
|
1510 |
+
|
1511 |
+
#: ../views-pro/tools-url.php:21
|
1512 |
+
msgid "of"
|
1513 |
+
msgstr ""
|
1514 |
+
|
1515 |
+
#: ../views-pro/tools-url.php:21
|
1516 |
+
msgid "links"
|
1517 |
+
msgstr ""
|
1518 |
+
|
1519 |
+
#: ../views-pro/tools-url.php:21
|
1520 |
+
msgid "Back to the form"
|
1521 |
+
msgstr ""
|
1522 |
+
|
1523 |
+
#: ../views-pro/tools-url.php:27
|
1524 |
+
msgid "Enter here the URLs, one per line:"
|
1525 |
+
msgstr ""
|
1526 |
+
|
1527 |
+
#: ../views-pro/tools-url.php:34
|
1528 |
+
msgid "Select operation"
|
1529 |
+
msgstr ""
|
1530 |
+
|
1531 |
+
#: ../views-pro/tools-url.php:36
|
1532 |
+
msgid "Add link rel="nofollow""
|
1533 |
+
msgstr ""
|
1534 |
+
|
1535 |
+
#: ../views-pro/tools-url.php:37
|
1536 |
+
msgid "Remove "nofollow" from rel property"
|
1537 |
+
msgstr ""
|
1538 |
+
|
1539 |
+
#: ../views-pro/tools-url.php:39
|
1540 |
+
msgid "Replace URL by its 301 redirection"
|
1541 |
+
msgstr ""
|
1542 |
+
|
1543 |
+
#: ../views-pro/tools-url.php:40
|
1544 |
+
msgid "Remove <object> containing URL"
|
1545 |
+
msgstr ""
|
1546 |
+
|
1547 |
+
#: ../views-pro/tools-url.php:43
|
1548 |
+
msgid "Test mode, no database updates"
|
1549 |
+
msgstr ""
|
1550 |
+
|
1551 |
+
#: ../views-pro/tools-url.php:44
|
1552 |
+
msgid "Update changes in database"
|
1553 |
+
msgstr ""
|
1554 |
+
|
1555 |
+
#: ../views-pro/tools-url.php:49
|
1556 |
+
msgid "Execute Test Process"
|
1557 |
+
msgstr ""
|
1558 |
+
|
1559 |
+
#: ../views-pro/tools-url.php:51
|
1560 |
+
msgid "Execute Database Update"
|
1561 |
+
msgstr ""
|
1562 |
+
|
1563 |
+
#: ../views-pro/tools-url.php:64 ../views-pro/tools-url.php:71
|
1564 |
+
msgid "Link"
|
1565 |
+
msgstr ""
|
1566 |
+
|
1567 |
+
#: ../views-pro/tools-url.php:65 ../views-pro/tools-url.php:72
|
1568 |
+
#: ../views/scans-results.php:113 ../views/scans-edit.php:342
|
1569 |
+
#: ../views/scans-edit.php:343 ../views/scans-edit.php:352
|
1570 |
+
msgid "Anchor text"
|
1571 |
+
msgstr ""
|
1572 |
+
|
1573 |
+
#: ../views-pro/tools-url.php:66 ../views-pro/tools-url.php:73
|
1574 |
+
msgid "Result"
|
1575 |
+
msgstr ""
|
1576 |
+
|
1577 |
+
#: ../views-pro/scans-results.php:45
|
1578 |
+
msgid "Edit anchor"
|
1579 |
+
msgstr ""
|
1580 |
+
|
1581 |
+
#: ../views-pro/scans-results.php:88
|
1582 |
+
msgid "Toggle to the advanced search panel"
|
1583 |
+
msgstr ""
|
1584 |
+
|
1585 |
+
#: ../views-pro/scans-results.php:88
|
1586 |
+
msgid "Advanced Search"
|
1587 |
+
msgstr ""
|
1588 |
+
|
1589 |
+
#: ../views-pro/scans-results.php:91
|
1590 |
+
msgid "Bulk unlink URLs"
|
1591 |
+
msgstr ""
|
1592 |
+
|
1593 |
+
#: ../views-pro/scans-results.php:91
|
1594 |
+
msgid "Bulk ignore results"
|
1595 |
+
msgstr ""
|
1596 |
+
|
1597 |
+
#: ../views-pro/scans-results.php:91
|
1598 |
+
msgid "Bulk undo ignore results"
|
1599 |
+
msgstr ""
|
1600 |
+
|
1601 |
+
#: ../views-pro/scans-results.php:91
|
1602 |
+
msgid "Bulk anchor text edition"
|
1603 |
+
msgstr ""
|
1604 |
+
|
1605 |
+
#: ../views-pro/scans-results.php:91
|
1606 |
+
msgid "Bulk URL edition"
|
1607 |
+
msgstr ""
|
1608 |
+
|
1609 |
+
#: ../views-pro/scans-results.php:91
|
1610 |
+
msgid "Bulk URL recheck status"
|
1611 |
+
msgstr ""
|
1612 |
+
|
1613 |
+
#: ../views-pro/scans-results.php:91
|
1614 |
+
msgid "Bulk apply redirections"
|
1615 |
+
msgstr ""
|
1616 |
+
|
1617 |
+
#: ../views-pro/scans-results.php:91
|
1618 |
+
msgid "Bulk add nofollow"
|
1619 |
+
msgstr ""
|
1620 |
+
|
1621 |
+
#: ../views-pro/scans-results.php:91
|
1622 |
+
msgid "Bulk remove nofollow"
|
1623 |
+
msgstr ""
|
1624 |
+
|
1625 |
+
#: ../views-pro/scans-results.php:120
|
1626 |
+
msgid "Common filters"
|
1627 |
+
msgstr ""
|
1628 |
+
|
1629 |
+
#: ../views-pro/scans-results.php:130
|
1630 |
+
msgid "Extended"
|
1631 |
+
msgstr ""
|
1632 |
+
|
1633 |
+
#: ../views-pro/scans-results.php:158
|
1634 |
+
msgid "Filter Results"
|
1635 |
+
msgstr ""
|
1636 |
+
|
1637 |
+
#: ../views-pro/scans-results.php:170
|
1638 |
+
msgid "Close advanced search panel"
|
1639 |
+
msgstr ""
|
1640 |
+
|
1641 |
+
#: ../views-pro/scans-results.php:171
|
1642 |
+
msgid "Reset advanced search fields"
|
1643 |
+
msgstr ""
|
1644 |
+
|
1645 |
+
#: ../views-pro/scans-results.php:171
|
1646 |
+
msgid "Reset advanced search fields?"
|
1647 |
+
msgstr ""
|
1648 |
+
|
1649 |
+
#: ../views-pro/scans-results.php:199
|
1650 |
+
msgid "Not ignored results"
|
1651 |
+
msgstr ""
|
1652 |
+
|
1653 |
+
#: ../views-pro/scans-results.php:229
|
1654 |
+
msgid "SEO links"
|
1655 |
+
msgstr ""
|
1656 |
+
|
1657 |
+
#: ../views-pro/scans-results.php:244
|
1658 |
+
msgid "Protocol"
|
1659 |
+
msgstr ""
|
1660 |
+
|
1661 |
+
#: ../views-pro/scans-results.php:259
|
1662 |
+
msgid "Special"
|
1663 |
+
msgstr ""
|
1664 |
+
|
1665 |
+
#: ../views-pro/scans-results.php:274
|
1666 |
+
msgid "Action"
|
1667 |
+
msgstr ""
|
1668 |
+
|
1669 |
+
#: ../views-pro/scans-results.php:291
|
1670 |
+
msgid "External and internal URLs"
|
1671 |
+
msgstr ""
|
1672 |
+
|
1673 |
+
#: ../admin/scans.php:473
|
1674 |
+
msgid "The crawling process for this scan is already started."
|
1675 |
+
msgstr ""
|
1676 |
+
|
1677 |
+
#: ../admin/scans.php:479
|
1678 |
+
msgid "The crawling process for this scan is already stopped."
|
1679 |
+
msgstr ""
|
1680 |
+
|
1681 |
+
#: ../admin/scans.php:485
|
1682 |
+
msgid "This scan was ended and is not possible to start again."
|
1683 |
+
msgstr ""
|
1684 |
+
|
1685 |
+
#: ../admin/scans.php:500
|
1686 |
+
msgid "Something went wrong and the unqueue process was failed."
|
1687 |
+
msgstr ""
|
1688 |
+
|
1689 |
+
#: ../admin/scans.php:506
|
1690 |
+
msgid "The crawler for this scan is back to the wait mode."
|
1691 |
+
msgstr ""
|
1692 |
+
|
1693 |
+
#: ../admin/scans.php:516
|
1694 |
+
msgid "Something went wront and the crawler stop was failed."
|
1695 |
+
msgstr ""
|
1696 |
+
|
1697 |
+
#: ../admin/scans.php:522
|
1698 |
+
#, php-format
|
1699 |
+
msgid ""
|
1700 |
+
"The crawler for this scan is stopped. You can see its collected data in the "
|
1701 |
+
"<a href=\"%s\">crawler results page</a>."
|
1702 |
+
msgstr ""
|
1703 |
+
|
1704 |
+
#: ../admin/scans.php:542
|
1705 |
+
#, php-format
|
1706 |
+
msgid ""
|
1707 |
+
"You need to complete some critical values before start the crawler, please "
|
1708 |
+
"<a href=\"%s\">edit this scan</a>."
|
1709 |
+
msgstr ""
|
1710 |
+
|
1711 |
+
#: ../admin/scans.php:577
|
1712 |
+
msgid "Something went wront and the crawler start was failed."
|
1713 |
+
msgstr ""
|
1714 |
+
|
1715 |
+
#: ../admin/scans.php:597
|
1716 |
+
#, php-format
|
1717 |
+
msgid ""
|
1718 |
+
"The crawler is running, you can see its data in the <a href=\"%s\">crawler "
|
1719 |
+
"results page</a>."
|
1720 |
+
msgstr ""
|
1721 |
+
|
1722 |
+
#: ../admin/scans.php:668
|
1723 |
+
#, php-format
|
1724 |
+
msgid ""
|
1725 |
+
"Sorry, we need a confirmation action. Please click here to <a href=\"%s\" "
|
1726 |
+
"class=\"wplnst-scan-delete\" data-confirm=\"%s\">delete scan</a>"
|
1727 |
+
msgstr ""
|
1728 |
+
|
1729 |
+
#: ../admin/scans.php:695
|
1730 |
+
msgid "The scans have been removed."
|
1731 |
+
msgstr ""
|
1732 |
+
|
1733 |
+
#: ../admin/scans.php:713
|
1734 |
+
#, php-format
|
1735 |
+
msgid ""
|
1736 |
+
"Sorry, we need a confirmation action. Please click here to <a href=\"%s\" "
|
1737 |
+
"class=\"wplnst-scan-delete-isolated\" data-confirm-delete=\"%s\">delete "
|
1738 |
+
"scan</a>"
|
1739 |
+
msgstr ""
|
1740 |
+
|
1741 |
+
#: ../admin/scans.php:722
|
1742 |
+
msgid "The scan has been removed."
|
1743 |
+
msgstr ""
|
1744 |
+
|
1745 |
+
#: ../admin/scans.php:751
|
1746 |
+
msgid "Back to the scans list"
|
1747 |
+
msgstr ""
|
1748 |
+
|
1749 |
+
#: ../admin/scans.php:794
|
1750 |
+
msgid "New scan added successfully."
|
1751 |
+
msgstr ""
|
1752 |
+
|
1753 |
+
#: ../admin/scans.php:809
|
1754 |
+
msgid "Something went wrong trying to start the crawler for this new scan."
|
1755 |
+
msgstr ""
|
1756 |
+
|
1757 |
+
#: ../admin/scans.php:815
|
1758 |
+
#, php-format
|
1759 |
+
msgid ""
|
1760 |
+
"The crawler for this new scan is running. You can see its data in the <a "
|
1761 |
+
"href=\"%s\">crawler results page</a>."
|
1762 |
+
msgstr ""
|
1763 |
+
|
1764 |
+
#: ../admin/scans.php:823
|
1765 |
+
#, php-format
|
1766 |
+
msgid "From now on you can <a href=\"%s\">start the crawler</a>."
|
1767 |
+
msgstr ""
|
1768 |
+
|
1769 |
+
#: ../admin/scans-submit.php:143
|
1770 |
+
msgid ""
|
1771 |
+
"Something went wrong adding the new scan. Please <a href=\"javascript:"
|
1772 |
+
"history.back();\">go back</a> and attempt again to submit form."
|
1773 |
+
msgstr ""
|
1774 |
+
|
1775 |
+
#: ../admin/scans-submit.php:219
|
1776 |
+
msgid ""
|
1777 |
+
"Something went wrong updating the scan data. Please <a href=\"javascript:"
|
1778 |
+
"history.back();\">go back</a> and attempt again to save data."
|
1779 |
+
msgstr ""
|
1780 |
+
|
1781 |
+
#: ../admin/scans-submit.php:225
|
1782 |
+
msgid "Scan updated successfully."
|
1783 |
+
msgstr ""
|
1784 |
+
|
1785 |
+
#: ../admin/scans-submit.php:243
|
1786 |
+
msgid "Something went wrong trying to start the crawler."
|
1787 |
+
msgstr ""
|
1788 |
+
|
1789 |
+
#: ../admin/scans-submit.php:259
|
1790 |
+
#, php-format
|
1791 |
+
msgid ""
|
1792 |
+
"The crawler fot this scan is running. You can see its data in the <a href="
|
1793 |
+
"\"%s\">crawler results page</a>."
|
1794 |
+
msgstr ""
|
1795 |
+
|
1796 |
+
#: ../admin/scans-submit.php:267
|
1797 |
+
#, php-format
|
1798 |
+
msgid ""
|
1799 |
+
"The crawler for this scan is <strong>not started</strong>, you can <a href="
|
1800 |
+
"\"%s\">start the crawler</a> now."
|
1801 |
+
msgstr ""
|
1802 |
+
|
1803 |
+
#: ../admin/settings.php:52
|
1804 |
+
msgid "Settings updated"
|
1805 |
+
msgstr ""
|
1806 |
+
|
1807 |
+
#: ../admin/admin.php:256
|
1808 |
+
msgid "Scans per page"
|
1809 |
+
msgstr ""
|
1810 |
+
|
1811 |
+
#: ../admin/admin.php:262
|
1812 |
+
msgid "Crawler results per page"
|
1813 |
+
msgstr ""
|
1814 |
+
|
1815 |
+
#: ../admin/admin.php:341
|
1816 |
+
msgid ""
|
1817 |
+
"Not detected the required cURL module enabled. Please contact with your "
|
1818 |
+
"hosting provider in order to install cURL for PHP in this server."
|
1819 |
+
msgstr ""
|
1820 |
+
|
1821 |
+
#: ../views/scans.php:105
|
1822 |
+
msgid "Scan info"
|
1823 |
+
msgstr ""
|
1824 |
+
|
1825 |
+
#: ../views/scans.php:106
|
1826 |
+
msgid "Configuration"
|
1827 |
+
msgstr ""
|
1828 |
+
|
1829 |
+
#: ../views/scans.php:121
|
1830 |
+
msgid "Some critical values of this scan are not completed"
|
1831 |
+
msgstr ""
|
1832 |
+
|
1833 |
+
#: ../views/scans.php:134
|
1834 |
+
msgid "Waiting..."
|
1835 |
+
msgstr ""
|
1836 |
+
|
1837 |
+
#: ../views/scans.php:144
|
1838 |
+
msgid "entries"
|
1839 |
+
msgstr ""
|
1840 |
+
|
1841 |
+
#: ../views/scans.php:152
|
1842 |
+
msgid "comments"
|
1843 |
+
msgstr ""
|
1844 |
+
|
1845 |
+
#: ../views/scans.php:159
|
1846 |
+
msgid "blogroll"
|
1847 |
+
msgstr ""
|
1848 |
+
|
1849 |
+
#: ../views/scans.php:190
|
1850 |
+
#, php-format
|
1851 |
+
msgid "Today from %s"
|
1852 |
+
msgstr ""
|
1853 |
+
|
1854 |
+
#: ../views/scans.php:196
|
1855 |
+
#, php-format
|
1856 |
+
msgid "Yesterday at %s"
|
1857 |
+
msgstr ""
|
1858 |
+
|
1859 |
+
#: ../views/scans.php:202
|
1860 |
+
#, php-format
|
1861 |
+
msgid "%s at %s"
|
1862 |
+
msgstr ""
|
1863 |
+
|
1864 |
+
#: ../views/scans.php:228 ../views/scans.php:244
|
1865 |
+
#, php-format
|
1866 |
+
msgid "to %s"
|
1867 |
+
msgstr ""
|
1868 |
+
|
1869 |
+
#: ../views/scans.php:234
|
1870 |
+
#, php-format
|
1871 |
+
msgid "to today at %s"
|
1872 |
+
msgstr ""
|
1873 |
+
|
1874 |
+
#: ../views/scans.php:250
|
1875 |
+
#, php-format
|
1876 |
+
msgid "to yesterday at %s"
|
1877 |
+
msgstr ""
|
1878 |
+
|
1879 |
+
#: ../views/scans.php:257
|
1880 |
+
#, php-format
|
1881 |
+
msgid "until %s"
|
1882 |
+
msgstr ""
|
1883 |
+
|
1884 |
+
#: ../views/scans.php:263
|
1885 |
+
#, php-format
|
1886 |
+
msgid "until %s at %s"
|
1887 |
+
msgstr ""
|
1888 |
+
|
1889 |
+
#: ../views/scans.php:284
|
1890 |
+
#, php-format
|
1891 |
+
msgid "Running time %s"
|
1892 |
+
msgstr ""
|
1893 |
+
|
1894 |
+
#: ../views/scans.php:306
|
1895 |
+
#, php-format
|
1896 |
+
msgid "<strong>%s</strong> results"
|
1897 |
+
msgstr ""
|
1898 |
+
|
1899 |
+
#: ../views/scans.php:306
|
1900 |
+
msgid "No results"
|
1901 |
+
msgstr ""
|
1902 |
+
|
1903 |
+
#: ../views/scans.php:312
|
1904 |
+
#, php-format
|
1905 |
+
msgid "<strong>%s</strong> unique URLs"
|
1906 |
+
msgstr ""
|
1907 |
+
|
1908 |
+
#: ../views/scans.php:317
|
1909 |
+
#, php-format
|
1910 |
+
msgid "%s enqueued"
|
1911 |
+
msgstr ""
|
1912 |
+
|
1913 |
+
#: ../views/scans.php:321
|
1914 |
+
#, php-format
|
1915 |
+
msgid "%s processing"
|
1916 |
+
msgstr ""
|
1917 |
+
|
1918 |
+
#: ../views/scans.php:325
|
1919 |
+
#, php-format
|
1920 |
+
msgid "<strong>%s</strong> Request error"
|
1921 |
+
msgstr ""
|
1922 |
+
|
1923 |
+
#: ../views/scans.php:352
|
1924 |
+
#, php-format
|
1925 |
+
msgid "Created today at %s"
|
1926 |
+
msgstr ""
|
1927 |
+
|
1928 |
+
#: ../views/scans.php:358
|
1929 |
+
#, php-format
|
1930 |
+
msgid "Created yesterday at %s"
|
1931 |
+
msgstr ""
|
1932 |
+
|
1933 |
+
#: ../views/scans.php:364
|
1934 |
+
#, php-format
|
1935 |
+
msgid "Created %s at %s"
|
1936 |
+
msgstr ""
|
1937 |
+
|
1938 |
+
#: ../views/scans.php:380
|
1939 |
+
#, php-format
|
1940 |
+
msgid "Ready to <a href=\"%s\">start the crawler</a>"
|
1941 |
+
msgstr ""
|
1942 |
+
|
1943 |
+
#: ../views/scans.php:396
|
1944 |
+
msgid "Scope"
|
1945 |
+
msgstr ""
|
1946 |
+
|
1947 |
+
#: ../views/scans.php:396
|
1948 |
+
msgid "Order by"
|
1949 |
+
msgstr ""
|
1950 |
+
|
1951 |
+
#: ../views/scans.php:396
|
1952 |
+
msgid "Check redirection status"
|
1953 |
+
msgstr ""
|
1954 |
+
|
1955 |
+
#: ../views/scans.php:396
|
1956 |
+
msgid "Redirections not checked"
|
1957 |
+
msgstr ""
|
1958 |
+
|
1959 |
+
#: ../views/scans.php:399 ../views/scans-edit.php:245
|
1960 |
+
#: ../views/scans-edit.php:252
|
1961 |
+
msgid "Post types"
|
1962 |
+
msgstr ""
|
1963 |
+
|
1964 |
+
#: ../views/scans.php:399 ../views/scans-edit.php:266
|
1965 |
+
#: ../views/scans-edit.php:273
|
1966 |
+
msgid "Post status"
|
1967 |
+
msgstr ""
|
1968 |
+
|
1969 |
+
#: ../views/scans.php:402
|
1970 |
+
msgid "Link status"
|
1971 |
+
msgstr ""
|
1972 |
+
|
1973 |
+
#: ../views/scans.php:431
|
1974 |
+
msgid "Show results"
|
1975 |
+
msgstr ""
|
1976 |
+
|
1977 |
+
#: ../views/scans.php:438
|
1978 |
+
msgid "Start crawler"
|
1979 |
+
msgstr ""
|
1980 |
+
|
1981 |
+
#: ../views/scans.php:438
|
1982 |
+
msgid "Unqueue crawling"
|
1983 |
+
msgstr ""
|
1984 |
+
|
1985 |
+
#: ../views/scans.php:438
|
1986 |
+
msgid "Stop crawler"
|
1987 |
+
msgstr ""
|
1988 |
+
|
1989 |
+
#: ../views/scans.php:461 ../views/scans-results.php:840
|
1990 |
+
msgid "Delete"
|
1991 |
+
msgstr ""
|
1992 |
+
|
1993 |
+
#: ../views/scans.php:498
|
1994 |
+
msgid "Do you want to remove these scans?"
|
1995 |
+
msgstr ""
|
1996 |
+
|
1997 |
+
#: ../views/settings.php:29
|
1998 |
+
msgid "Crawling"
|
1999 |
+
msgstr ""
|
2000 |
+
|
2001 |
+
#: ../views/settings.php:30
|
2002 |
+
msgid "Timing"
|
2003 |
+
msgstr ""
|
2004 |
+
|
2005 |
+
#: ../views/settings.php:31 ../views/scans-edit.php:93
|
2006 |
+
msgid "Advanced"
|
2007 |
+
msgstr ""
|
2008 |
+
|
2009 |
+
#: ../views/settings.php:40
|
2010 |
+
msgid "Number of crawler threads"
|
2011 |
+
msgstr ""
|
2012 |
+
|
2013 |
+
#: ../views/settings.php:42
|
2014 |
+
msgid ""
|
2015 |
+
"One thread means an HTTP request to your site only used for crawling "
|
2016 |
+
"purposes."
|
2017 |
+
msgstr ""
|
2018 |
+
|
2019 |
+
#: ../views/settings.php:45
|
2020 |
+
msgid "Max crawlers running"
|
2021 |
+
msgstr ""
|
2022 |
+
|
2023 |
+
#: ../views/settings.php:47
|
2024 |
+
msgid ""
|
2025 |
+
"Number of crawlers allowed to run simultaneously, each one with its own "
|
2026 |
+
"threads."
|
2027 |
+
msgstr ""
|
2028 |
+
|
2029 |
+
#: ../views/settings.php:50
|
2030 |
+
msgid "Max pack items"
|
2031 |
+
msgstr ""
|
2032 |
+
|
2033 |
+
#: ../views/settings.php:52
|
2034 |
+
msgid ""
|
2035 |
+
"Total objects (posts, comments or blogroll) processed in one single thread."
|
2036 |
+
msgstr ""
|
2037 |
+
|
2038 |
+
#: ../views/settings.php:55
|
2039 |
+
msgid "Max URL request attempts"
|
2040 |
+
msgstr ""
|
2041 |
+
|
2042 |
+
#: ../views/settings.php:57
|
2043 |
+
msgid "Number of HTTP requests attempts before set an URL as wrong."
|
2044 |
+
msgstr ""
|
2045 |
+
|
2046 |
+
#: ../views/settings.php:60
|
2047 |
+
msgid "Max redirections allowed"
|
2048 |
+
msgstr ""
|
2049 |
+
|
2050 |
+
#: ../views/settings.php:62
|
2051 |
+
msgid "Total redirections steps allowed to follow from original URL."
|
2052 |
+
msgstr ""
|
2053 |
+
|
2054 |
+
#: ../views/settings.php:65
|
2055 |
+
msgid "Max download size"
|
2056 |
+
msgstr ""
|
2057 |
+
|
2058 |
+
#: ../views/settings.php:67
|
2059 |
+
msgid "KB"
|
2060 |
+
msgstr ""
|
2061 |
+
|
2062 |
+
#: ../views/settings.php:67
|
2063 |
+
#, php-format
|
2064 |
+
msgid "(minimum value of %s KB and max value of %s KB)."
|
2065 |
+
msgstr ""
|
2066 |
+
|
2067 |
+
#: ../views/settings.php:70
|
2068 |
+
msgid "Default User Agent"
|
2069 |
+
msgstr ""
|
2070 |
+
|
2071 |
+
#: ../views/settings.php:81
|
2072 |
+
msgid "URL Connection timeout"
|
2073 |
+
msgstr ""
|
2074 |
+
|
2075 |
+
#: ../views/settings.php:83 ../views/settings.php:88 ../views/settings.php:93
|
2076 |
+
#: ../views/settings.php:98 ../views/settings.php:103
|
2077 |
+
#: ../views/settings.php:108 ../views/settings.php:113
|
2078 |
+
#: ../views/settings.php:118 ../views/scans-edit.php:516
|
2079 |
+
#: ../views/scans-edit.php:520 ../views/scans-edit.php:535
|
2080 |
+
#: ../views/scans-edit.php:539
|
2081 |
+
msgid "seconds"
|
2082 |
+
msgstr ""
|
2083 |
+
|
2084 |
+
#: ../views/settings.php:83
|
2085 |
+
msgid "Max time allowed to establish a connection with the URL host."
|
2086 |
+
msgstr ""
|
2087 |
+
|
2088 |
+
#: ../views/settings.php:86
|
2089 |
+
msgid "URL Request timeout"
|
2090 |
+
msgstr ""
|
2091 |
+
|
2092 |
+
#: ../views/settings.php:88
|
2093 |
+
msgid "Max time allowed to retrieve headers and body from one URL."
|
2094 |
+
msgstr ""
|
2095 |
+
|
2096 |
+
#: ../views/settings.php:91
|
2097 |
+
msgid "URL Extra timeout check"
|
2098 |
+
msgstr ""
|
2099 |
+
|
2100 |
+
#: ../views/settings.php:93 ../views/settings.php:98 ../views/settings.php:103
|
2101 |
+
#: ../views/settings.php:108 ../views/settings.php:113
|
2102 |
+
#: ../views/settings.php:118
|
2103 |
+
#, php-format
|
2104 |
+
msgid "(mininum value of %d seconds)"
|
2105 |
+
msgstr ""
|
2106 |
+
|
2107 |
+
#: ../views/settings.php:93
|
2108 |
+
msgid "A little grace period to avoid timeouts conflicts."
|
2109 |
+
msgstr ""
|
2110 |
+
|
2111 |
+
#: ../views/settings.php:96
|
2112 |
+
msgid "Check crawler alive each"
|
2113 |
+
msgstr ""
|
2114 |
+
|
2115 |
+
#: ../views/settings.php:98
|
2116 |
+
msgid "Checks if a crawler is interrupted and if so restart it."
|
2117 |
+
msgstr ""
|
2118 |
+
|
2119 |
+
#: ../views/settings.php:101
|
2120 |
+
msgid "Total objects check each"
|
2121 |
+
msgstr ""
|
2122 |
+
|
2123 |
+
#: ../views/settings.php:103
|
2124 |
+
msgid "Total of objects (posts, comments or blogroll) to check links."
|
2125 |
+
msgstr ""
|
2126 |
+
|
2127 |
+
#: ../views/settings.php:106
|
2128 |
+
msgid "Summary of status each"
|
2129 |
+
msgstr ""
|
2130 |
+
|
2131 |
+
#: ../views/settings.php:108
|
2132 |
+
msgid "Calculate status code totals to display data in real time."
|
2133 |
+
msgstr ""
|
2134 |
+
|
2135 |
+
#: ../views/settings.php:111
|
2136 |
+
msgid "Summary of URLs each"
|
2137 |
+
msgstr ""
|
2138 |
+
|
2139 |
+
#: ../views/settings.php:113
|
2140 |
+
msgid "Current number of URLs processed or waiting to be checked."
|
2141 |
+
msgstr ""
|
2142 |
+
|
2143 |
+
#: ../views/settings.php:116
|
2144 |
+
msgid "Summary of objects each"
|
2145 |
+
msgstr ""
|
2146 |
+
|
2147 |
+
#: ../views/settings.php:118
|
2148 |
+
msgid "Summary of objects (posts, comments or blogroll) with processed URLs."
|
2149 |
+
msgstr ""
|
2150 |
+
|
2151 |
+
#: ../views/settings.php:129
|
2152 |
+
msgid "Recursion limit"
|
2153 |
+
msgstr ""
|
2154 |
+
|
2155 |
+
#: ../views/settings.php:130
|
2156 |
+
msgid "function calls"
|
2157 |
+
msgstr ""
|
2158 |
+
|
2159 |
+
#: ../views/settings.php:133
|
2160 |
+
msgid "Data results pagination"
|
2161 |
+
msgstr ""
|
2162 |
+
|
2163 |
+
#: ../views/settings.php:134
|
2164 |
+
msgid "Use <code>SQL_CALC_FOUND_ROWS</code> to calculate total rows"
|
2165 |
+
msgstr ""
|
2166 |
+
|
2167 |
+
#: ../views/settings.php:141
|
2168 |
+
msgid "Save settings"
|
2169 |
+
msgstr ""
|
2170 |
+
|
2171 |
+
#: ../views/scans-results.php:112
|
2172 |
+
msgid "Status"
|
2173 |
+
msgstr ""
|
2174 |
+
|
2175 |
+
#: ../views/scans-results.php:114
|
2176 |
+
msgid "Content"
|
2177 |
+
msgstr ""
|
2178 |
+
|
2179 |
+
#: ../views/scans-results.php:213 ../views/scans-results.php:236
|
2180 |
+
#: ../core-pro/results.php:1876 ../core-pro/results.php:1889
|
2181 |
+
msgid "Error code "
|
2182 |
+
msgstr ""
|
2183 |
+
|
2184 |
+
#: ../views/scans-results.php:217 ../views/scans-results.php:240
|
2185 |
+
#, php-format
|
2186 |
+
msgid "error code %d"
|
2187 |
+
msgstr ""
|
2188 |
+
|
2189 |
+
#: ../views/scans-results.php:270
|
2190 |
+
msgid "Protocol relative"
|
2191 |
+
msgstr ""
|
2192 |
+
|
2193 |
+
#: ../views/scans-results.php:271
|
2194 |
+
msgid "Ignored"
|
2195 |
+
msgstr ""
|
2196 |
+
|
2197 |
+
#: ../views/scans-results.php:300 ../views/scans-results.php:316
|
2198 |
+
#: ../views/scans-results.php:1023 ../views/scans-results.php:1114
|
2199 |
+
#: ../core-pro/tools-url.php:644
|
2200 |
+
msgid "Request error"
|
2201 |
+
msgstr ""
|
2202 |
+
|
2203 |
+
#: ../views/scans-results.php:341
|
2204 |
+
msgid "Image"
|
2205 |
+
msgstr ""
|
2206 |
+
|
2207 |
+
#: ../views/scans-results.php:380
|
2208 |
+
#, php-format
|
2209 |
+
msgid "Edit “%s”"
|
2210 |
+
msgstr ""
|
2211 |
+
|
2212 |
+
#: ../views/scans-results.php:393
|
2213 |
+
#, php-format
|
2214 |
+
msgid "Entry %d not found"
|
2215 |
+
msgstr ""
|
2216 |
+
|
2217 |
+
#: ../views/scans-results.php:442
|
2218 |
+
#, php-format
|
2219 |
+
msgid "Comment %d not found"
|
2220 |
+
msgstr ""
|
2221 |
+
|
2222 |
+
#: ../views/scans-results.php:482
|
2223 |
+
#, php-format
|
2224 |
+
msgid "Bookmark %d not found"
|
2225 |
+
msgstr ""
|
2226 |
+
|
2227 |
+
#: ../views/scans-results.php:692
|
2228 |
+
msgid "Edit this item"
|
2229 |
+
msgstr ""
|
2230 |
+
|
2231 |
+
#: ../views/scans-results.php:692 ../views/scans-results.php:803
|
2232 |
+
#: ../views/scans-results.php:839
|
2233 |
+
msgid "Edit"
|
2234 |
+
msgstr ""
|
2235 |
+
|
2236 |
+
#: ../views/scans-results.php:699
|
2237 |
+
msgid "Restore this item from the Trash"
|
2238 |
+
msgstr ""
|
2239 |
+
|
2240 |
+
#: ../views/scans-results.php:699 ../views/scans-results.php:793
|
2241 |
+
msgid "Restore"
|
2242 |
+
msgstr ""
|
2243 |
+
|
2244 |
+
#: ../views/scans-results.php:703
|
2245 |
+
msgid "Move this item to the Trash"
|
2246 |
+
msgstr ""
|
2247 |
+
|
2248 |
+
#: ../views/scans-results.php:703 ../views/scans-results.php:799
|
2249 |
+
msgid "Trash"
|
2250 |
+
msgstr ""
|
2251 |
+
|
2252 |
+
#: ../views/scans-results.php:707
|
2253 |
+
msgid "Delete this item permanently"
|
2254 |
+
msgstr ""
|
2255 |
+
|
2256 |
+
#: ../views/scans-results.php:707 ../views/scans-results.php:797
|
2257 |
+
msgid "Delete Permanently"
|
2258 |
+
msgstr ""
|
2259 |
+
|
2260 |
+
#: ../views/scans-results.php:722
|
2261 |
+
#, php-format
|
2262 |
+
msgid "Preview “%s”"
|
2263 |
+
msgstr ""
|
2264 |
+
|
2265 |
+
#: ../views/scans-results.php:722
|
2266 |
+
msgid "Preview"
|
2267 |
+
msgstr ""
|
2268 |
+
|
2269 |
+
#: ../views/scans-results.php:727
|
2270 |
+
#, php-format
|
2271 |
+
msgid "View “%s”"
|
2272 |
+
msgstr ""
|
2273 |
+
|
2274 |
+
#: ../views/scans-results.php:727 ../views/scans-results.php:808
|
2275 |
+
msgid "View"
|
2276 |
+
msgstr ""
|
2277 |
+
|
2278 |
+
#: ../views/scans-results.php:781
|
2279 |
+
msgid "Unapprove this comment"
|
2280 |
+
msgstr ""
|
2281 |
+
|
2282 |
+
#: ../views/scans-results.php:781
|
2283 |
+
msgid "Unapprove"
|
2284 |
+
msgstr ""
|
2285 |
+
|
2286 |
+
#: ../views/scans-results.php:783
|
2287 |
+
msgid "Approve this comment"
|
2288 |
+
msgstr ""
|
2289 |
+
|
2290 |
+
#: ../views/scans-results.php:783
|
2291 |
+
msgid "Approve"
|
2292 |
+
msgstr ""
|
2293 |
+
|
2294 |
+
#: ../views/scans-results.php:787
|
2295 |
+
msgid "Mark this comment as spam"
|
2296 |
+
msgstr ""
|
2297 |
+
|
2298 |
+
#: ../views/scans-results.php:787
|
2299 |
+
msgid "Spam"
|
2300 |
+
msgstr ""
|
2301 |
+
|
2302 |
+
#: ../views/scans-results.php:789
|
2303 |
+
msgid "Not Spam"
|
2304 |
+
msgstr ""
|
2305 |
+
|
2306 |
+
#: ../views/scans-results.php:799
|
2307 |
+
msgid "Move this comment to the trash"
|
2308 |
+
msgstr ""
|
2309 |
+
|
2310 |
+
#: ../views/scans-results.php:803
|
2311 |
+
msgid "Edit comment"
|
2312 |
+
msgstr ""
|
2313 |
+
|
2314 |
+
#: ../views/scans-results.php:910
|
2315 |
+
msgid "Please, confirm you want to remove this entry pressing the Ok button"
|
2316 |
+
msgstr ""
|
2317 |
+
|
2318 |
+
#: ../views/scans-results.php:910
|
2319 |
+
msgid "Please, confirm you want to remove this comment pressing the Ok button"
|
2320 |
+
msgstr ""
|
2321 |
+
|
2322 |
+
#: ../views/scans-results.php:910
|
2323 |
+
msgid "Please, confirm you want to remove this bookmark pressing the Ok button"
|
2324 |
+
msgstr ""
|
2325 |
+
|
2326 |
+
#: ../views/scans-results.php:910
|
2327 |
+
msgid "Please, select any result to proceed"
|
2328 |
+
msgstr ""
|
2329 |
+
|
2330 |
+
#: ../views/scans-results.php:910
|
2331 |
+
msgid "error code"
|
2332 |
+
msgstr ""
|
2333 |
+
|
2334 |
+
#: ../views/scans-results.php:1019
|
2335 |
+
msgid "All results"
|
2336 |
+
msgstr ""
|
2337 |
+
|
2338 |
+
#: ../views/scans-results.php:1030
|
2339 |
+
msgid "(counters in progress)"
|
2340 |
+
msgstr ""
|
2341 |
+
|
2342 |
+
#: ../views/scans-results.php:1053
|
2343 |
+
msgid "Filter"
|
2344 |
+
msgstr ""
|
2345 |
+
|
2346 |
+
#: ../views/scans-results.php:1130
|
2347 |
+
msgid "All status codes"
|
2348 |
+
msgstr ""
|
2349 |
+
|
2350 |
+
#: ../views/scans-results.php:1160
|
2351 |
+
msgid "All content"
|
2352 |
+
msgstr ""
|
2353 |
+
|
2354 |
+
#: ../views/scans-results.php:1175
|
2355 |
+
msgid "All link types"
|
2356 |
+
msgstr ""
|
2357 |
+
|
2358 |
+
#: ../views/scans-edit.php:57
|
2359 |
+
#, php-format
|
2360 |
+
msgid ""
|
2361 |
+
"The crawler for this scan is <strong>stopped</strong> but you can see the <a "
|
2362 |
+
"href=\"%s\">crawling results</a> collected data."
|
2363 |
+
msgstr ""
|
2364 |
+
|
2365 |
+
#: ../views/scans-edit.php:57
|
2366 |
+
#, php-format
|
2367 |
+
msgid "Or you can <a href=\"%s\">start again the crawler</a>."
|
2368 |
+
msgstr ""
|
2369 |
+
|
2370 |
+
#: ../views/scans-edit.php:63
|
2371 |
+
#, php-format
|
2372 |
+
msgid ""
|
2373 |
+
"The crawler for this scan is <strong>running</strong> and you can see its <a "
|
2374 |
+
"href=\"%s\">crawling results data</a>."
|
2375 |
+
msgstr ""
|
2376 |
+
|
2377 |
+
#: ../views/scans-edit.php:63
|
2378 |
+
#, php-format
|
2379 |
+
msgid "If needed you can <a href=\"%s\">stop the crawler</a>."
|
2380 |
+
msgstr ""
|
2381 |
+
|
2382 |
+
#: ../views/scans-edit.php:69
|
2383 |
+
#, php-format
|
2384 |
+
msgid ""
|
2385 |
+
"The crawler has ended and you can see all its <a href=\"%s\">crawling "
|
2386 |
+
"results</a>."
|
2387 |
+
msgstr ""
|
2388 |
+
|
2389 |
+
#: ../views/scans-edit.php:88
|
2390 |
+
msgid "General"
|
2391 |
+
msgstr ""
|
2392 |
+
|
2393 |
+
#: ../views/scans-edit.php:89
|
2394 |
+
msgid "Content options"
|
2395 |
+
msgstr ""
|
2396 |
+
|
2397 |
+
#: ../views/scans-edit.php:90
|
2398 |
+
msgid "Content filters"
|
2399 |
+
msgstr ""
|
2400 |
+
|
2401 |
+
#: ../views/scans-edit.php:91
|
2402 |
+
msgid "Links status"
|
2403 |
+
msgstr ""
|
2404 |
+
|
2405 |
+
#: ../views/scans-edit.php:92
|
2406 |
+
msgid "Schedule"
|
2407 |
+
msgstr ""
|
2408 |
+
|
2409 |
+
#: ../views/scans-edit.php:103
|
2410 |
+
msgid "Scan name"
|
2411 |
+
msgstr ""
|
2412 |
+
|
2413 |
+
#: ../views/scans-edit.php:104
|
2414 |
+
msgid "optional"
|
2415 |
+
msgstr ""
|
2416 |
+
|
2417 |
+
#: ../views/scans-edit.php:113 ../views/scans-edit.php:120
|
2418 |
+
msgid "Link types"
|
2419 |
+
msgstr ""
|
2420 |
+
|
2421 |
+
#: ../views/scans-edit.php:134 ../views/scans-edit.php:141
|
2422 |
+
msgid "Destination type"
|
2423 |
+
msgstr ""
|
2424 |
+
|
2425 |
+
#: ../views/scans-edit.php:153 ../views/scans-edit.php:160
|
2426 |
+
msgid "Time scope"
|
2427 |
+
msgstr ""
|
2428 |
+
|
2429 |
+
#: ../views/scans-edit.php:170 ../views/scans-edit.php:177
|
2430 |
+
msgid "Crawl order"
|
2431 |
+
msgstr ""
|
2432 |
+
|
2433 |
+
#: ../views/scans-edit.php:187 ../views/scans-edit.php:194
|
2434 |
+
msgid "Redirection status"
|
2435 |
+
msgstr ""
|
2436 |
+
|
2437 |
+
#: ../views/scans-edit.php:188
|
2438 |
+
msgid "Check status of destination URLs"
|
2439 |
+
msgstr ""
|
2440 |
+
|
2441 |
+
#: ../views/scans-edit.php:195
|
2442 |
+
msgid "<strong>Yes</strong>, check status of destination URLs"
|
2443 |
+
msgstr ""
|
2444 |
+
|
2445 |
+
#: ../views/scans-edit.php:195
|
2446 |
+
msgid "No check status of destination URLs"
|
2447 |
+
msgstr ""
|
2448 |
+
|
2449 |
+
#: ../views/scans-edit.php:204 ../views/scans-edit.php:211
|
2450 |
+
msgid "Malformed URLs"
|
2451 |
+
msgstr ""
|
2452 |
+
|
2453 |
+
#: ../views/scans-edit.php:205
|
2454 |
+
msgid "Track malformed links"
|
2455 |
+
msgstr ""
|
2456 |
+
|
2457 |
+
#: ../views/scans-edit.php:212
|
2458 |
+
msgid "<strong>Yes</strong>, track malformed links"
|
2459 |
+
msgstr ""
|
2460 |
+
|
2461 |
+
#: ../views/scans-edit.php:212
|
2462 |
+
msgid "No tracking of malformed links"
|
2463 |
+
msgstr ""
|
2464 |
+
|
2465 |
+
#: ../views/scans-edit.php:221
|
2466 |
+
msgid "Notifications"
|
2467 |
+
msgstr ""
|
2468 |
+
|
2469 |
+
#: ../views/scans-edit.php:222
|
2470 |
+
msgid "Send an e-mail when the scan is completed:"
|
2471 |
+
msgstr ""
|
2472 |
+
|
2473 |
+
#: ../views/scans-edit.php:223
|
2474 |
+
#, php-format
|
2475 |
+
msgid "Send to the current blog address <strong>%s</strong>"
|
2476 |
+
msgstr ""
|
2477 |
+
|
2478 |
+
#: ../views/scans-edit.php:224
|
2479 |
+
msgid "Send to these e-mail addresses:"
|
2480 |
+
msgstr ""
|
2481 |
+
|
2482 |
+
#: ../views/scans-edit.php:284 ../views/scans-edit.php:292
|
2483 |
+
msgid "Custom fields"
|
2484 |
+
msgstr ""
|
2485 |
+
|
2486 |
+
#: ../views/scans-edit.php:286
|
2487 |
+
msgid "Custom field key"
|
2488 |
+
msgstr ""
|
2489 |
+
|
2490 |
+
#: ../views/scans-edit.php:286 ../views/scans-edit.php:345
|
2491 |
+
#: ../views/scans-edit.php:368 ../views/scans-edit.php:387
|
2492 |
+
#: ../views/scans-edit.php:413
|
2493 |
+
msgid "Add"
|
2494 |
+
msgstr ""
|
2495 |
+
|
2496 |
+
#: ../views/scans-edit.php:301 ../views/scans-edit.php:308
|
2497 |
+
msgid "Comment links"
|
2498 |
+
msgstr ""
|
2499 |
+
|
2500 |
+
#: ../views/scans-edit.php:317 ../views/scans-edit.php:324
|
2501 |
+
msgid "Also check links in"
|
2502 |
+
msgstr ""
|
2503 |
+
|
2504 |
+
#: ../views/scans-edit.php:318 ../views/scans-edit.php:325
|
2505 |
+
msgid "Blogroll links"
|
2506 |
+
msgstr ""
|
2507 |
+
|
2508 |
+
#: ../views/scans-edit.php:341 ../views/scans-edit.php:351
|
2509 |
+
msgid "Anchor filters"
|
2510 |
+
msgstr ""
|
2511 |
+
|
2512 |
+
#: ../views/scans-edit.php:344
|
2513 |
+
msgid "Anchor text filter"
|
2514 |
+
msgstr ""
|
2515 |
+
|
2516 |
+
#: ../views/scans-edit.php:364 ../views/scans-edit.php:374
|
2517 |
+
msgid "Include URLs"
|
2518 |
+
msgstr ""
|
2519 |
+
|
2520 |
+
#: ../views/scans-edit.php:383 ../views/scans-edit.php:393
|
2521 |
+
msgid "Exclude URLs"
|
2522 |
+
msgstr ""
|
2523 |
+
|
2524 |
+
#: ../views/scans-edit.php:406 ../views/scans-edit.php:419
|
2525 |
+
msgid "HTML attributes"
|
2526 |
+
msgstr ""
|
2527 |
+
|
2528 |
+
#: ../views/scans-edit.php:410
|
2529 |
+
msgid "Attribute name"
|
2530 |
+
msgstr ""
|
2531 |
+
|
2532 |
+
#: ../views/scans-edit.php:412
|
2533 |
+
msgid "Attribute value"
|
2534 |
+
msgstr ""
|
2535 |
+
|
2536 |
+
#: ../views/scans-edit.php:429
|
2537 |
+
msgid "Accelerate crawling process integrating filters in main database query"
|
2538 |
+
msgstr ""
|
2539 |
+
|
2540 |
+
#: ../views/scans-edit.php:437
|
2541 |
+
msgid "Yes"
|
2542 |
+
msgstr ""
|
2543 |
+
|
2544 |
+
#: ../views/scans-edit.php:437
|
2545 |
+
msgid "No"
|
2546 |
+
msgstr ""
|
2547 |
+
|
2548 |
+
#: ../views/scans-edit.php:453 ../views/scans-edit.php:460
|
2549 |
+
msgid "Track links by level"
|
2550 |
+
msgstr ""
|
2551 |
+
|
2552 |
+
#: ../views/scans-edit.php:469 ../views/scans-edit.php:489
|
2553 |
+
msgid "Track links by code"
|
2554 |
+
msgstr ""
|
2555 |
+
|
2556 |
+
#: ../views/scans-edit.php:511 ../views/scans-edit.php:530
|
2557 |
+
msgid "Number of threads"
|
2558 |
+
msgstr ""
|
2559 |
+
|
2560 |
+
#: ../views/scans-edit.php:515 ../views/scans-edit.php:534
|
2561 |
+
msgid "Connection timeout"
|
2562 |
+
msgstr ""
|
2563 |
+
|
2564 |
+
#: ../views/scans-edit.php:519 ../views/scans-edit.php:538
|
2565 |
+
msgid "Request timeout"
|
2566 |
+
msgstr ""
|
2567 |
+
|
2568 |
+
#: ../views/scans-edit.php:526
|
2569 |
+
msgid "All these values are optional, leave them empty to use plugin defaults."
|
2570 |
+
msgstr ""
|
2571 |
+
|
2572 |
+
#: ../views/scans-edit.php:531
|
2573 |
+
#, php-format
|
2574 |
+
msgid "(optional, default %d threads)"
|
2575 |
+
msgstr ""
|
2576 |
+
|
2577 |
+
#: ../views/scans-edit.php:535 ../views/scans-edit.php:539
|
2578 |
+
#, php-format
|
2579 |
+
msgid "(optional, default %d seconds)"
|
2580 |
+
msgstr ""
|
2581 |
+
|
2582 |
+
#: ../views/scans-edit.php:548
|
2583 |
+
msgid "Save scan changes"
|
2584 |
+
msgstr ""
|
2585 |
+
|
2586 |
+
#: ../views/scans-edit.php:549
|
2587 |
+
msgid "Save and run crawler"
|
2588 |
+
msgstr ""
|
2589 |
+
|
2590 |
+
#: ../views/scans-edit.php:550
|
2591 |
+
msgid "Delete this scan"
|
2592 |
+
msgstr ""
|
2593 |
+
|
2594 |
+
#: ../core-pro/tools-url.php:60
|
2595 |
+
msgid "Empty URLs pack"
|
2596 |
+
msgstr ""
|
2597 |
+
|
2598 |
+
#: ../core-pro/tools-url.php:67
|
2599 |
+
msgid "Error when process URLs pack"
|
2600 |
+
msgstr ""
|
2601 |
+
|
2602 |
+
#: ../core-pro/tools-url.php:219
|
2603 |
+
msgid "Removed object element"
|
2604 |
+
msgstr ""
|
2605 |
+
|
2606 |
+
#: ../core-pro/tools-url.php:245
|
2607 |
+
msgid "nofollow exists"
|
2608 |
+
msgstr ""
|
2609 |
+
|
2610 |
+
#: ../core-pro/tools-url.php:260
|
2611 |
+
msgid "Changed to nofollow"
|
2612 |
+
msgstr ""
|
2613 |
+
|
2614 |
+
#: ../core-pro/tools-url.php:272
|
2615 |
+
msgid "Set nofollow previously"
|
2616 |
+
msgstr ""
|
2617 |
+
|
2618 |
+
#: ../core-pro/tools-url.php:282
|
2619 |
+
msgid "nofollow not exists"
|
2620 |
+
msgstr ""
|
2621 |
+
|
2622 |
+
#: ../core-pro/tools-url.php:298
|
2623 |
+
msgid "Removed nofollow"
|
2624 |
+
msgstr ""
|
2625 |
+
|
2626 |
+
#: ../core-pro/tools-url.php:310
|
2627 |
+
msgid "Removed nofollow previously"
|
2628 |
+
msgstr ""
|
2629 |
+
|
2630 |
+
#: ../core-pro/tools-url.php:320
|
2631 |
+
msgid "Removed link"
|
2632 |
+
msgstr ""
|
2633 |
+
|
2634 |
+
#: ../core-pro/tools-url.php:328
|
2635 |
+
msgid "Removed link before"
|
2636 |
+
msgstr ""
|
2637 |
+
|
2638 |
+
#: ../core-pro/tools-url.php:341
|
2639 |
+
msgid "Something went wrong"
|
2640 |
+
msgstr ""
|
2641 |
+
|
2642 |
+
#: ../core-pro/tools-url.php:379
|
2643 |
+
msgid "Changed redirection location"
|
2644 |
+
msgstr ""
|
2645 |
+
|
2646 |
+
#: ../core-pro/tools-url.php:390
|
2647 |
+
msgid "Redirection changed previously"
|
2648 |
+
msgstr ""
|
2649 |
+
|
2650 |
+
#: ../core-pro/tools-url.php:426
|
2651 |
+
msgid "Database Match"
|
2652 |
+
msgstr ""
|
2653 |
+
|
2654 |
+
#: ../core-pro/tools-url.php:588
|
2655 |
+
msgid "Malformed URL"
|
2656 |
+
msgstr ""
|
2657 |
+
|
2658 |
+
#: ../core-pro/tools-url.php:622
|
2659 |
+
msgid "Empty request response"
|
2660 |
+
msgstr ""
|
2661 |
+
|
2662 |
+
#: ../core-pro/tools-url.php:630
|
2663 |
+
msgid "Empty response data"
|
2664 |
+
msgstr ""
|
2665 |
+
|
2666 |
+
#: ../core-pro/tools-url.php:640
|
2667 |
+
msgid "Malformed response data"
|
2668 |
+
msgstr ""
|
2669 |
+
|
2670 |
+
#: ../core-pro/tools-url.php:648
|
2671 |
+
msgid "Missing response data"
|
2672 |
+
msgstr ""
|
2673 |
+
|
2674 |
+
#: ../core-pro/tools-url.php:661
|
2675 |
+
msgid "Redirect header but missing Location"
|
2676 |
+
msgstr ""
|
2677 |
+
|
2678 |
+
#: ../core-pro/tools-url.php:671
|
2679 |
+
msgid "Redirect header and Location but bad URL"
|
2680 |
+
msgstr ""
|
2681 |
+
|
2682 |
+
#: ../core-pro/tools-url.php:704
|
2683 |
+
msgid "No 301 redirect header"
|
2684 |
+
msgstr ""
|
2685 |
+
|
2686 |
+
#: ../core-pro/results.php:116
|
2687 |
+
msgid "Missing or invalid action parameter"
|
2688 |
+
msgstr ""
|
2689 |
+
|
2690 |
+
#: ../core-pro/results.php:127
|
2691 |
+
msgid "Missing or invalid result identifier parameter"
|
2692 |
+
msgstr ""
|
2693 |
+
|
2694 |
+
#: ../core-pro/results.php:137 ../core-pro/results.php:150
|
2695 |
+
msgid "Resource not found in database"
|
2696 |
+
msgstr ""
|
2697 |
+
|
2698 |
+
#: ../core-pro/results.php:158
|
2699 |
+
msgid "Unable to retrieve the resource associated scan"
|
2700 |
+
msgstr ""
|
2701 |
+
|
2702 |
+
#: ../core-pro/results.php:321
|
2703 |
+
msgid "Headers information not found"
|
2704 |
+
msgstr ""
|
2705 |
+
|
2706 |
+
#: ../core-pro/results.php:869 ../core-pro/results.php:1519
|
2707 |
+
msgid "Link already unlinked"
|
2708 |
+
msgstr ""
|
2709 |
+
|
2710 |
+
#: ../core-pro/results.php:876
|
2711 |
+
msgid "Link type unknown"
|
2712 |
+
msgstr ""
|
2713 |
+
|
2714 |
+
#: ../core-pro/results.php:883
|
2715 |
+
msgid "Input value missing"
|
2716 |
+
msgstr ""
|
2717 |
+
|
2718 |
+
#: ../core-pro/results.php:890
|
2719 |
+
msgid "Operation not allowed"
|
2720 |
+
msgstr ""
|
2721 |
+
|
2722 |
+
#: ../core-pro/results.php:897
|
2723 |
+
msgid "Object not found"
|
2724 |
+
msgstr ""
|
2725 |
+
|
2726 |
+
#: ../core-pro/results.php:904
|
2727 |
+
msgid "Not valid URL"
|
2728 |
+
msgstr ""
|
2729 |
+
|
2730 |
+
#: ../core-pro/results.php:917
|
2731 |
+
msgid "Cannot retrieve element content"
|
2732 |
+
msgstr ""
|
2733 |
+
|
2734 |
+
#: ../core-pro/results.php:931
|
2735 |
+
msgid "Not valid context"
|
2736 |
+
msgstr ""
|
2737 |
+
|
2738 |
+
#: ../core-pro/results.php:960
|
2739 |
+
msgid "Unable to parse the current link"
|
2740 |
+
msgstr ""
|
2741 |
+
|
2742 |
+
#: ../core-pro/results.php:967
|
2743 |
+
msgid "Saved URL does not match the link URL"
|
2744 |
+
msgstr ""
|
2745 |
+
|
2746 |
+
#: ../core-pro/results.php:974
|
2747 |
+
msgid "Saved anchor does not match the anchor link"
|
2748 |
+
msgstr ""
|
2749 |
+
|
2750 |
+
#: ../core-pro/results.php:996 ../core-pro/results.php:1353
|
2751 |
+
#: ../core-pro/results.php:1420
|
2752 |
+
msgid "No anchor text changes detected."
|
2753 |
+
msgstr ""
|
2754 |
+
|
2755 |
+
#: ../core-pro/results.php:1007 ../core-pro/results.php:1054
|
2756 |
+
#: ../core-pro/results.php:1095 ../core-pro/results.php:1167
|
2757 |
+
#: ../core-pro/results.php:1199
|
2758 |
+
msgid "Cannot update, stored content does not match."
|
2759 |
+
msgstr ""
|
2760 |
+
|
2761 |
+
#: ../core-pro/results.php:1124
|
2762 |
+
msgid "Unable to parse the current image"
|
2763 |
+
msgstr ""
|
2764 |
+
|
2765 |
+
#: ../core-pro/results.php:1131
|
2766 |
+
msgid "Saved URL does not match the image URL"
|
2767 |
+
msgstr ""
|
2768 |
+
|
2769 |
+
#: ../core-pro/results.php:1160 ../core-pro/results.php:1284
|
2770 |
+
#: ../core-pro/results.php:1322 ../core-pro/results.php:1389
|
2771 |
+
msgid "No URL changes detected."
|
2772 |
+
msgstr ""
|
2773 |
+
|
2774 |
+
#: ../core-pro/results.php:1174 ../core-pro/results.php:1294
|
2775 |
+
#: ../core-pro/results.php:1332 ../core-pro/results.php:1399
|
2776 |
+
msgid "Failed to check the new link."
|
2777 |
+
msgstr ""
|
2778 |
+
|
2779 |
+
#: ../core-pro/results.php:1274
|
2780 |
+
msgid "Failed to retrieve post meta data."
|
2781 |
+
msgstr ""
|
2782 |
+
|
2783 |
+
#: ../core-pro/results.php:1526 ../core-pro/results.php:1564
|
2784 |
+
msgid "Given URL missing."
|
2785 |
+
msgstr ""
|
2786 |
+
|
2787 |
+
#: ../core-pro/results.php:1571
|
2788 |
+
msgid "No URL status info available."
|
2789 |
+
msgstr ""
|
2790 |
+
|
2791 |
+
#: ../core-pro/results.php:1578
|
2792 |
+
msgid "No allowed redirections."
|
2793 |
+
msgstr ""
|
2794 |
+
|
2795 |
+
#: ../core-pro/results.php:1585
|
2796 |
+
msgid "No redirection found."
|
2797 |
+
msgstr ""
|
2798 |
+
|
2799 |
+
#: ../core-pro/results.php:1984
|
2800 |
+
msgid "Post not found"
|
2801 |
+
msgstr ""
|
2802 |
+
|
2803 |
+
#: ../core-pro/results.php:1994
|
2804 |
+
msgid "Current user can`t edit this post"
|
2805 |
+
msgstr ""
|
2806 |
+
|
2807 |
+
#: ../core-pro/results.php:2014
|
2808 |
+
msgid "Comment not found"
|
2809 |
+
msgstr ""
|
2810 |
+
|
2811 |
+
#: ../core-pro/results.php:2024
|
2812 |
+
msgid "Current user can`t edit this comment"
|
2813 |
+
msgstr ""
|
2814 |
+
|
2815 |
+
#: ../core-pro/results.php:2044
|
2816 |
+
msgid "Bookmark record not found"
|
2817 |
+
msgstr ""
|
2818 |
+
|
2819 |
+
#: ../core-pro/results.php:2054
|
2820 |
+
msgid "Current user can`t edit this bookmark"
|
2821 |
+
msgstr ""
|
readme.txt
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== WP Broken Link Status Checker ===
|
2 |
+
Contributors: seedplugins, pauiglesias
|
3 |
+
Tags: broken links, broken, links, crawler, headers, http, nofollow, redirections, scan, status, checker, url
|
4 |
+
Requires at least: 3.4
|
5 |
+
Tested up to: 4.4.2
|
6 |
+
Stable tag: 1.0
|
7 |
+
License: GPLv2 or later
|
8 |
+
|
9 |
+
Check HTTP status response codes of all your content links and images, looking for broken links, redirections, nofollow links, etc.
|
10 |
+
|
11 |
+
== Description ==
|
12 |
+
|
13 |
+
This plugin is a broken link checker utility organized through entities called scans, each one containing its own configuration and results.
|
14 |
+
|
15 |
+
Start creating a new scan, and once a scan is configured you can start the crawler from the same edit page, or run it later from the scans list screen.
|
16 |
+
|
17 |
+
Knowing that these crawling processes can hurt your server perfomance, we have tried to put the focus on performance impacts, without performing massive data queries or updates, and not prioritizing crawler activity ahead of real visits.
|
18 |
+
|
19 |
+
Once started, you can see results inmediately without having to wait for the scan to be completed. You can access to the results page doing a click in the scan name, or clicking the "Show results" link from the scan actions row.
|
20 |
+
|
21 |
+
The crawler results page shows all links detected according to the scan configuration, allowing basic filtering options.
|
22 |
+
|
23 |
+
You can read a detailed user guide and the documentation from the plugin page:
|
24 |
+
|
25 |
+
http://seedplugins.com/wp-link-status/
|
26 |
+
|
27 |
+
== Installation ==
|
28 |
+
|
29 |
+
Install from WordPress
|
30 |
+
|
31 |
+
1. Visit the Plugins page from your WordPress main menu and select Add New link
|
32 |
+
1. Click on Upload plugin, next Browse, choose wp-link-status.zip and press Install Now.
|
33 |
+
1. Once uploaded and install click Activate Plugin
|
34 |
+
1. Get started from the WP Link Status menu
|
35 |
+
|
36 |
+
Or upload via FTP
|
37 |
+
|
38 |
+
1. Unzip and upload wp-link-status folder to the `/wp-content/plugins/` directory
|
39 |
+
1. Activate the plugin through the 'Plugins' menu in WordPress
|
40 |
+
1. Get started from the WP Link Status menu
|
41 |
+
|
42 |
+
== Frequently Asked Questions ==
|
43 |
+
|
44 |
+
= Do I need to keep the browser opened, or a WordPress user session active during the crawling process? =
|
45 |
+
|
46 |
+
No, it is not necessary. The crawler module runs in background and it is intended to work in unattended mode.
|
47 |
+
|
48 |
+
= How the crawling process affects to server performance? =
|
49 |
+
|
50 |
+
There are several mechanisms to avoid constant database access. When a URL is found, the crawler stops extracting URLs from content and check the detected URL. In addition, in the settings page you can manage many parameters related to performance. Let me known if you experience any issue.
|
51 |
+
|
52 |
+
= Why the crawler does not work and show "Waiting..."? =
|
53 |
+
|
54 |
+
The crawler module works submitting HTTP requests through internal plugin scripts. So if you are running this plugin under an environment outside the Internet (e.g. local or development server) you need to add the involved hosts names or domains into your hosts file, both the client and server where this plugin is executed.
|
55 |
+
|
56 |
+
In the same way, if the site you are crawling implements browser password protection, you need to remove this password restriction in order to work properly.
|
57 |
+
|
58 |
+
== Screenshots ==
|
59 |
+
|
60 |
+
1. Scan basic configuration
|
61 |
+
1. Scan content options
|
62 |
+
1. Scan URL filters
|
63 |
+
1. Scan HTTP status selection
|
64 |
+
1. Scan advanced options
|
65 |
+
1. Main scans list
|
66 |
+
1. Crawler results page
|
67 |
+
|
68 |
+
== Changelog ==
|
69 |
+
|
70 |
+
= 1.0 =
|
71 |
+
Release Date: February 11th, 2016
|
72 |
+
|
73 |
+
* First and tested released until WordPress 4.4.2
|
74 |
+
* Tested code from WordPress 3.4 version.
|
75 |
+
|
76 |
+
== Upgrade Notice ==
|
77 |
+
|
78 |
+
= 1.0 =
|
79 |
+
Initial Release.
|
views/extensions.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Load views class
|
4 |
+
require_once(dirname(__FILE__).'/views.php');
|
5 |
+
|
6 |
+
/**
|
7 |
+
* WP Link Status Views Extensions class
|
8 |
+
*
|
9 |
+
* @package WP Link Status
|
10 |
+
* @subpackage WP Link Status Views
|
11 |
+
*/
|
12 |
+
class WPLNST_Views_Extensions extends WPLNST_Views {
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Show scan edit form
|
18 |
+
*/
|
19 |
+
public static function view($args) {
|
20 |
+
|
21 |
+
// Vars
|
22 |
+
extract($args);
|
23 |
+
|
24 |
+
// Plugin images
|
25 |
+
$base_url = plugins_url('assets/images/extensions/', WPLNST_FILE);
|
26 |
+
|
27 |
+
?><div id="wplnst-extensions">
|
28 |
+
|
29 |
+
|
30 |
+
<div class="wplnst-extensions-section">
|
31 |
+
|
32 |
+
<p><a href="http://seedplugins.com/wp-link-status/" target="_blank"><img src="<?php echo $base_url.'pro-banner.jpg'; ?>" width="590" height="300" border="0" /></a></p>
|
33 |
+
|
34 |
+
<p style="width: 590px; text-align: center;"><a href="http://seedplugins.com/wp-link-status/" target="_blank" class="button-primary">Get WP Link Status Pro version</a></p>
|
35 |
+
|
36 |
+
</div>
|
37 |
+
|
38 |
+
|
39 |
+
<div class="wplnst-extensions-section">
|
40 |
+
|
41 |
+
<h3>Advanced filters</h3>
|
42 |
+
|
43 |
+
<p><img src="<?php echo $base_url.'wpls-web-crawler-results-advanced.png'; ?>" width="800" height="120" border="0" /></p>
|
44 |
+
|
45 |
+
</div>
|
46 |
+
|
47 |
+
|
48 |
+
<div class="wplnst-extensions-section">
|
49 |
+
|
50 |
+
<h3>Inline result editing</h3>
|
51 |
+
|
52 |
+
<p><img src="<?php echo $base_url.'wpls-web-crawler-results-actions.png'; ?>" width="800" height="100" border="0" /></p>
|
53 |
+
|
54 |
+
<p><img src="<?php echo $base_url.'wpls-web-crawler-edit.png'; ?>" width="800" height="300" border="0" /></p>
|
55 |
+
|
56 |
+
</div>
|
57 |
+
|
58 |
+
|
59 |
+
<div class="wplnst-extensions-section">
|
60 |
+
|
61 |
+
<h3>Extra URL Tools</h3>
|
62 |
+
|
63 |
+
<p><img src="<?php echo $base_url.'wpls-web-crawler-url-tools.png'; ?>" width="800" height="363" border="0" /></p>
|
64 |
+
|
65 |
+
<p><img src="<?php echo $base_url.'wpls-web-crawler-url-tools-results.png'; ?>" width="800" height="427" border="0" /></p>
|
66 |
+
|
67 |
+
</div>
|
68 |
+
|
69 |
+
<p style="width: 800px; text-align: center;"><a href="http://seedplugins.com/wp-link-status/" target="_blank" class="button-primary">Get WP Link Status Pro version</a></p>
|
70 |
+
|
71 |
+
|
72 |
+
</div><?php
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
}
|
views/scans-edit.php
ADDED
@@ -0,0 +1,559 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Load views class
|
4 |
+
require_once(dirname(__FILE__).'/views.php');
|
5 |
+
|
6 |
+
/**
|
7 |
+
* WP Link Status Views Scans Edit class
|
8 |
+
*
|
9 |
+
* @package WP Link Status
|
10 |
+
* @subpackage WP Link Status Views
|
11 |
+
*/
|
12 |
+
class WPLNST_Views_Scans_Edit extends WPLNST_Views {
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Show scan edit form
|
18 |
+
*/
|
19 |
+
public static function view($args) {
|
20 |
+
|
21 |
+
// Vars
|
22 |
+
extract($args);
|
23 |
+
|
24 |
+
// Initialize
|
25 |
+
$is_ready = true;
|
26 |
+
$editable = ('wait' == $scan->status);
|
27 |
+
|
28 |
+
// Check errors
|
29 |
+
$link_types_error = $post_types_error = $post_status_error = $link_status_error = false;
|
30 |
+
if (!empty($notice_ready) && is_array($notice_ready)) {
|
31 |
+
|
32 |
+
// Inside form errors
|
33 |
+
$link_types_error = isset($notice_ready['link_types']);
|
34 |
+
$post_types_error = isset($notice_ready['post_types']);
|
35 |
+
$post_status_error = isset($notice_ready['post_status']);
|
36 |
+
$link_status_error = isset($notice_ready['link_status']);
|
37 |
+
|
38 |
+
// Determine if ready
|
39 |
+
$is_ready = !($link_types_error || $post_types_error || $post_status_error || $link_status_error);
|
40 |
+
|
41 |
+
// Show notice errors
|
42 |
+
echo '<div class="error notice">';
|
43 |
+
foreach ($notice_ready as $notice_key => $notice_title)
|
44 |
+
echo '<p>'.$notice_title.'</p>';
|
45 |
+
echo '</div>';
|
46 |
+
} ?>
|
47 |
+
|
48 |
+
<?php if ($is_ready && $scan->id > 0) :
|
49 |
+
|
50 |
+
// Prepare URLs
|
51 |
+
$results_url = esc_url(WPLNST_Core_Plugin::get_url_scans_results($scan->id));
|
52 |
+
$start_url = esc_url(WPLNST_Core_Plugin::get_url_scans_crawler($scan->id, 'on', $scan->hash));
|
53 |
+
$stop_url = esc_url(WPLNST_Core_Plugin::get_url_scans_crawler($scan->id, 'off', $scan->hash)); ?>
|
54 |
+
|
55 |
+
<?php if ('stop' == $scan->status) : ?>
|
56 |
+
|
57 |
+
<div class="notice"><p><?php printf(__('The crawler for this scan is <strong>stopped</strong> but you can see the <a href="%s">crawling results</a> collected data.', 'wplnst'), $results_url); if ($more_scans) : echo ' '; printf(__('Or you can <a href="%s">start again the crawler</a>.', 'wplnst'), $start_url); endif; ?></p></div>
|
58 |
+
|
59 |
+
<?php elseif ('play' == $scan->status) : ?>
|
60 |
+
|
61 |
+
<?php if (empty($_POST['scan_run']) && empty($_GET['started'])) : ?>
|
62 |
+
|
63 |
+
<div class="notice"><p><?php printf(__('The crawler for this scan is <strong>running</strong> and you can see its <a href="%s">crawling results data</a>.', 'wplnst'), $results_url); echo ' '; printf(__('If needed you can <a href="%s">stop the crawler</a>.', 'wplnst'), $stop_url); ?></p></div>
|
64 |
+
|
65 |
+
<?php endif; ?>
|
66 |
+
|
67 |
+
<?php elseif ('end' == $scan->status) : ?>
|
68 |
+
|
69 |
+
<div class="notice"><p><?php printf(__('The crawler is completed and you can see all its <a href="%s">crawling results</a>.', 'wplnst'), $results_url); ?></p></div>
|
70 |
+
|
71 |
+
<?php endif; ?>
|
72 |
+
|
73 |
+
<?php endif; ?>
|
74 |
+
|
75 |
+
<form method="post" id="wplnst-form" action="<?php echo esc_url($action); ?>">
|
76 |
+
|
77 |
+
<input type="hidden" name="scan_id" id="wplnst-scan-id" value="<?php echo esc_attr($scan->id); ?>" />
|
78 |
+
<input type="hidden" name="scan_run" id="wplnst-scan-run" value="" />
|
79 |
+
<input type="hidden" name="scan_edit_nonce" value="<?php echo esc_attr($nonce); ?>" />
|
80 |
+
|
81 |
+
<input type="hidden" name="scan_custom_fields" id="wplnst-scan-custom-fields" value='<?php echo self::esc_attr_elist($scan->custom_fields); ?>' />
|
82 |
+
<input type="hidden" name="scan_anchor_filters" id="wplnst-scan-anchor-filters" value='<?php echo self::esc_attr_elist($scan->anchor_filters); ?>' />
|
83 |
+
<input type="hidden" name="scan_include_urls" id="wplnst-scan-include-urls" value='<?php echo self::esc_attr_elist($scan->include_urls); ?>' />
|
84 |
+
<input type="hidden" name="scan_exclude_urls" id="wplnst-scan-exclude-urls" value='<?php echo self::esc_attr_elist($scan->exclude_urls); ?>' />
|
85 |
+
<input type="hidden" name="scan_html_attributes" id="wplnst-scan-html-attributes" value='<?php echo self::esc_attr_elist($scan->html_attributes); ?>' />
|
86 |
+
|
87 |
+
<h2 id="wplnst-tabs-nav" class="nav-tab-wrapper">
|
88 |
+
<a id="wplnst-general-tab" href="#top#wplnst-general" class="nav-tab"<?php if ($link_types_error) echo ' style="color: red;"'; ?>><?php _e('General', 'wplnst'); ?></a>
|
89 |
+
<a id="wplnst-content-tab" href="#top#wplnst-content" class="nav-tab"<?php if ($post_types_error || $post_status_error) echo ' style="color: red;"'; ?>><?php _e('Content options', 'wplnst'); ?></a>
|
90 |
+
<a id="wplnst-filters-tab" href="#top#wplnst-filters" class="nav-tab"><?php _e('Content filters', 'wplnst'); ?></a>
|
91 |
+
<a id="wplnst-status-tab" href="#top#wplnst-status" class="nav-tab"<?php if ($link_status_error) echo ' style="color: red;"'; ?>><?php _e('Links status', 'wplnst'); ?></a>
|
92 |
+
<?php if (false) : ?><a id="wplnst-scheduled-tab" href="#top#wplnst-scheduled" class="nav-tab"><?php _e('Schedule', 'wplnst'); ?></a><?php endif; ?>
|
93 |
+
<a id="wplnst-advanced-tab" href="#top#wplnst-advanced" class="nav-tab"><?php _e('Advanced', 'wplnst'); ?></a>
|
94 |
+
</h2>
|
95 |
+
|
96 |
+
<div id="wplnst-tabs" class="wplnst-tabs-scan-edit">
|
97 |
+
|
98 |
+
<div id="wplnst-general" class="wplnst-tab wplnst-tab-default">
|
99 |
+
|
100 |
+
<table class="form-table">
|
101 |
+
|
102 |
+
<tr>
|
103 |
+
<th><label for="tx-name"><?php _e('Scan name', 'wplnst'); ?></label></th>
|
104 |
+
<td><input type="text" name="tx-name" id="tx-name" value="<?php echo esc_attr($scan->name); ?>" class="regular-text" maxlength="255" /> (<?php _e('optional', 'wplnst'); ?>)</td>
|
105 |
+
</tr>
|
106 |
+
|
107 |
+
|
108 |
+
<?php if (!empty($link_types)) : ?>
|
109 |
+
|
110 |
+
<?php if ($editable) : ?>
|
111 |
+
|
112 |
+
<tr>
|
113 |
+
<th<?php if ($link_types_error) echo ' style="color: red;"'; ?>><?php _e('Link types', 'wplnst'); ?></th>
|
114 |
+
<td class="wplnst-list"><?php foreach ($link_types as $key => $name) : ?><input <?php self::checked($key, $scan->link_types); ?> type="checkbox" name="ck-link-type[<?php echo $key; ?>]" id="ck-link-type-<?php echo $key; ?>" value="on" /><label for="ck-link-type-<?php echo $key; ?>"><?php echo $name; ?></label> <?php endforeach; ?></td>
|
115 |
+
</tr>
|
116 |
+
|
117 |
+
<?php else : ?>
|
118 |
+
|
119 |
+
<tr>
|
120 |
+
<th><?php _e('Link types', 'wplnst'); ?></th>
|
121 |
+
<td class="wplnst-value-list"><?php if (!empty($scan->link_types_names) && is_array($scan->link_types_names)) echo implode(', ', array_map('esc_html', $scan->link_types_names)); ?></td>
|
122 |
+
</tr>
|
123 |
+
|
124 |
+
<?php endif; ?>
|
125 |
+
|
126 |
+
<?php endif; ?>
|
127 |
+
|
128 |
+
|
129 |
+
<?php if (!empty($destination_types)) : ?>
|
130 |
+
|
131 |
+
<?php if ($editable) : ?>
|
132 |
+
|
133 |
+
<tr>
|
134 |
+
<th><label for="wplnst-destination-type"><?php _e('Destination type', 'wplnst'); ?></label></th>
|
135 |
+
<td><select id="wplnst-destination-type" name="sl-destination-type"><?php self::options($destination_types, $scan->destination_type); ?></select></td>
|
136 |
+
</tr>
|
137 |
+
|
138 |
+
<?php else : ?>
|
139 |
+
|
140 |
+
<tr>
|
141 |
+
<th><?php _e('Destination type', 'wplnst'); ?></th>
|
142 |
+
<td class="wplnst-value"><?php echo esc_html($scan->destination_type_name); ?></td>
|
143 |
+
</tr>
|
144 |
+
|
145 |
+
<?php endif; ?>
|
146 |
+
|
147 |
+
<?php endif; ?>
|
148 |
+
|
149 |
+
|
150 |
+
<?php if ($editable) : ?>
|
151 |
+
|
152 |
+
<tr>
|
153 |
+
<th><label for="wplnst-time-scope"><?php _e('Time scope', 'wplnst'); ?></label></th>
|
154 |
+
<td><select id="wplnst-time-scope" name="sl-time-scope"><?php self::options($time_scopes, $scan->time_scope); ?></select></td>
|
155 |
+
</tr>
|
156 |
+
|
157 |
+
<?php else : ?>
|
158 |
+
|
159 |
+
<tr>
|
160 |
+
<th><?php _e('Time scope', 'wplnst'); ?></th>
|
161 |
+
<td class="wplnst-value"><?php echo esc_html($scan->time_scope_name); ?></td>
|
162 |
+
</tr>
|
163 |
+
|
164 |
+
<?php endif; ?>
|
165 |
+
|
166 |
+
|
167 |
+
<?php if ($editable) : ?>
|
168 |
+
|
169 |
+
<tr>
|
170 |
+
<th><label for="wplnst-crawl-order"><?php _e('Crawl order', 'wplnst'); ?></label></th>
|
171 |
+
<td><select id="wplnst-crawl-order" name="sl-crawl-order"><?php self::options($crawl_order, $scan->crawl_order); ?></select></td>
|
172 |
+
</tr>
|
173 |
+
|
174 |
+
<?php else : ?>
|
175 |
+
|
176 |
+
<tr>
|
177 |
+
<th><?php _e('Crawl order', 'wplnst'); ?></th>
|
178 |
+
<td class="wplnst-value"><?php echo esc_html($scan->crawl_order_name); ?></td>
|
179 |
+
</tr>
|
180 |
+
|
181 |
+
<?php endif; ?>
|
182 |
+
|
183 |
+
|
184 |
+
<?php if ($editable) : ?>
|
185 |
+
|
186 |
+
<tr>
|
187 |
+
<th><?php _e('Redirection status', 'wplnst'); ?></th>
|
188 |
+
<td class="wplnst-list"><input <?php self::checked($scan->redir_status, true); ?> type="checkbox" id="ck-redir-status" name="ck-redir-status" value="on" /><label for="ck-redir-status"><?php _e('Check status of destination URLs', 'wplnst'); ?></label></td>
|
189 |
+
</tr>
|
190 |
+
|
191 |
+
<?php else : ?>
|
192 |
+
|
193 |
+
<tr>
|
194 |
+
<th><?php _e('Redirection status', 'wplnst'); ?></th>
|
195 |
+
<td class="wplnst-value"><?php echo $scan->redir_status? __('<strong>Yes</strong>, check status of destination URLs', 'wplnst') : __('No check status of destination URLs', 'wplnst'); ?></td>
|
196 |
+
</tr>
|
197 |
+
|
198 |
+
<?php endif; ?>
|
199 |
+
|
200 |
+
|
201 |
+
<?php if ($editable) : ?>
|
202 |
+
|
203 |
+
<tr>
|
204 |
+
<th><?php _e('Malformed URLs', 'wplnst'); ?></th>
|
205 |
+
<td class="wplnst-list"><input <?php self::checked($scan->malformed, true); ?> type="checkbox" id="ck-malformed-links" name="ck-malformed-links" value="on" /><label for="ck-malformed-links"><?php _e('Track malformed links', 'wplnst'); ?></label></td>
|
206 |
+
</tr>
|
207 |
+
|
208 |
+
<?php else : ?>
|
209 |
+
|
210 |
+
<tr>
|
211 |
+
<th><?php _e('Malformed URLs', 'wplnst'); ?></th>
|
212 |
+
<td class="wplnst-value"><?php echo $scan->malformed? __('<strong>Yes</strong>, track malformed links', 'wplnst') : __('No tracking of malformed links', 'wplnst'); ?></td>
|
213 |
+
</tr>
|
214 |
+
|
215 |
+
<?php endif; ?>
|
216 |
+
|
217 |
+
|
218 |
+
<?php if ('end' != $scan->status) : ?>
|
219 |
+
|
220 |
+
<tr>
|
221 |
+
<th><?php _e('Notifications', 'wplnst'); ?></th>
|
222 |
+
<td class="wplnst-list"><p><?php _e('Send an e-mail when the scan is completed:', 'wplnst'); ?></p>
|
223 |
+
<p><input <?php self::checked($scan->notify_default, true); ?> type="checkbox" id="ck-notify-default" name="ck-notify-default" value="on" /><label for="ck-notify-default"><?php printf(__('Send to the current blog address <strong>%s</strong>', 'wplnst'), get_option('admin_email'));; ?></label></p>
|
224 |
+
<p><input <?php self::checked($scan->notify_address, true); ?> type="checkbox" id="ck-notify-address" name="ck-notify-address" value="on" /><label for="ck-notify-address"><?php _e('Send to these e-mail addresses:', 'wplnst'); ?></label><br /><input type="text" name="tx-notify-address-email" id="tx-notify-address-email" value="<?php echo esc_attr($scan->notify_address_email); ?>" class="regular-text" maxlength="255" /></p></td>
|
225 |
+
</tr>
|
226 |
+
|
227 |
+
<?php endif; ?>
|
228 |
+
|
229 |
+
|
230 |
+
</table>
|
231 |
+
|
232 |
+
</div>
|
233 |
+
|
234 |
+
|
235 |
+
<div id="wplnst-content" class="wplnst-tab">
|
236 |
+
|
237 |
+
<table class="form-table">
|
238 |
+
|
239 |
+
|
240 |
+
<?php if (!empty($post_types)) : ?>
|
241 |
+
|
242 |
+
<?php if ($editable) : ?>
|
243 |
+
|
244 |
+
<tr>
|
245 |
+
<th<?php if ($post_types_error) echo ' style="color: red;"'; ?>><?php _e('Post types', 'wplnst'); ?></th>
|
246 |
+
<td class="wplnst-list"><?php foreach ($post_types as $key => $name) : ?><input <?php self::checked($key, $scan->post_types); ?> type="checkbox" name="ck-post-type[<?php echo $key; ?>]" id="ck-post-type-<?php echo $key; ?>" value="on" /><label for="ck-post-type-<?php echo $key; ?>"><?php echo $name; ?> (<code><?php echo $key; ?></code>)</label><br /><?php endforeach; ?></td>
|
247 |
+
</tr>
|
248 |
+
|
249 |
+
<?php else : ?>
|
250 |
+
|
251 |
+
<tr>
|
252 |
+
<th><?php _e('Post types', 'wplnst'); ?></th>
|
253 |
+
<td class="wplnst-value-list"><?php if (empty($scan->post_types_names_strict) || !is_array($scan->post_types_names_strict)) : echo '-'; else : echo implode("<br />", $scan->post_types_names_strict); endif; ?></td>
|
254 |
+
</tr>
|
255 |
+
|
256 |
+
<?php endif; ?>
|
257 |
+
|
258 |
+
<?php endif; ?>
|
259 |
+
|
260 |
+
|
261 |
+
<?php if (!empty($post_status)) : ?>
|
262 |
+
|
263 |
+
<?php if ($editable) : ?>
|
264 |
+
|
265 |
+
<tr>
|
266 |
+
<th<?php if ($post_status_error) echo ' style="color: red;"'; ?>><?php _e('Post status', 'wplnst'); ?></th>
|
267 |
+
<td class="wplnst-list"><?php foreach ($post_status as $key) : ?><input <?php self::checked($key, $scan->post_status); ?> type="checkbox" name="ck-post-status[<?php echo $key; ?>]" id="ck-post-status-<?php echo $key; ?>" value="on" /><label for="ck-post-status-<?php echo $key; ?>"><?php echo ucfirst($key); ?></label> <?php endforeach; ?></td>
|
268 |
+
</tr>
|
269 |
+
|
270 |
+
<?php else : ?>
|
271 |
+
|
272 |
+
<tr>
|
273 |
+
<th><?php _e('Post status', 'wplnst'); ?></th>
|
274 |
+
<td class="wplnst-value-list"><?php if (empty($scan->post_status_names) || !is_array($scan->post_status_names)) : echo '-'; else : echo implode(', ', array_map('esc_html', $scan->post_status_names)); endif; ?></td>
|
275 |
+
</tr>
|
276 |
+
|
277 |
+
<?php endif; ?>
|
278 |
+
|
279 |
+
<?php endif; ?>
|
280 |
+
|
281 |
+
<?php if ($editable) : ?>
|
282 |
+
|
283 |
+
<tr>
|
284 |
+
<th><label for="wplnst-cf-new"><?php _e('Custom fields', 'wplnst'); ?></label></th>
|
285 |
+
<td><table id="wplnst-elist-custom-fields" class="wplnst-elist" data-editable="true"></table>
|
286 |
+
<input type="text" id="wplnst-cf-new" value="" class="regular-text" placeholder="<?php _e('Custom field key', 'wplnst'); ?>" /> <select id="wplnst-cf-new-type"><?php self::options($custom_fields, false); ?></select> <input class="button-secondary" type="button" id="wplnst-cf-new-add" value="<?php _e('Add', 'wplnst'); ?>" /></td>
|
287 |
+
</tr>
|
288 |
+
|
289 |
+
<?php else : ?>
|
290 |
+
|
291 |
+
<tr>
|
292 |
+
<th><?php _e('Custom fields', 'wplnst'); ?></th>
|
293 |
+
<td><?php if (empty($scan->custom_fields)) : ?>-<?php else : ?><table id="wplnst-elist-custom-fields" class="wplnst-elist wplnst-elist-readonly" data-editable="false"></table><?php endif; ?></td>
|
294 |
+
</tr>
|
295 |
+
|
296 |
+
<?php endif; ?>
|
297 |
+
|
298 |
+
<?php if ($editable) : ?>
|
299 |
+
|
300 |
+
<tr>
|
301 |
+
<th<?php if ($post_types_error) echo ' style="color: red;"'; ?>><?php _e('Comment links', 'wplnst'); ?></th>
|
302 |
+
<td class="wplnst-list"><?php foreach ($comment_types as $key => $name) : ?><input <?php self::checked($key, $scan->comment_types); ?> type="checkbox" name="ck-comment-type[<?php echo $key; ?>]" id="ck-comment-type-<?php echo $key; ?>" value="on" /><label for="ck-comment-type-<?php echo $key; ?>"><?php echo $name; ?></label> <?php endforeach; ?></td>
|
303 |
+
</tr>
|
304 |
+
|
305 |
+
<?php else : ?>
|
306 |
+
|
307 |
+
<tr>
|
308 |
+
<th><?php _e('Comment links', 'wplnst'); ?></th>
|
309 |
+
<td class="wplnst-value-list"><?php if (!empty($scan->comment_types_names) && is_array($scan->comment_types_names)) echo implode(', ', array_map('esc_html', $scan->comment_types_names)); ?></td>
|
310 |
+
</tr>
|
311 |
+
|
312 |
+
<?php endif; ?>
|
313 |
+
|
314 |
+
<?php if ($editable) : ?>
|
315 |
+
|
316 |
+
<tr>
|
317 |
+
<th<?php if ($post_types_error) echo ' style="color: red;"'; ?>><?php _e('Also check links in', 'wplnst'); ?></th>
|
318 |
+
<td class="wplnst-list"><input <?php self::checked($scan->check_blogroll, true); ?> type="checkbox" name="ck-blogroll" id="ck-blogroll" value="on" /><label for="ck-blogroll"><?php _e('Blogroll links', 'wplnst'); ?></label></td>
|
319 |
+
</tr>
|
320 |
+
|
321 |
+
<?php else : ?>
|
322 |
+
|
323 |
+
<tr>
|
324 |
+
<th><?php _e('Also check links in', 'wplnst'); ?></th>
|
325 |
+
<td class="wplnst-value-list"><?php echo $scan->check_blogroll? __('Blogroll links', 'wplnst') : '-'; ?></td>
|
326 |
+
</tr>
|
327 |
+
|
328 |
+
<?php endif; ?>
|
329 |
+
</table>
|
330 |
+
|
331 |
+
</div>
|
332 |
+
|
333 |
+
|
334 |
+
<div id="wplnst-filters" class="wplnst-tab">
|
335 |
+
|
336 |
+
<table class="form-table">
|
337 |
+
|
338 |
+
<?php if ($editable) : ?>
|
339 |
+
|
340 |
+
<tr>
|
341 |
+
<th style="width: 120px;"><?php _e('Anchor filters', 'wplnst'); ?></th>
|
342 |
+
<td><table id="wplnst-elist-anchor-filters" class="wplnst-elist" cellspacing="0" cellpadding="0" border="0" data-editable="true" data-label="<?php _e('Anchor text', 'wplnst'); ?>"></table>
|
343 |
+
<?php _e('Anchor text', 'wplnst'); ?> <select id="wplnst-af-new-type"><?php self::options($anchor_filters, false); ?></select>
|
344 |
+
<input id="wplnst-af-new" type="text" class="regular-text" value="" placeholder="<?php _e('Anchor text filter', 'wplnst'); ?>" />
|
345 |
+
<input class="button-secondary" type="button" id="wplnst-af-new-add" value="<?php _e('Add', 'wplnst'); ?>" /></td>
|
346 |
+
</tr>
|
347 |
+
|
348 |
+
<?php else : ?>
|
349 |
+
|
350 |
+
<tr>
|
351 |
+
<th style="width: 120px;"><?php _e('Anchor filters', 'wplnst'); ?></th>
|
352 |
+
<td><?php if (empty($scan->anchor_filters)) : ?>-<?php else : ?><table id="wplnst-elist-anchor-filters" class="wplnst-elist wplnst-elist-readonly" cellspacing="0" cellpadding="0" border="0" data-label="<?php _e('Anchor text', 'wplnst'); ?>" data-editable="false"></table><?php endif; ?></td>
|
353 |
+
</tr>
|
354 |
+
|
355 |
+
<?php endif; ?>
|
356 |
+
|
357 |
+
</table>
|
358 |
+
|
359 |
+
<table class="form-table">
|
360 |
+
|
361 |
+
<?php if ($editable) : ?>
|
362 |
+
|
363 |
+
<tr>
|
364 |
+
<th style="width: 120px;"><?php _e('Include URLs', 'wplnst'); ?></th>
|
365 |
+
<td><table id="wplnst-elist-include-urls" class="wplnst-elist" cellspacing="0" cellpadding="0" border="0" data-editable="true"></table>
|
366 |
+
<input id="wplnst-ius-new" type="text" class="regular-text" value="" />
|
367 |
+
<select id="wplnst-ius-new-type"><?php self::options($url_filters, false); ?></select>
|
368 |
+
<input class="button-secondary" type="button" id="wplnst-ius-new-add" value="<?php _e('Add', 'wplnst'); ?>" /></td>
|
369 |
+
</tr>
|
370 |
+
|
371 |
+
<?php else : ?>
|
372 |
+
|
373 |
+
<tr>
|
374 |
+
<th style="width: 120px;"><?php _e('Include URLs', 'wplnst'); ?></th>
|
375 |
+
<td><?php if (empty($scan->include_urls)) : ?>-<?php else : ?><table id="wplnst-elist-include-urls" class="wplnst-elist wplnst-elist-readonly" cellspacing="0" cellpadding="0" border="0" data-editable="false"></table><?php endif; ?></td>
|
376 |
+
</tr>
|
377 |
+
|
378 |
+
<?php endif; ?>
|
379 |
+
|
380 |
+
<?php if ($editable) : ?>
|
381 |
+
|
382 |
+
<tr>
|
383 |
+
<th style="width: 120px;"><?php _e('Exclude URLs', 'wplnst'); ?></th>
|
384 |
+
<td><table id="wplnst-elist-exclude-urls" class="wplnst-elist" cellspacing="0" cellpadding="0" border="0" data-editable="true"></table>
|
385 |
+
<input id="wplnst-eus-new" type="text" class="regular-text" value="" />
|
386 |
+
<select id="wplnst-eus-new-type"><?php self::options($url_filters, false); ?></select>
|
387 |
+
<input class="button-secondary" type="button" id="wplnst-eus-new-add" value="<?php _e('Add', 'wplnst'); ?>" /></td>
|
388 |
+
</tr>
|
389 |
+
|
390 |
+
<?php else : ?>
|
391 |
+
|
392 |
+
<tr>
|
393 |
+
<th style="width: 120px;"><?php _e('Exclude URLs', 'wplnst'); ?></th>
|
394 |
+
<td><?php if (empty($scan->exclude_urls)) : ?>-<?php else : ?><table id="wplnst-elist-exclude-urls" class="wplnst-elist wplnst-elist-readonly" cellspacing="0" cellpadding="0" border="0" data-editable="false"></table><?php endif; ?></td>
|
395 |
+
</tr>
|
396 |
+
|
397 |
+
<?php endif; ?>
|
398 |
+
|
399 |
+
</table>
|
400 |
+
|
401 |
+
<table class="form-table">
|
402 |
+
|
403 |
+
<?php if ($editable) : ?>
|
404 |
+
|
405 |
+
<tr>
|
406 |
+
<th style="width: 120px;"><?php _e('HTML attributes', 'wplnst'); ?></th>
|
407 |
+
<td><table id="wplnst-elist-html-attributes" class="wplnst-elist" cellspacing="0" cellpadding="0" border="0" data-editable="true"></table>
|
408 |
+
<select id="wplnst-hes-new" style="width: 55px;"><option value="a">a</option><option value="img">img</option></select>
|
409 |
+
<select id="wplnst-hes-new-have"><?php self::options($html_attributes_having, false); ?></select>
|
410 |
+
<input id="wplnst-hes-new-att" type="text" class="regular-text" value="" placeholder="<?php _e('Attribute name', 'wplnst'); ?>" style="width: 135px;" />
|
411 |
+
<select id="wplnst-hes-new-op"><?php self::options($html_attributes_operators, false); ?></select>
|
412 |
+
<input id="wplnst-hes-new-val" type="text" class="regular-text" value="" placeholder="<?php _e('Attribute value', 'wplnst'); ?>" style="width: 135px;" />
|
413 |
+
<input id="wplnst-hes-new-add" class="button-secondary" type="button" value="<?php _e('Add', 'wplnst'); ?>" /></td>
|
414 |
+
</tr>
|
415 |
+
|
416 |
+
<?php else : ?>
|
417 |
+
|
418 |
+
<tr>
|
419 |
+
<th style="width: 120px;"><?php _e('HTML attributes', 'wplnst'); ?></th>
|
420 |
+
<td><?php if (empty($scan->html_attributes)) : ?>-<?php else : ?><table id="wplnst-elist-html-attributes" class="wplnst-elist wplnst-elist-readonly" cellspacing="0" cellpadding="0" border="0" data-editable="false"></table><?php endif; ?></td>
|
421 |
+
</tr>
|
422 |
+
|
423 |
+
<?php endif; ?>
|
424 |
+
|
425 |
+
</table>
|
426 |
+
|
427 |
+
<table class="form-table">
|
428 |
+
|
429 |
+
<?php $label = __('Accelerate crawling process integrating filters in main database query', 'wplnst'); ?>
|
430 |
+
|
431 |
+
<?php if ($editable) : ?>
|
432 |
+
|
433 |
+
<tr><td><input <?php self::checked($scan->filtered_query, true); ?> type="checkbox" id="wplnst-filtered-query" name="ck-filtered-query" value="on" /><label for="wplnst-filtered-query"> <?php echo $label; ?></label></td></tr>
|
434 |
+
|
435 |
+
<?php elseif (!empty($scan->anchor_filters) || !empty($scan->include_urls) || !empty($scan->exclude_urls) || !empty($scan->html_attributes)) : ?>
|
436 |
+
|
437 |
+
<tr><td><?php echo $label; ?>: <strong><?php echo $scan->filtered_query? __('Yes', 'wplnst') : __('No', 'wplnst'); ?></strong></td></tr>
|
438 |
+
|
439 |
+
<?php endif; ?>
|
440 |
+
|
441 |
+
</table>
|
442 |
+
|
443 |
+
</div>
|
444 |
+
|
445 |
+
|
446 |
+
<div id="wplnst-status" class="wplnst-tab">
|
447 |
+
|
448 |
+
<table class="form-table">
|
449 |
+
|
450 |
+
<?php if ($editable) : ?>
|
451 |
+
|
452 |
+
<tr>
|
453 |
+
<th<?php if ($link_status_error) echo ' style="color: red;"'; ?>><?php _e('Track links by level', 'wplnst'); ?></th>
|
454 |
+
<td class="wplnst-list"><?php foreach ($status_levels as $key => $value) : ?><input <?php self::checked($key, $scan->status_levels); ?> type="checkbox" name="ck-status-level[<?php echo $key; ?>]" id="ck-status-level-<?php echo $key; ?>" class="wplnst-status-level" value="on" /><label for="ck-status-level-<?php echo $key; ?>"><strong><?php echo $key; ?>00s</strong> <?php echo $value; ?></label><br /><?php endforeach; ?></td>
|
455 |
+
</tr>
|
456 |
+
|
457 |
+
<?php else : ?>
|
458 |
+
|
459 |
+
<tr>
|
460 |
+
<th><?php _e('Track links by level', 'wplnst'); ?></th>
|
461 |
+
<td class="wplnst-value-list"><?php if (empty($scan->status_levels_names) || !is_array($scan->status_levels_names)) : echo '-'; else : echo implode("<br />", array_map('esc_html', $scan->status_levels_names)); endif; ?></td>
|
462 |
+
</tr>
|
463 |
+
|
464 |
+
<?php endif; ?>
|
465 |
+
|
466 |
+
<?php if ($editable) : ?>
|
467 |
+
|
468 |
+
<tr>
|
469 |
+
<th<?php if ($link_status_error) echo ' style="color: red;"'; ?>><?php _e('Track links by code', 'wplnst'); ?></th>
|
470 |
+
<td class="wplnst-list"><table cellpadding="0" cellspacing="0" style="margin: 2px 0 0; padding: 0;">
|
471 |
+
<?php foreach ($status_codes as $level => $codes) : ?>
|
472 |
+
<?php $codes_keys = array_keys($codes); $num = 0; $inc = count($codes) / 2; $inc = ($inc != floor($inc))? floor($inc) : $inc - 1; foreach ($codes as $code => $name) : $num++; $inc++; ?>
|
473 |
+
<tr style="margin: 0; padding: 0 0 25px;">
|
474 |
+
<td style="margin: 0; padding: 0 25px 5px 0;"><input <?php self::checked($code, $scan->status_codes); ?> type="checkbox" name="ck-status-code[<?php echo $code; ?>]" id="ck-status-code-<?php echo $code; ?>" value="on" class="wplnst-code-level wplnst-code-level-<?php echo $level; ?>" /><label for="ck-status-code-<?php echo $code; ?>"><strong><?php echo $code; ?></strong> <?php echo $name; ?></label></td>
|
475 |
+
<td style="margin: 0; padding: 0;"><?php if ($inc < count($codes)) : $code_r = $codes_keys[$inc]; ?><input <?php self::checked($code_r, $scan->status_codes); ?> type="checkbox" name="ck-status-code[<?php echo $code_r; ?>]" id="ck-status-code-<?php echo $code_r; ?>" value="on" class="wplnst-code-level wplnst-code-level-<?php echo $level; ?>" /><label for="ck-status-code-<?php echo $code_r; ?>"><strong><?php echo $code_r; ?></strong> <?php echo $codes[$code_r]; ?></label><?php endif; ?></td>
|
476 |
+
</tr>
|
477 |
+
<?php if ($num >= count($codes) / 2) break; ?>
|
478 |
+
<?php endforeach; ?>
|
479 |
+
<tr style="margin: 0; padding: 0;">
|
480 |
+
<td colspan="2" style="margin: 0; padding: 0;"> </td>
|
481 |
+
</tr>
|
482 |
+
<?php endforeach; ?>
|
483 |
+
</table></td>
|
484 |
+
</tr>
|
485 |
+
|
486 |
+
<?php else : ?>
|
487 |
+
|
488 |
+
<tr>
|
489 |
+
<th><?php _e('Track links by code', 'wplnst'); ?></th>
|
490 |
+
<td class="wplnst-value-list"><?php if (empty($scan->status_codes_names) || !is_array($scan->status_codes_names)) : echo '-'; else : echo implode("<br />", array_map('esc_html', $scan->status_codes_names)); endif; ?></td>
|
491 |
+
</tr>
|
492 |
+
|
493 |
+
<?php endif; ?>
|
494 |
+
|
495 |
+
</table>
|
496 |
+
|
497 |
+
</div>
|
498 |
+
|
499 |
+
|
500 |
+
<?php if (false) : ?><div id="wplnst-scheduled" class="wplnst-tab">
|
501 |
+
|
502 |
+
</div><?php endif; ?>
|
503 |
+
|
504 |
+
|
505 |
+
<div id="wplnst-advanced" class="wplnst-tab">
|
506 |
+
|
507 |
+
<?php if ('end' == $scan->status) : ?>
|
508 |
+
|
509 |
+
<table class="form-table">
|
510 |
+
<tr>
|
511 |
+
<th><?php _e('Number of threads', 'wplnst'); ?></th>
|
512 |
+
<td class="wplnst-value"><?php echo empty($scan->threads->max)? '-' : esc_html($scan->threads->max); ?></td>
|
513 |
+
</tr>
|
514 |
+
<tr>
|
515 |
+
<th><?php _e('Connection timeout', 'wplnst'); ?></th>
|
516 |
+
<td class="wplnst-value"><?php echo empty($scan->threads->connect_timeout)? '-' : esc_html($scan->threads->connect_timeout).' '.__('seconds', 'wplnst'); ?></td>
|
517 |
+
</tr>
|
518 |
+
<tr>
|
519 |
+
<th><?php _e('Request timeout', 'wplnst'); ?></th>
|
520 |
+
<td class="wplnst-value"><?php echo empty($scan->threads->request_timeout)? '-' : esc_html($scan->threads->request_timeout).' '.__('seconds', 'wplnst'); ?></td>
|
521 |
+
</tr>
|
522 |
+
</table>
|
523 |
+
|
524 |
+
<?php else : ?>
|
525 |
+
|
526 |
+
<p><?php _e('All these values are optional, leave them empty to use plugin defaults.', 'wplnst'); ?></p>
|
527 |
+
|
528 |
+
<table class="form-table">
|
529 |
+
<tr>
|
530 |
+
<th><label for="tx-threads"><?php _e('Number of threads', 'wplnst'); ?></label></th>
|
531 |
+
<td><input type="text" name="tx-threads" id="tx-threads" value="<?php echo empty($scan->threads->max)? '' : esc_attr($scan->threads->max); ?>" class="small-text" /> <?php printf(__('(optional, default %d threads)', 'wplnst'), $default_max_threads); ?></td>
|
532 |
+
</tr>
|
533 |
+
<tr>
|
534 |
+
<th><label for="tx-connect-timeout"><?php _e('Connection timeout', 'wplnst'); ?></label></th>
|
535 |
+
<td><input type="text" name="tx-connect-timeout" id="tx-connect-timeout" value="<?php echo empty($scan->threads->connect_timeout)? '' : esc_attr($scan->threads->connect_timeout); ?>" class="small-text" /> <?php _e('seconds', 'wplnst'); ?> <?php printf(__('(optional, default %d seconds)', 'wplnst'), $default_connect_timeout); ?></td>
|
536 |
+
</tr>
|
537 |
+
<tr>
|
538 |
+
<th><label for="tx-request-timeout"><?php _e('Request timeout', 'wplnst'); ?></label></th>
|
539 |
+
<td><input type="text" name="tx-request-timeout" id="tx-request-timeout" value="<?php echo empty($scan->threads->request_timeout)? '' : esc_attr($scan->threads->request_timeout); ?>" class="small-text" /> <?php _e('seconds', 'wplnst'); ?> <?php printf(__('(optional, default %d seconds)', 'wplnst'), $default_request_timeout); ?></td>
|
540 |
+
</tr>
|
541 |
+
</table>
|
542 |
+
|
543 |
+
<?php endif; ?>
|
544 |
+
|
545 |
+
</div>
|
546 |
+
|
547 |
+
|
548 |
+
<p><input type="submit" value="<?php _e('Save scan changes', 'wplnst'); ?>" class="button button-primary" />
|
549 |
+
<?php if ($is_ready && ('wait' == $scan->status)) : ?> <input id="wplnst-save-and-run" type="button" value="<?php _e('Save and run crawler', 'wplnst'); ?>" class="button" /><?php endif; ?>
|
550 |
+
<?php if ($scan->id > 0) : ?> <a href="<?php echo esc_url(WPLNST_Core_Plugin::get_url_scans_delete($scan->id, $scan->hash)); ?>" class="wplnst-scan-delete-isolated wplnst-trash-editor" data-confirm-delete="<?php echo esc_attr(WPLNST_Admin::get_text('scan_delete_confirm')); ?>"><?php _e('Delete this scan', 'wplnst'); ?></a><?php endif; ?></p>
|
551 |
+
|
552 |
+
</div>
|
553 |
+
|
554 |
+
</form><?php
|
555 |
+
}
|
556 |
+
|
557 |
+
|
558 |
+
|
559 |
+
}
|
views/scans-results.php
ADDED
@@ -0,0 +1,1186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Check WP constant
|
4 |
+
if (!defined('ABSPATH'))
|
5 |
+
die;
|
6 |
+
|
7 |
+
// Check dependencies
|
8 |
+
if(!class_exists('WP_List_Table'))
|
9 |
+
require_once(ABSPATH.'wp-admin/includes/class-wp-list-table.php');
|
10 |
+
|
11 |
+
/**
|
12 |
+
* WP Link Status Views Scans Results class
|
13 |
+
*
|
14 |
+
* @package WP Link Status
|
15 |
+
* @subpackage WP Link Status Views
|
16 |
+
*/
|
17 |
+
class WPLNST_Views_Scans_Results extends WP_List_Table {
|
18 |
+
|
19 |
+
|
20 |
+
|
21 |
+
// Properties
|
22 |
+
// ---------------------------------------------------------------------------------------------------
|
23 |
+
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* External data
|
28 |
+
*/
|
29 |
+
protected $results;
|
30 |
+
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Base URL for filters
|
35 |
+
*/
|
36 |
+
protected $base_url;
|
37 |
+
|
38 |
+
|
39 |
+
|
40 |
+
// Initialization
|
41 |
+
// ---------------------------------------------------------------------------------------------------
|
42 |
+
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Constructor
|
47 |
+
*/
|
48 |
+
public function __construct($results) {
|
49 |
+
|
50 |
+
// Dependencies
|
51 |
+
wplnst_require('core', 'util-math');
|
52 |
+
wplnst_require('core', 'util-string');
|
53 |
+
|
54 |
+
// Parent constructor
|
55 |
+
parent::__construct();
|
56 |
+
|
57 |
+
// Copy results
|
58 |
+
$this->results = $results;
|
59 |
+
|
60 |
+
// Base link for filters
|
61 |
+
$this->base_url = esc_url(WPLNST_Core_Plugin::get_url_scans_results($this->results->scan->id));
|
62 |
+
}
|
63 |
+
|
64 |
+
|
65 |
+
|
66 |
+
// Prepare columns and items
|
67 |
+
// ---------------------------------------------------------------------------------------------------
|
68 |
+
|
69 |
+
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Prepare columns and data
|
73 |
+
*/
|
74 |
+
function prepare_items() {
|
75 |
+
|
76 |
+
// Columns
|
77 |
+
$this->setup_columns();
|
78 |
+
|
79 |
+
// Data items
|
80 |
+
$this->setup_items();
|
81 |
+
|
82 |
+
// Pagination
|
83 |
+
$this->setup_pagination();
|
84 |
+
}
|
85 |
+
|
86 |
+
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Setup columns
|
90 |
+
*/
|
91 |
+
private function setup_columns() {
|
92 |
+
|
93 |
+
// Initialize
|
94 |
+
$hidden = array();
|
95 |
+
$sortable = array();
|
96 |
+
|
97 |
+
// Column headers
|
98 |
+
$this->_column_headers = array($this->get_columns(), $hidden, $sortable);
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Columns array
|
105 |
+
*/
|
106 |
+
public function get_columns(){
|
107 |
+
|
108 |
+
// Prepare
|
109 |
+
$columns = array(
|
110 |
+
'cb' => '<input type="checkbox" />',
|
111 |
+
'wplnst-url' => 'URL',
|
112 |
+
'wplnst-status' => __('Status', 'wplnst'),
|
113 |
+
'wplnst-anchor' => __('Anchor text', 'wplnst'),
|
114 |
+
'wplnst-content' => __('Content', 'wplnst'),
|
115 |
+
);
|
116 |
+
|
117 |
+
// Exception
|
118 |
+
if ($this->results->isolated) {
|
119 |
+
unset($columns['cb']);
|
120 |
+
unset($columns['wplnst-content']);
|
121 |
+
} elseif (!$this->get_columns_cb()) {
|
122 |
+
unset($columns['cb']);
|
123 |
+
}
|
124 |
+
|
125 |
+
// Done
|
126 |
+
return $columns;
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Check if needed a cb column
|
133 |
+
*/
|
134 |
+
protected function get_columns_cb() {
|
135 |
+
return false;
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Setup data items
|
142 |
+
*/
|
143 |
+
private function setup_items() {
|
144 |
+
|
145 |
+
// Dependencies
|
146 |
+
wplnst_require('core', 'types-curl');
|
147 |
+
|
148 |
+
// Initialize
|
149 |
+
$status_levels = WPLNST_Core_Types::get_status_levels();
|
150 |
+
$status_codes = WPLNST_Core_Types::get_status_codes_raw();
|
151 |
+
|
152 |
+
// Populate data
|
153 |
+
$this->items = array();
|
154 |
+
foreach ($this->results->rows as $row) {
|
155 |
+
|
156 |
+
|
157 |
+
// Normalize identifier
|
158 |
+
$item = array(
|
159 |
+
'ID' => $row->url_id,
|
160 |
+
'url' => $row->url,
|
161 |
+
'url_id' => $row->url_id,
|
162 |
+
'loc_id' => $row->loc_id,
|
163 |
+
'status_level' => $row->status_level,
|
164 |
+
'redirect_url' => $row->redirect_url,
|
165 |
+
'redirect_url_id' => $row->redirect_url_id,
|
166 |
+
'object_id' => $row->object_id,
|
167 |
+
'object_type' => $row->object_type,
|
168 |
+
'object_field' => $row->object_field,
|
169 |
+
'link_type' => $row->link_type,
|
170 |
+
'ignored' => $row->ignored,
|
171 |
+
'unlinked' => $row->unlinked,
|
172 |
+
'nofollow' => $row->nofollow,
|
173 |
+
'anchored' => $row->anchored,
|
174 |
+
'attributed' => $row->attributed,
|
175 |
+
);
|
176 |
+
|
177 |
+
|
178 |
+
/* First column: URL */
|
179 |
+
|
180 |
+
|
181 |
+
// Add unlinked flag
|
182 |
+
$url = '<span id="wplnst-results-url-unlinked-'.$row->loc_id.'" class="wplnst-results-mark wplnst-results-mark-unlinked'.($row->unlinked? '' : ' wplnst-display-none').'">'.__('Unlinked', 'wplnst').'</span>';
|
183 |
+
|
184 |
+
// Check link
|
185 |
+
if ('http' == $row->scheme || 'https' == $row->scheme || 'ftp' == $row->scheme) {
|
186 |
+
|
187 |
+
// Link to an browser resource
|
188 |
+
$url .= '<strong><a href="'.esc_url($row->url).'" target="_blank" id="wplnst-results-url-loc-'.$row->loc_id.'" title="'.esc_url($row->url).'">'.esc_html($row->raw_url).'</a></strong>';
|
189 |
+
|
190 |
+
// No link
|
191 |
+
} else {
|
192 |
+
|
193 |
+
// Unsupported linkable protocol
|
194 |
+
$url .= '<strong><span id="wplnst-results-url-loc-'.$row->loc_id.'">'.esc_html($row->raw_url).'</span></strong>';
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
// Redirection
|
199 |
+
$class_redirection = ('3' == $row->status_level && $row->redirect_url_id > 0 && !empty($row->redirect_url))? '' : 'wplnst-display-none';
|
200 |
+
$url .= '<span id="wplnst-results-url-redir-'.$row->loc_id.'" class="'.$class_redirection.'"><br />→ <a id="wplnst-results-url-redir-href-'.$row->loc_id.'" href="'.esc_url($row->redirect_url).'" target="_blank">'.esc_html($row->redirect_url).'</a></span>';
|
201 |
+
|
202 |
+
|
203 |
+
// Check error
|
204 |
+
$class_error = (!empty($row->status_code) || empty($row->curl_errno))? 'wplnst-display-none' : '';
|
205 |
+
$url .= '<div id="wplnst-results-url-error-'.$row->loc_id.'" class="'.$class_error.'">';
|
206 |
+
if (empty($row->status_code) && !empty($row->curl_errno)) {
|
207 |
+
|
208 |
+
// Retrieve error type
|
209 |
+
$curl_error = WPLNST_Core_Types_CURL::get_code_info($row->curl_errno);
|
210 |
+
|
211 |
+
// Unknown
|
212 |
+
if (empty($curl_error)) {
|
213 |
+
$url .= '<strong id="wplnst-results-url-error-title-'.$row->loc_id.'">'.__('Error code ', 'wplnst').$row->curl_errno.'</strong> <span id="wplnst-results-url-error-code-'.$row->loc_id.'" class="wplnst-results-url-error-code"></span><br /><span id="wplnst-results-url-error-desc-'.$row->loc_id.'"></span>';
|
214 |
+
|
215 |
+
// Knowed error
|
216 |
+
} else {
|
217 |
+
$url .= '<strong id="wplnst-results-url-error-title-'.$row->loc_id.'">'.esc_html($curl_error['title']).'</strong> <span id="wplnst-results-url-error-code-'.$row->loc_id.'" class="wplnst-results-url-error-code">'.esc_html(sprintf(__('error code %d', 'wplnst'), $row->curl_errno)).'</span><br /><span id="wplnst-results-url-error-desc-'.$row->loc_id.'">'.esc_html($curl_error['desc']).'</span>';
|
218 |
+
}
|
219 |
+
} else {
|
220 |
+
$url .= '<strong id="wplnst-results-url-error-title-'.$row->loc_id.'"></strong> <span id="wplnst-results-url-error-code-'.$row->loc_id.'" class="wplnst-results-url-error-code"></span><br /><span id="wplnst-results-url-error-desc-'.$row->loc_id.'"></span>';
|
221 |
+
}
|
222 |
+
$url .= '</div>';
|
223 |
+
|
224 |
+
|
225 |
+
// Check redirection error
|
226 |
+
$error_redir = !empty($row->redirect_url_id) && empty($row->redirect_url_status) && !empty($row->redirect_curl_errno);
|
227 |
+
$class_error_redir = $error_redir? '' : 'wplnst-display-none';
|
228 |
+
$url .= '<div id="wplnst-results-url-error-redir-'.$row->loc_id.'" class="'.$class_error_redir.'">→ ';
|
229 |
+
if ($error_redir) {
|
230 |
+
|
231 |
+
// Retrieve error type
|
232 |
+
$curl_error = WPLNST_Core_Types_CURL::get_code_info($row->redirect_curl_errno);
|
233 |
+
|
234 |
+
// Unknown
|
235 |
+
if (empty($curl_error)) {
|
236 |
+
$url .= '<strong id="wplnst-results-url-error-redir-title-'.$row->loc_id.'">'.__('Error code ', 'wplnst').$row->curl_errno.'</strong> <span id="wplnst-results-url-error-redir-code-'.$row->loc_id.'" class="wplnst-results-url-error-code"></span><br /><span id="wplnst-results-url-error-redir-desc-'.$row->loc_id.'"></span>';
|
237 |
+
|
238 |
+
// Knowed error
|
239 |
+
} else {
|
240 |
+
$url .= '<strong id="wplnst-results-url-error-redir-title-'.$row->loc_id.'">'.esc_html($curl_error['title']).'</strong> <span id="wplnst-results-url-error-redir-code-'.$row->loc_id.'" class="wplnst-results-url-error-code">'.esc_html(sprintf(__('error code %d', 'wplnst'), $row->redirect_curl_errno)).'</span><br /><span id="wplnst-results-url-error-redir-desc-'.$row->loc_id.'">'.esc_html($curl_error['desc']).'</span>';
|
241 |
+
}
|
242 |
+
} else {
|
243 |
+
$url .= '<strong id="wplnst-results-url-error-redir-title-'.$row->loc_id.'"></strong> <span id="wplnst-results-url-error-redir-code-'.$row->loc_id.'" class="wplnst-results-url-error-code"></span><br /><span id="wplnst-results-url-error-redir-desc-'.$row->loc_id.'"></span>';
|
244 |
+
}
|
245 |
+
$url .= '</div>';
|
246 |
+
|
247 |
+
// Check relative or absolute
|
248 |
+
$url .= '<div id="wplnst-results-url-full-'.$row->loc_id.'" class="wplnst-results-url-full'.(($row->relative || $row->absolute)? '' : ' wplnst-display-none').'">'.esc_html($row->url).'</div>';
|
249 |
+
|
250 |
+
|
251 |
+
// Prepare data for https mark
|
252 |
+
$is_https = ('https' == $row->scheme);
|
253 |
+
|
254 |
+
// Prepare data for redirections
|
255 |
+
$redirs_count = 0;
|
256 |
+
if ($redirs = ('3' == $row->status_level && $row->redirect_url_id > 0 && !empty($row->redirect_url))) {
|
257 |
+
$redirs_steps = @json_decode($row->redirect_steps, true);
|
258 |
+
if (!empty($redirs_steps) && is_array($redirs_steps))
|
259 |
+
$redirs_count = count($redirs_steps);
|
260 |
+
}
|
261 |
+
|
262 |
+
// Prepare row of marks
|
263 |
+
$mark_modified = '<span class="wplnst-results-mark wplnst-results-mark-modified' .($row->modified? '' : ' wplnst-display-none').'">'.__('Modified', 'wplnst').'</span>';
|
264 |
+
$mark_nofollow = '<span class="wplnst-results-mark wplnst-results-mark-nofollow' .($row->nofollow? '' : ' wplnst-display-none').'">nofollow</span>';
|
265 |
+
$mark_relative = '<span class="wplnst-results-mark wplnst-results-mark-relative' .($row->relative? '' : ' wplnst-display-none').'">'.__('Relative', 'wplnst').'</span>';
|
266 |
+
$mark_absolute = '<span class="wplnst-results-mark wplnst-results-mark-absolute' .($row->absolute? '' : ' wplnst-display-none').'">'.__('Absolute', 'wplnst').'</span>';
|
267 |
+
$mark_spaced = '<span class="wplnst-results-mark wplnst-results-mark-spaced' .($row->spaced? '' : ' wplnst-display-none').'">'.__('Spaced', 'wplnst').'</span>';
|
268 |
+
$mark_malformed = '<span class="wplnst-results-mark wplnst-results-mark-malformed'.($row->malformed? '' : ' wplnst-display-none').'">'.__('Malformed', 'wplnst').'</span>';
|
269 |
+
$mark_https = '<span class="wplnst-results-mark wplnst-results-mark-https' .($is_https? '' : ' wplnst-display-none').'">HTTPS</span>';
|
270 |
+
$mark_protorel = '<span class="wplnst-results-mark wplnst-results-mark-protorel' .($row->protorel? '' : ' wplnst-display-none').'">'.__('Protocol relative', 'wplnst').'</span>';
|
271 |
+
$mark_ignored = '<span class="wplnst-results-mark wplnst-results-mark-ignored' .($row->ignored? '' : ' wplnst-display-none').'">'.__('Ignored', 'wplnst').'</span>';
|
272 |
+
$mark_redirs = '<span class="wplnst-results-mark wplnst-results-mark-redirs' .($redirs? '' : ' wplnst-display-none').'">'.((!$redirs || empty($redirs_count) || 1 == $redirs_count)? '1 redirect' : $redirs_count.' redirects').'</span>';
|
273 |
+
|
274 |
+
// Add new row checking visibility
|
275 |
+
$mark_visible = ($row->modified || $row->nofollow || $row->relative || $row->absolute || $row->spaced || $row->malformed || $is_https || $row->protorel || $row->ignored || $redirs);
|
276 |
+
$url .= '<div id="wplnst-results-url-marks-'.$row->loc_id.'" class="wplnst-results-url-marks'.($mark_visible? '' : ' wplnst-display-none').'">'.$mark_modified.$mark_nofollow.$mark_relative.$mark_absolute.$mark_spaced.$mark_malformed.$mark_https.$mark_protorel.$mark_ignored.$mark_redirs.'</div>';
|
277 |
+
|
278 |
+
|
279 |
+
// Done
|
280 |
+
$item['wplnst-url'] = '<div class="wplnst-row-url">'.$url.'</div>';
|
281 |
+
|
282 |
+
|
283 |
+
|
284 |
+
/* Second column: status, redirection status, and time/size info */
|
285 |
+
|
286 |
+
// Start container
|
287 |
+
$item['wplnst-status'] = '<div class="wplnst-url-status-code">';
|
288 |
+
|
289 |
+
// Prepare status classes
|
290 |
+
$class_status_error = empty($row->curl_errno)? ' wplnst-display-none' : '';
|
291 |
+
$class_status_code = empty($row->status_code)? ' wplnst-display-none' : '';
|
292 |
+
|
293 |
+
// Prepare status Code
|
294 |
+
$status_code_label = isset($status_codes[$row->status_code])? ' '.$status_codes[$row->status_code] : '';
|
295 |
+
|
296 |
+
// Prepare rechecked mark
|
297 |
+
$mark_rechecked = ' <span id="wplnst-url-status-recheck-mark-'.$row->loc_id.'" class="wplnst-results-mark wplnst-results-mark-rechecked'.($row->rechecked? '' : ' wplnst-display-none').'">Rechecked</span>';
|
298 |
+
|
299 |
+
// Status code result
|
300 |
+
$item['wplnst-status'] .= '<div class="wplnst-url-status-code-result"><span id="wplnst-url-status-code-0-loc-'.$row->loc_id.'" class="wplnst-url-status-code-0'.$class_status_error.'">'.__('Request error', 'wplnst').'</span><span id="wplnst-url-status-code-loc-'.$row->loc_id.'" class="wplnst-url-status-code-'.esc_attr($row->status_level).$class_status_code.'">'.esc_html($row->status_code.$status_code_label).'</span>'.$mark_rechecked.'</div>';
|
301 |
+
|
302 |
+
// Prepare redirections status
|
303 |
+
$redir_status_level = $redir_status_label = '';
|
304 |
+
$status_redir = (!empty($row->redirect_url_id) && (!empty($row->redirect_url_status) || !empty($row->redirect_curl_errno)));
|
305 |
+
if ($status_redir && !empty($row->redirect_url_status)) {
|
306 |
+
$redir_status_level = mb_substr($row->redirect_url_status, 0, 1);
|
307 |
+
$redir_status_label = $row->redirect_url_status.(isset($status_codes[$row->redirect_url_status])? ' '.$status_codes[$row->redirect_url_status] : '');
|
308 |
+
}
|
309 |
+
|
310 |
+
// Prepare redirection classes
|
311 |
+
$class_status_redir = $status_redir? '' : ' wplnst-display-none';
|
312 |
+
$class_status_redir_error = ($status_redir && !empty($row->redirect_curl_errno))? '' : ' wplnst-display-none';
|
313 |
+
$class_status_redir_code = ($status_redir && !empty($row->redirect_url_status))? '' : ' wplnst-display-none';
|
314 |
+
|
315 |
+
// Redirection status code
|
316 |
+
$item['wplnst-status'] .= '<div id="wplnst-url-status-code-redir-'.$row->loc_id.'" class="wplnst-url-status-code-redir'.$class_status_redir.'"><span class="wplnst-url-status-code-redir-arrow">→ </span><span id="wplnst-url-status-code-redir-error-'.$row->loc_id.'" class="wplnst-url-status-code-0'.$class_status_redir_error.'">'.__('Request error', 'wplnst').'</span><span id="wplnst-url-status-code-redir-status-'.$row->loc_id.'" class="wplnst-url-status-code-'.esc_attr($redir_status_level).$class_status_redir_code.'">'.esc_html($redir_status_label).'</span></div>';
|
317 |
+
|
318 |
+
// End status container
|
319 |
+
$item['wplnst-status'] .= '</div>';
|
320 |
+
|
321 |
+
// Time and size
|
322 |
+
$item['wplnst-status'] .= '<div class="wplnst-url-status-info"><span id="wplnst-url-status-info-time-'.$row->loc_id.'">'.number_format_i18n($row->total_time, 3).' s</span>'.(($row->total_bytes > 0)? '<span id="wplnst-url-status-info-split-'.$row->loc_id.'" class="wplnst-url-status-info-split"> | </span><span id="wplnst-url-status-info-size-'.$row->loc_id.'">'.wplnst_format_bytes($row->total_bytes).'</span>' : '<span id="wplnst-url-status-info-split-'.$row->loc_id.'" class="wplnst-url-status-info-split wplnst-display-none"> | </span><span id="wplnst-url-status-info-size-'.$row->loc_id.'" class="wplnst-display-none"></span>').'</div>';
|
323 |
+
|
324 |
+
|
325 |
+
|
326 |
+
/* Third column: anchor text */
|
327 |
+
|
328 |
+
// Set text anchor
|
329 |
+
if ('links' == $row->link_type) {
|
330 |
+
|
331 |
+
// Prepare modified mark
|
332 |
+
$mark_anchored = '<div id="wplnst-results-anchor-mod-'.$row->loc_id.'" class="wplnst-results-anchor-mod'.($row->anchored? '' : ' wplnst-display-none').'"><span class="wplnst-results-mark wplnst-results-mark-modified">'.__('Modified', 'wplnst').'</span></div>';
|
333 |
+
|
334 |
+
// Anchor text
|
335 |
+
$item['wplnst-anchor'] = '<div class="wplnst-anchor-link"><span id="wplnst-results-anchor-loc-'.$row->loc_id.'">'.esc_html($row->anchor).'</span>'.$mark_anchored.'</div>';
|
336 |
+
|
337 |
+
// Is an image
|
338 |
+
} elseif ('images' == $row->link_type) {
|
339 |
+
|
340 |
+
// Image info
|
341 |
+
$item['wplnst-anchor'] = '<div class="wplnst-anchor-image wplnst-row-dashicon"><span>'.esc_html(__('Image', 'wplnst')).'</span></div>';
|
342 |
+
}
|
343 |
+
|
344 |
+
|
345 |
+
|
346 |
+
/* Fourth column: Content host */
|
347 |
+
|
348 |
+
// Check no isolated
|
349 |
+
if (!$this->results->isolated) {
|
350 |
+
|
351 |
+
// Default content link
|
352 |
+
$item['wplnst-content'] = $row->object_type.' '.$row->object_id;
|
353 |
+
|
354 |
+
// Extract identifier
|
355 |
+
$object_id = (int) $row->object_id;
|
356 |
+
|
357 |
+
// Column content for posts
|
358 |
+
if ('posts' == $row->object_type) {
|
359 |
+
|
360 |
+
// Retrieve post
|
361 |
+
$post = get_post($object_id);
|
362 |
+
|
363 |
+
// Check post object
|
364 |
+
if (!empty($post) && is_object($post) && 'WP_Post' == get_class($post)) {
|
365 |
+
|
366 |
+
// Copy object
|
367 |
+
$item['post'] = $post;
|
368 |
+
$item['can_edit'] = current_user_can('edit_post', $post->ID);
|
369 |
+
|
370 |
+
// Prepare title
|
371 |
+
$title = _draft_or_post_title($post);
|
372 |
+
|
373 |
+
// Check edit post link
|
374 |
+
if ($item['can_edit'] && 'trash' != $post->post_status) {
|
375 |
+
|
376 |
+
// Copy edit post link
|
377 |
+
$item['edit_post_link'] = get_edit_post_link($post->ID);
|
378 |
+
|
379 |
+
// Editable post link
|
380 |
+
$post_row = '<strong><a href="'.$item['edit_post_link'].'" title="'.esc_attr(sprintf(__( 'Edit “%s”'), $title)).'" target="_blank">'.$title.'</a></strong>';
|
381 |
+
|
382 |
+
// Post without link
|
383 |
+
} else {
|
384 |
+
|
385 |
+
// Only title
|
386 |
+
$post_row = '<strong>'.$title.'</strong>';
|
387 |
+
}
|
388 |
+
|
389 |
+
// Not found
|
390 |
+
} else {
|
391 |
+
|
392 |
+
// Not found item
|
393 |
+
$post_row = sprintf(__('Entry %d not found', 'wplnst'), $object_id);
|
394 |
+
}
|
395 |
+
|
396 |
+
// Set column value
|
397 |
+
$item['wplnst-content'] = '<div class="wplnst-content-post wplnst-row-dashicon"><span>'.$post_row.'</span></div>';
|
398 |
+
|
399 |
+
// Column content for comments
|
400 |
+
} elseif ('comments' == $row->object_type) {
|
401 |
+
|
402 |
+
// Retrieve comment
|
403 |
+
$object_id = (int) $row->object_id;
|
404 |
+
$comment = get_comment($object_id);
|
405 |
+
|
406 |
+
// Check comment object
|
407 |
+
if (!empty($comment) && is_object($comment)) {
|
408 |
+
|
409 |
+
// Copy object
|
410 |
+
$item['comment'] = $comment;
|
411 |
+
$item['can_edit'] = current_user_can('edit_comment', $comment->comment_ID);
|
412 |
+
|
413 |
+
// Isolate comment author
|
414 |
+
$comment_author = ('' === $comment->comment_author)? '' : '<strong>'.esc_html($comment->comment_author).'</strong> — ';
|
415 |
+
|
416 |
+
// First comment chars
|
417 |
+
$comment_text = wplnst_crop_text($comment->comment_content, 50);
|
418 |
+
|
419 |
+
// Check editable comment
|
420 |
+
if ($item['can_edit']) {
|
421 |
+
|
422 |
+
// Submitted on link
|
423 |
+
$comment_row = '<a href="'.admin_url('comment.php?action=editcomment&c='.$comment->comment_ID).'">'.$comment_author.$comment_text.'</a>';
|
424 |
+
|
425 |
+
// Check approved comment
|
426 |
+
} elseif ('approved' == wp_get_comment_status($comment->comment_ID)) {
|
427 |
+
|
428 |
+
// View comment
|
429 |
+
$comment_row = '<a href="'.esc_url(get_comment_link($comment->comment_ID)).'" target="_blank">'.$comment_author.$comment_text.'</a>';
|
430 |
+
|
431 |
+
// No link
|
432 |
+
} else {
|
433 |
+
|
434 |
+
// Only text
|
435 |
+
$comment_row = $comment_author.$comment_text;
|
436 |
+
}
|
437 |
+
|
438 |
+
// Not found
|
439 |
+
} else {
|
440 |
+
|
441 |
+
// Not found item
|
442 |
+
$comment_row = sprintf(__('Comment %d not found', 'wplnst'), $object_id);
|
443 |
+
}
|
444 |
+
|
445 |
+
// Set column value
|
446 |
+
$item['wplnst-content'] = '<div class="wplnst-content-comment wplnst-row-dashicon"><span>'.$comment_row.'</span></div>';
|
447 |
+
|
448 |
+
// Column content for links
|
449 |
+
} elseif ('blogroll' == $row->object_type) {
|
450 |
+
|
451 |
+
// Retrieve link
|
452 |
+
$object_id = (int) $row->object_id;
|
453 |
+
$bookmark = get_bookmark($object_id);
|
454 |
+
|
455 |
+
// Check link object
|
456 |
+
if (!empty($bookmark) && is_object($bookmark)) {
|
457 |
+
|
458 |
+
// Copy object
|
459 |
+
$item['bookmark'] = $bookmark;
|
460 |
+
$item['can_edit'] = current_user_can('manage_links', $bookmark->link_id);
|
461 |
+
|
462 |
+
// Prepare visible URL
|
463 |
+
$link_url = esc_html(url_shorten($bookmark->link_url));
|
464 |
+
|
465 |
+
// Check editable comment
|
466 |
+
if ($item['can_edit']) {
|
467 |
+
|
468 |
+
// Submitted on link
|
469 |
+
$bookmark_row = '<a href="'.admin_url('link.php?action=edit&link_id='.((int) $bookmark->link_id)).'" target="_blank">'.$link_url.'</a>';
|
470 |
+
|
471 |
+
// No link
|
472 |
+
} else {
|
473 |
+
|
474 |
+
// Only text
|
475 |
+
$bookmark_row = '<a href="'.esc_url($link->link_url).'" target="_blank" target="_blank">'.$link_url.'</a>';
|
476 |
+
}
|
477 |
+
|
478 |
+
// Not found
|
479 |
+
} else {
|
480 |
+
|
481 |
+
// Not found item
|
482 |
+
$bookmark_row = sprintf(__('Bookmark %d not found', 'wplnst'), $object_id);
|
483 |
+
}
|
484 |
+
|
485 |
+
// Set column value
|
486 |
+
$item['wplnst-content'] = '<div class="wplnst-content-bookmark wplnst-row-dashicon"><span>'.$bookmark_row.'</span></div>';
|
487 |
+
}
|
488 |
+
}
|
489 |
+
|
490 |
+
// Add row
|
491 |
+
$this->items[] = $item;
|
492 |
+
}
|
493 |
+
}
|
494 |
+
|
495 |
+
|
496 |
+
|
497 |
+
// Column actions
|
498 |
+
// ---------------------------------------------------------------------------------------------------
|
499 |
+
|
500 |
+
|
501 |
+
|
502 |
+
/**
|
503 |
+
* Get an associative array ( option_name => option_title ) with the list
|
504 |
+
* of bulk actions available on this table.
|
505 |
+
*
|
506 |
+
* @return array
|
507 |
+
*/
|
508 |
+
protected function get_bulk_actions() {
|
509 |
+
return array();
|
510 |
+
}
|
511 |
+
|
512 |
+
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Handles the checkbox column output.
|
516 |
+
*/
|
517 |
+
protected function column_cb($item) {
|
518 |
+
if (!$this->results->isolated) {
|
519 |
+
$disabled = !(isset($item['post']) || isset($item['comment']) || isset($item['bookmark']));
|
520 |
+
return sprintf('<input type="checkbox"'.($disabled? ' disabled' : ' class="wplnst-ck-loc-id"').' value="%s" />', $item['loc_id']);
|
521 |
+
}
|
522 |
+
}
|
523 |
+
|
524 |
+
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Default method to display a column
|
528 |
+
*
|
529 |
+
* @param array $item
|
530 |
+
* @param string $column_name
|
531 |
+
*
|
532 |
+
* @return mixed
|
533 |
+
*/
|
534 |
+
protected function column_default($item, $column_name) {
|
535 |
+
|
536 |
+
// Actions for URL column
|
537 |
+
if ('wplnst-url' == $column_name) {
|
538 |
+
|
539 |
+
// URL actions row
|
540 |
+
$actions = $this->column_actions_url($item);
|
541 |
+
if (!empty($actions) && is_array($actions))
|
542 |
+
return sprintf('%1$s %2$s', $item[$column_name], $this->row_actions($actions, $item['loc_id']));
|
543 |
+
|
544 |
+
// Actions for status column
|
545 |
+
} elseif ('wplnst-status' == $column_name) {
|
546 |
+
|
547 |
+
// Status actions row
|
548 |
+
$actions = $this->column_actions_status($item);
|
549 |
+
if (!empty($actions) && is_array($actions))
|
550 |
+
return sprintf('%1$s %2$s', $item[$column_name], $this->row_actions($actions, $item['loc_id']));
|
551 |
+
|
552 |
+
// Actions for the link anchor
|
553 |
+
} elseif ('wplnst-anchor' == $column_name) {
|
554 |
+
|
555 |
+
// Check links type and available anchor
|
556 |
+
if ('links' == $item['link_type'] && false === strpos($item['object_field'], 'custom_field_url_')) {
|
557 |
+
|
558 |
+
// Anchor actions row
|
559 |
+
$actions = $this->column_actions_anchor($item);
|
560 |
+
if (!empty($actions) && is_array($actions))
|
561 |
+
return sprintf('%1$s %2$s', $item[$column_name], $this->row_actions($actions, $item['loc_id']));
|
562 |
+
}
|
563 |
+
|
564 |
+
// Actions for content column
|
565 |
+
} elseif ('wplnst-content' == $column_name) {
|
566 |
+
|
567 |
+
// Posts actions
|
568 |
+
if ('posts' == $item['object_type']) {
|
569 |
+
|
570 |
+
// Content post actions row
|
571 |
+
$actions = $this->column_actions_content_posts($item);
|
572 |
+
if (!empty($actions) && is_array($actions))
|
573 |
+
return sprintf('%1$s %2$s', $item[$column_name], $this->row_actions($actions, $item['loc_id']));
|
574 |
+
|
575 |
+
// Comments actions
|
576 |
+
} elseif ('comments' == $item['object_type']) {
|
577 |
+
|
578 |
+
// Content comments actions row
|
579 |
+
$actions = $this->column_actions_content_comments($item);
|
580 |
+
if (!empty($actions) && is_array($actions))
|
581 |
+
return sprintf('%1$s %2$s', $item[$column_name], $this->row_actions($actions, $item['loc_id']));
|
582 |
+
|
583 |
+
// Blogroll actions
|
584 |
+
} elseif ('blogroll' == $item['object_type']) {
|
585 |
+
|
586 |
+
// Content bookmarks actions row
|
587 |
+
$actions = $this->column_actions_content_blogroll($item);
|
588 |
+
if (!empty($actions) && is_array($actions))
|
589 |
+
return sprintf('%1$s %2$s', $item[$column_name], $this->row_actions($actions, $item['loc_id']));
|
590 |
+
}
|
591 |
+
}
|
592 |
+
|
593 |
+
// Default column
|
594 |
+
return $item[$column_name];
|
595 |
+
}
|
596 |
+
|
597 |
+
|
598 |
+
|
599 |
+
/**
|
600 |
+
* Column URL row actions
|
601 |
+
*/
|
602 |
+
private function column_actions_url($item) {
|
603 |
+
|
604 |
+
// Initialize
|
605 |
+
$actions = array();
|
606 |
+
|
607 |
+
// For not isolated
|
608 |
+
if (!$this->results->isolated) {
|
609 |
+
|
610 |
+
// Check object
|
611 |
+
if (isset($item['can_edit']) && $item['can_edit']) {
|
612 |
+
|
613 |
+
// Add results actions
|
614 |
+
$actions = apply_filters('wplnst_results_actions_url', $actions, $item);
|
615 |
+
}
|
616 |
+
|
617 |
+
// Filter by URL (for future versions)
|
618 |
+
// $actions['wplnst-action-filter'] = '<a href="'.esc_url(WPLNST_Core_Plugin::get_url_scans_locations($this->results->scan->id, $item['url_id'])).'" class="wplnst-results-action">'.__('Filter by URL', 'wplnst').'</a>';
|
619 |
+
}
|
620 |
+
|
621 |
+
// Done
|
622 |
+
return $actions;
|
623 |
+
}
|
624 |
+
|
625 |
+
|
626 |
+
|
627 |
+
/**
|
628 |
+
* Column Status row actions
|
629 |
+
*/
|
630 |
+
private function column_actions_status($item) {
|
631 |
+
|
632 |
+
// Initialize
|
633 |
+
$actions = array();
|
634 |
+
|
635 |
+
// For not isolated
|
636 |
+
if (!$this->results->isolated) {
|
637 |
+
|
638 |
+
// Add results actions
|
639 |
+
$actions = apply_filters('wplnst_results_actions_status', $actions, $item);
|
640 |
+
}
|
641 |
+
|
642 |
+
// Done
|
643 |
+
return $actions;
|
644 |
+
}
|
645 |
+
|
646 |
+
|
647 |
+
|
648 |
+
/**
|
649 |
+
* Column Anchor row actions
|
650 |
+
*/
|
651 |
+
private function column_actions_anchor($item) {
|
652 |
+
|
653 |
+
// Initialize
|
654 |
+
$actions = array();
|
655 |
+
|
656 |
+
// For not isolated
|
657 |
+
if (!$this->results->isolated) {
|
658 |
+
|
659 |
+
// Check editable object
|
660 |
+
if (isset($item['can_edit']) && $item['can_edit']) {
|
661 |
+
|
662 |
+
// Add results actions
|
663 |
+
$actions = apply_filters('wplnst_results_actions_anchor', $actions, $item);
|
664 |
+
}
|
665 |
+
}
|
666 |
+
|
667 |
+
// Done
|
668 |
+
return $actions;
|
669 |
+
}
|
670 |
+
|
671 |
+
|
672 |
+
|
673 |
+
/**
|
674 |
+
* Column content row actions for posts
|
675 |
+
*/
|
676 |
+
private function column_actions_content_posts($item) {
|
677 |
+
|
678 |
+
// Check object
|
679 |
+
if (!isset($item['post']))
|
680 |
+
return array();
|
681 |
+
|
682 |
+
// Initialize
|
683 |
+
$actions = array();
|
684 |
+
$post = $item['post'];
|
685 |
+
|
686 |
+
// Permissions
|
687 |
+
$can_edit_post = $item['can_edit'];
|
688 |
+
$post_type_object = get_post_type_object($post->post_type);
|
689 |
+
|
690 |
+
// Check edit post action
|
691 |
+
if ($can_edit_post && 'trash' != $post->post_status)
|
692 |
+
$actions['edit'] = '<a href="'.$item['edit_post_link'].'" title="'.esc_attr__('Edit this item').'" target="_blank">'.__( 'Edit' ).'</a>';
|
693 |
+
|
694 |
+
// Check delete post action
|
695 |
+
if (current_user_can('delete_post', $post->ID)) {
|
696 |
+
|
697 |
+
// Post in trash
|
698 |
+
if ('trash' == $post->post_status)
|
699 |
+
$actions['untrash'] = "<a title='" . esc_attr__( 'Restore this item from the Trash' ) . "' href='" . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ) . "'>" . __( 'Restore' ) . "</a>";
|
700 |
+
|
701 |
+
// Post to trash
|
702 |
+
elseif (EMPTY_TRASH_DAYS)
|
703 |
+
$actions['trash'] = "<a class='submitdelete' title='".esc_attr__('Move this item to the Trash')."' href='".get_delete_post_link($post->ID)."'>".__('Trash')."</a>";
|
704 |
+
|
705 |
+
// Remove Permanently
|
706 |
+
if ('trash' == $post->post_status || !EMPTY_TRASH_DAYS)
|
707 |
+
$actions['delete'] = "<a class='submitdelete wplnst-remove-entry' title='".esc_attr__('Delete this item permanently')."' href='".get_delete_post_link($post->ID, '', true)."'>".__('Delete Permanently')."</a>";
|
708 |
+
}
|
709 |
+
|
710 |
+
// Check view post action
|
711 |
+
if ($post_type_object->public) {
|
712 |
+
|
713 |
+
// Post title
|
714 |
+
$title = _draft_or_post_title();
|
715 |
+
|
716 |
+
// Not published
|
717 |
+
if (in_array($post->post_status, array('pending', 'draft', 'future'))) {
|
718 |
+
if ($can_edit_post) {
|
719 |
+
$preview_link = set_url_scheme(get_permalink($post->ID));
|
720 |
+
/** This filter is documented in wp-admin/includes/meta-boxes.php */
|
721 |
+
$preview_link = apply_filters( 'preview_post_link', add_query_arg('preview', 'true', $preview_link ), $post );
|
722 |
+
$actions['view'] = '<a href="' . esc_url( $preview_link ) . '" title="' . esc_attr( sprintf( __( 'Preview “%s”' ), $title ) ) . '" rel="permalink" target="_blank">' . __( 'Preview' ) . '</a>';
|
723 |
+
}
|
724 |
+
|
725 |
+
// Not in trash
|
726 |
+
} elseif ( 'trash' != $post->post_status ) {
|
727 |
+
$actions['view'] = '<a href="' . get_permalink( $post->ID ) . '" title="' . esc_attr( sprintf( __( 'View “%s”' ), $title ) ) . '" rel="permalink" target="_blank">' . __( 'View' ) . '</a>';
|
728 |
+
}
|
729 |
+
}
|
730 |
+
|
731 |
+
// Done
|
732 |
+
return $actions;
|
733 |
+
}
|
734 |
+
|
735 |
+
|
736 |
+
|
737 |
+
/**
|
738 |
+
* Column content row actions for comments
|
739 |
+
*/
|
740 |
+
private function column_actions_content_comments($item) {
|
741 |
+
|
742 |
+
// Check object
|
743 |
+
if (!isset($item['comment']))
|
744 |
+
return array();
|
745 |
+
|
746 |
+
// Initialize
|
747 |
+
$actions = array();
|
748 |
+
$comment = $item['comment'];
|
749 |
+
|
750 |
+
// Check editable comment
|
751 |
+
if ($item['can_edit']) {
|
752 |
+
|
753 |
+
// Real comment status
|
754 |
+
$the_comment_status = wp_get_comment_status($comment->comment_ID);
|
755 |
+
|
756 |
+
// Remove and approve nonces
|
757 |
+
$del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) );
|
758 |
+
$approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) );
|
759 |
+
|
760 |
+
// Base URL
|
761 |
+
$url = "comment.php?c=$comment->comment_ID";
|
762 |
+
|
763 |
+
// All URLs
|
764 |
+
$approve_url = esc_url( $url . "&action=approvecomment&$approve_nonce" );
|
765 |
+
$unapprove_url = esc_url( $url . "&action=unapprovecomment&$approve_nonce" );
|
766 |
+
$spam_url = esc_url( $url . "&action=spamcomment&$del_nonce" );
|
767 |
+
$unspam_url = esc_url( $url . "&action=unspamcomment&$del_nonce" );
|
768 |
+
$trash_url = esc_url( $url . "&action=trashcomment&$del_nonce" );
|
769 |
+
$untrash_url = esc_url( $url . "&action=untrashcomment&$del_nonce" );
|
770 |
+
$delete_url = esc_url( $url . "&action=deletecomment&$del_nonce" );
|
771 |
+
|
772 |
+
// Preorder it: Edit | Approve | Spam | Trash.
|
773 |
+
$actions = array(
|
774 |
+
'edit' => '',
|
775 |
+
'approvecomment' => '', 'unapprove' => '',
|
776 |
+
'spam' => '', 'unspam' => '',
|
777 |
+
'trash' => '', 'untrash' => '', 'delete' => ''
|
778 |
+
);
|
779 |
+
|
780 |
+
if ( 'approved' == $the_comment_status ) {
|
781 |
+
$actions['unapprove'] = "<a href='$unapprove_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment&new=unapproved' class='vim-u vim-destructive' title='" . esc_attr__( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>';
|
782 |
+
} elseif ( 'unapproved' == $the_comment_status ) {
|
783 |
+
$actions['approvecomment'] = "<a href='$approve_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment&new=approved' class='vim-a vim-destructive' title='" . esc_attr__( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>';
|
784 |
+
}
|
785 |
+
|
786 |
+
if ( 'spam' != $the_comment_status ) {
|
787 |
+
$actions['spam'] = "<a href='$spam_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::spam=1' class='vim-s vim-destructive' title='" . esc_attr__( 'Mark this comment as spam' ) . "'>" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . '</a>';
|
788 |
+
} elseif ( 'spam' == $the_comment_status ) {
|
789 |
+
$actions['unspam'] = "<a href='$unspam_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:66cc66:unspam=1' class='vim-z vim-destructive'>" . _x( 'Not Spam', 'comment' ) . '</a>';
|
790 |
+
}
|
791 |
+
|
792 |
+
if ( 'trash' == $the_comment_status ) {
|
793 |
+
$actions['untrash'] = "<a href='$untrash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:66cc66:untrash=1' class='vim-z vim-destructive'>" . __( 'Restore' ) . '</a>';
|
794 |
+
}
|
795 |
+
|
796 |
+
if ( 'spam' == $the_comment_status || 'trash' == $the_comment_status || !EMPTY_TRASH_DAYS ) {
|
797 |
+
$actions['delete'] = "<a href='$delete_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::delete=1' class='delete vim-d vim-destructive wplnst-remove-comment'>" . __( 'Delete Permanently' ) . '</a>';
|
798 |
+
} else {
|
799 |
+
$actions['trash'] = "<a href='$trash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::trash=1' class='delete vim-d vim-destructive' title='" . esc_attr__( 'Move this comment to the trash' ) . "'>" . _x( 'Trash', 'verb' ) . '</a>';
|
800 |
+
}
|
801 |
+
|
802 |
+
if ('spam' != $the_comment_status && 'trash' != $the_comment_status)
|
803 |
+
$actions['edit'] = "<a href='comment.php?action=editcomment&c={$comment->comment_ID}' title='" . esc_attr__( 'Edit comment' ) . "'>". __( 'Edit' ) . '</a>';
|
804 |
+
}
|
805 |
+
|
806 |
+
// Check approved comment to see it
|
807 |
+
if ('approved' == wp_get_comment_status($comment->comment_ID))
|
808 |
+
$actions['view'] = '<a href="'.esc_url(get_comment_link($comment->comment_ID)).'" target="_blank">'.__('View').'</a>';
|
809 |
+
|
810 |
+
/** This filter is documented in wp-admin/includes/dashboard.php */
|
811 |
+
$actions = apply_filters('comment_row_actions', array_filter($actions), $comment);
|
812 |
+
|
813 |
+
// Done
|
814 |
+
return $actions;
|
815 |
+
}
|
816 |
+
|
817 |
+
|
818 |
+
|
819 |
+
/**
|
820 |
+
* Column content row actions for blogroll
|
821 |
+
*/
|
822 |
+
private function column_actions_content_blogroll($item) {
|
823 |
+
|
824 |
+
// Check object
|
825 |
+
if (!isset($item['bookmark']))
|
826 |
+
return array();
|
827 |
+
|
828 |
+
// Initialize
|
829 |
+
$actions = array();
|
830 |
+
$bookmark = $item['bookmark'];
|
831 |
+
|
832 |
+
// Check editable comment
|
833 |
+
if ($item['can_edit']) {
|
834 |
+
|
835 |
+
// Cast identifier
|
836 |
+
$bookmark_id = (int) $bookmark->link_id;
|
837 |
+
|
838 |
+
// Edit or remove link
|
839 |
+
$actions['edit'] = '<a href="'.admin_url('link.php?action=edit&link_id='.$bookmark_id).'" target="_blank">'.__('Edit').'</a>';
|
840 |
+
$actions['trash'] = '<a class="wplnst-remove-bookmark" href="'.wp_nonce_url('link.php?action=delete&link_id='.$bookmark_id, 'delete-bookmark_'.$bookmark_id).'" target="_blank">'.__('Delete').'</a>';
|
841 |
+
}
|
842 |
+
|
843 |
+
// Visit action
|
844 |
+
$actions['visit'] = '<a href="'.esc_url($bookmark->link_url).'" target="_blank">'.__('Visit', 'wplnst').'</a>';
|
845 |
+
|
846 |
+
// Done
|
847 |
+
return $actions;
|
848 |
+
}
|
849 |
+
|
850 |
+
|
851 |
+
|
852 |
+
/**
|
853 |
+
* Generate row actions div
|
854 |
+
*
|
855 |
+
* @since 3.1.0
|
856 |
+
* @access protected
|
857 |
+
*
|
858 |
+
* @param array $actions The list of actions
|
859 |
+
* @param bool $always_visible Whether the actions should be always visible
|
860 |
+
* @return string
|
861 |
+
*/
|
862 |
+
protected function row_actions( $actions, $loc_id = 0 ) {
|
863 |
+
|
864 |
+
$action_count = count( $actions );
|
865 |
+
$i = 0;
|
866 |
+
|
867 |
+
if ( !$action_count )
|
868 |
+
return '';
|
869 |
+
|
870 |
+
$out = '<div class="row-actions wplnst-row-actions wplnst-row-actions-'.$loc_id.'">';
|
871 |
+
foreach ( $actions as $action => $link ) {
|
872 |
+
++$i;
|
873 |
+
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
874 |
+
$out .= "<span class='$action'>$link$sep</span>";
|
875 |
+
}
|
876 |
+
$out .= '</div>';
|
877 |
+
|
878 |
+
return $out;
|
879 |
+
}
|
880 |
+
|
881 |
+
|
882 |
+
|
883 |
+
// Display and pagination
|
884 |
+
// ---------------------------------------------------------------------------------------------------
|
885 |
+
|
886 |
+
|
887 |
+
|
888 |
+
/**
|
889 |
+
* Set pagination arguments
|
890 |
+
*/
|
891 |
+
private function setup_pagination() {
|
892 |
+
$this->set_pagination_args(array(
|
893 |
+
'per_page' => $this->results->isolated? 0 : $this->results->per_page,
|
894 |
+
'total_items' => $this->results->total_rows,
|
895 |
+
'total_pages' => $this->results->isolated? 0 : $this->results->total_pages,
|
896 |
+
));
|
897 |
+
}
|
898 |
+
|
899 |
+
|
900 |
+
|
901 |
+
/**
|
902 |
+
* Display the table
|
903 |
+
*
|
904 |
+
* @since 3.1.0
|
905 |
+
* @access public
|
906 |
+
*/
|
907 |
+
public function display() {
|
908 |
+
|
909 |
+
// Wrapper form
|
910 |
+
echo '<form method="get" action="'.esc_url(remove_query_arg('paged', set_url_scheme('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']))).'" id="wplnst-results" data-nonce="'.esc_attr(wp_create_nonce('wplnst-results-'.$this->results->scan->hash)).'" data-nonce-advanced-display="'.esc_attr(wp_create_nonce('wplnst-results-advanced-display')).'" data-confirm-delete-entry="'.esc_attr__('Please, confirm you want to remove this entry pressing the Ok button', 'wplnst').'" data-confirm-delete-comment="'.esc_attr__('Please, confirm you want to remove this comment pressing the Ok button', 'wplnst').'" data-confirm-delete-bookmark="'.esc_attr__('Please, confirm you want to remove this bookmark pressing the Ok button', 'wplnst').'" data-label-action-url-redir="'.esc_attr__('Apply Redirection', 'wplnst').'" data-label-server-comm-error="'.esc_attr(WPLNST_Core_Text::get_text('server_comm_error')).'" data-label-unknown-error="'.esc_attr(WPLNST_Core_Text::get_text('unknown_error')).'" data-label-select-any="'.esc_attr__('Please, select any result to proceed', 'wplnst').'" data-label-error-code="'.esc_attr__('error code', 'wplnst').'">';
|
911 |
+
|
912 |
+
// Hidden fields
|
913 |
+
echo '<input type="hidden" name="page" value="'.esc_attr($_GET['page']).'" />';
|
914 |
+
echo '<input type="hidden" name="scan_id" value="'.esc_attr($this->results->scan->id).'" />';
|
915 |
+
echo '<input type="hidden" name="context" value="results" />';
|
916 |
+
if (isset($this->results->status_level)) echo '<input type="hidden" name="status" value="'.esc_attr($this->results->status_level).'" />';
|
917 |
+
|
918 |
+
// Raise event at this point
|
919 |
+
do_action('wplnst_scans_results_view_display');
|
920 |
+
|
921 |
+
// Check isolated classes
|
922 |
+
$extra_classes = array();
|
923 |
+
if ($this->results->isolated)
|
924 |
+
$extra_classes[] = 'wplnst-isolated-table';
|
925 |
+
|
926 |
+
// Show levels menu
|
927 |
+
$this->menu();
|
928 |
+
|
929 |
+
// Check isolated display
|
930 |
+
if (!$this->results->isolated)
|
931 |
+
$this->display_tablenav('top');
|
932 |
+
|
933 |
+
?><table class="wp-list-table <?php echo implode(' ', array_merge($this->get_table_classes(), $extra_classes)); ?>">
|
934 |
+
<thead>
|
935 |
+
<tr>
|
936 |
+
<?php $this->print_column_headers(); ?>
|
937 |
+
</tr>
|
938 |
+
</thead>
|
939 |
+
<tbody id="the-list">
|
940 |
+
<?php $this->display_rows_or_placeholder(); ?>
|
941 |
+
</tbody>
|
942 |
+
<?php if (!$this->results->isolated) : ?>
|
943 |
+
<tfoot>
|
944 |
+
<tr>
|
945 |
+
<?php $this->print_column_headers( false ); ?>
|
946 |
+
</tr>
|
947 |
+
</tfoot>
|
948 |
+
<?php endif; ?>
|
949 |
+
</table><?php
|
950 |
+
|
951 |
+
// Check isolated display
|
952 |
+
if (!$this->results->isolated)
|
953 |
+
$this->display_tablenav('bottom');
|
954 |
+
|
955 |
+
// Close form
|
956 |
+
echo '</form>';
|
957 |
+
}
|
958 |
+
|
959 |
+
|
960 |
+
|
961 |
+
/**
|
962 |
+
* Generate the table navigation above or below the table
|
963 |
+
*/
|
964 |
+
protected function display_tablenav($which) {
|
965 |
+
?><div class="tablenav <?php echo esc_attr($which); ?>">
|
966 |
+
<?php if ('top' == $which) $this->filters(); ?>
|
967 |
+
<?php $this->pagination($which); ?>
|
968 |
+
<br class="clear" />
|
969 |
+
</div><?php
|
970 |
+
}
|
971 |
+
|
972 |
+
|
973 |
+
|
974 |
+
// Menu and filters
|
975 |
+
// ---------------------------------------------------------------------------------------------------
|
976 |
+
|
977 |
+
|
978 |
+
|
979 |
+
/**
|
980 |
+
* Display a menu based on status levels
|
981 |
+
*/
|
982 |
+
private function menu() {
|
983 |
+
|
984 |
+
// Initialize
|
985 |
+
$status_levels = WPLNST_Core_Types::get_status_levels();
|
986 |
+
|
987 |
+
// Enum summary elements
|
988 |
+
$levels = array();
|
989 |
+
foreach ($this->results->scan->summary as $key => $value) {
|
990 |
+
|
991 |
+
// Status level record
|
992 |
+
if (0 === strpos($key, 'status_level_')) {
|
993 |
+
$key = explode('status_level_', $key);
|
994 |
+
if (2 == count($key)) {
|
995 |
+
$key = $key[1];
|
996 |
+
if ('0' == $key) {
|
997 |
+
$levels[$key] = (isset($levels[$key])? $levels[$key] : 0) + (int) $value;
|
998 |
+
} elseif (isset($status_levels[$key])) {
|
999 |
+
$levels[$key] = $value;
|
1000 |
+
}
|
1001 |
+
}
|
1002 |
+
}
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
// Status levels menu
|
1006 |
+
$menu_levels = array();
|
1007 |
+
foreach ($status_levels as $key => $label) {
|
1008 |
+
if (in_array($key, array_keys($levels)))
|
1009 |
+
$menu_levels[$key] = $levels[$key];
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
// Check stored total
|
1013 |
+
$total = empty($this->results->scan->summary['status_total'])? 0 : (int) $this->results->scan->summary['status_total'];
|
1014 |
+
|
1015 |
+
// Menu levels
|
1016 |
+
$menu_links = array();
|
1017 |
+
|
1018 |
+
// All results
|
1019 |
+
$menu_links[] = '<a href="'.$this->base_url.'"'.($total > 0 && $this->results->is_all_results? ' class="current"' : '').'>'.__('All results', 'wplnst').' </a><span class="count">('.($this->results->is_all_results? number_format_i18n($this->results->total_rows) : number_format_i18n($total)).')</span>';
|
1020 |
+
|
1021 |
+
// Request error
|
1022 |
+
if (!empty($levels['0']))
|
1023 |
+
$menu_links[] = '<a href="'.$this->base_url.'&status=0"'.(('0' === $this->results->status_level && !$this->results->is_search)? ' class="current"' : '').'>'.__('Request error', 'wplnst').' </a><span class="count">('.number_format_i18n($levels['0']).')</span>';
|
1024 |
+
|
1025 |
+
// Level results
|
1026 |
+
foreach ($menu_levels as $key => $total)
|
1027 |
+
$menu_links[] = '<a href="'.$this->base_url.'&status='.$key.'"'.(($key == $this->results->status_level && !$this->results->is_search)? ' class="current"' : '').'>'.esc_html($key.'00s '.$status_levels[$key]).' </a><span class="count">('.number_format_i18n($total).')</span>';
|
1028 |
+
|
1029 |
+
// Show menu
|
1030 |
+
echo '<div id="wplnst-levels-menu" class="wplnst-clearfix'.($this->results->isolated? ' wplnst-levels-menu-isolated' : '').'"><ul class="subsubsub"><li>'.implode(' | </li><li>', $menu_links).'</li></ul>'.(('end' != $this->results->scan->status)? '<div class="alignright wplnst-aproximate-total">'.__('(counters in progress)', 'wplnst').'</div>' : '').'</div>';
|
1031 |
+
}
|
1032 |
+
|
1033 |
+
|
1034 |
+
|
1035 |
+
/**
|
1036 |
+
* Display a set of filters
|
1037 |
+
*/
|
1038 |
+
protected function filters() {
|
1039 |
+
|
1040 |
+
// Check filters
|
1041 |
+
$fields = $this->filters_fields();
|
1042 |
+
if (empty($fields))
|
1043 |
+
return;
|
1044 |
+
|
1045 |
+
// Show menu, actions, etc.
|
1046 |
+
echo '<div id="wplnst-results-filters" class="alignleft actions'.$this->filters_classes().'">';
|
1047 |
+
|
1048 |
+
// Display fields
|
1049 |
+
foreach ($fields as $key => $field)
|
1050 |
+
echo '<select id="wplnst-filter-'.$key.'"><option value="">'.esc_html($field['title']).'</option>'.$field['options'].'</select>';
|
1051 |
+
|
1052 |
+
// Button and end of div
|
1053 |
+
echo ' <input id="wplnst-filter-button" data-fields="'.implode(',', array_keys($fields)).'" data-href="'.esc_attr($this->base_url).'" class="button" type="button" value="'.__('Filter', 'wplnst').'" /></div>';
|
1054 |
+
}
|
1055 |
+
|
1056 |
+
|
1057 |
+
|
1058 |
+
/**
|
1059 |
+
* Additional classes
|
1060 |
+
*/
|
1061 |
+
protected function filters_classes() {
|
1062 |
+
return '';
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
|
1066 |
+
|
1067 |
+
/**
|
1068 |
+
* Retrieve fields for basic filters
|
1069 |
+
*/
|
1070 |
+
protected function filters_fields() {
|
1071 |
+
|
1072 |
+
// Basic fields
|
1073 |
+
$fields = array();
|
1074 |
+
|
1075 |
+
|
1076 |
+
/* Status codes filter */
|
1077 |
+
|
1078 |
+
// Initialize
|
1079 |
+
$objects_types = WPLNST_Core_Types::get_objects_types();
|
1080 |
+
$status_levels = WPLNST_Core_Types::get_status_levels();
|
1081 |
+
$status_codes_raw = WPLNST_Core_Types::get_status_codes_raw();
|
1082 |
+
|
1083 |
+
// Enum summary elements
|
1084 |
+
$levels = $codes = $objects = array();
|
1085 |
+
foreach ($this->results->scan->summary as $key => $value) {
|
1086 |
+
|
1087 |
+
// Status codes
|
1088 |
+
if (0 === strpos($key, 'status_code_')) {
|
1089 |
+
$key = explode('status_code_', $key);
|
1090 |
+
if (2 == count($key)) {
|
1091 |
+
$key = $key[1];
|
1092 |
+
if ('0' == $key) {
|
1093 |
+
$levels['0'] = true;
|
1094 |
+
} elseif (3 == strlen($key) && isset($status_codes_raw[$key])) {
|
1095 |
+
$level = substr($key, 0, 1);
|
1096 |
+
if (isset($status_levels[$level]))
|
1097 |
+
$levels[$level] = isset($levels[$level])? $levels[$level] + 1 : 1;
|
1098 |
+
$codes[$key] = $value;
|
1099 |
+
}
|
1100 |
+
}
|
1101 |
+
|
1102 |
+
// Objects match
|
1103 |
+
} elseif (0 === strpos($key, 'objects_match_')) {
|
1104 |
+
$key = explode('objects_match_', $key);
|
1105 |
+
if (2 == count($key) && in_array($key[1], array_keys($objects_types)))
|
1106 |
+
$objects[$key[1]] = $value;
|
1107 |
+
}
|
1108 |
+
}
|
1109 |
+
|
1110 |
+
|
1111 |
+
/* Status codes options */
|
1112 |
+
|
1113 |
+
// Collect options
|
1114 |
+
$options_codes = empty($levels['0'])? '' : '<option '.((isset($this->results->status_level) && '0' === $this->results->status_level)? 'selected' : '').' value="0">'.__('Request error', 'wplnst').'</option>';
|
1115 |
+
$options_levels = array();
|
1116 |
+
foreach ($status_codes_raw as $key => $label) {
|
1117 |
+
if (isset($codes[$key])) {
|
1118 |
+
$level = substr($key, 0, 1);
|
1119 |
+
if (isset($levels[$level]) && $levels[$level] > 1 && !in_array($level, $options_levels)) {
|
1120 |
+
$options_levels[] = $level;
|
1121 |
+
$options_codes .= '<option '.((!empty($this->results->status_level) && $this->results->status_level == $level)? 'selected' : '').' value="'.$level.'">'.$level.'xx'.' '.$status_levels[$level].'</option>';
|
1122 |
+
}
|
1123 |
+
$options_codes .= '<option '.((!empty($this->results->status_code) && $this->results->status_code == $key)? 'selected' : '').' value="'.$key.'">'.$key.' '.$label.'</option>';
|
1124 |
+
}
|
1125 |
+
}
|
1126 |
+
|
1127 |
+
// Add filter
|
1128 |
+
$fields['status'] = array(
|
1129 |
+
'type' => 'select',
|
1130 |
+
'title' => __('All status codes', 'wplnst'),
|
1131 |
+
'options' => $options_codes,
|
1132 |
+
);
|
1133 |
+
|
1134 |
+
|
1135 |
+
/* Objects options */
|
1136 |
+
|
1137 |
+
// Collect custom post types
|
1138 |
+
$options_post_types = '';
|
1139 |
+
if (in_array('posts', array_keys($objects))) {
|
1140 |
+
$post_types = WPLNST_Core_Types::get_post_types();
|
1141 |
+
foreach ($post_types as $type => $name) {
|
1142 |
+
if (in_array($type, $this->results->scan->post_types))
|
1143 |
+
$options_post_types .= '<option '.((!empty($this->results->object_post_type) && $this->results->object_post_type == $type)? 'selected' : '').' value="posts_'.$type.'">—'.esc_html($name).'</option>';
|
1144 |
+
}
|
1145 |
+
}
|
1146 |
+
|
1147 |
+
// Collect options
|
1148 |
+
$objects_codes = '';
|
1149 |
+
foreach ($objects_types as $key => $value) {
|
1150 |
+
if (in_array($key, array_keys($objects))) {
|
1151 |
+
$objects_codes .= '<option '.((!empty($this->results->object_type) && $this->results->object_type == $key)? 'selected' : '').' value="'.$key.'">'.$value.'</option>';
|
1152 |
+
if ('posts' == $key)
|
1153 |
+
$objects_codes .= $options_post_types;
|
1154 |
+
}
|
1155 |
+
}
|
1156 |
+
|
1157 |
+
// Check filter
|
1158 |
+
$fields['otype'] = array(
|
1159 |
+
'type' => 'select',
|
1160 |
+
'title' => __('All content', 'wplnst'),
|
1161 |
+
'options' => $objects_codes,
|
1162 |
+
);
|
1163 |
+
|
1164 |
+
|
1165 |
+
/* Options for link types */
|
1166 |
+
|
1167 |
+
$options_ltypes = '';
|
1168 |
+
$link_types = WPLNST_Core_Types::get_link_types();
|
1169 |
+
foreach ($link_types as $link_type => $link_type_name)
|
1170 |
+
$options_ltypes .= '<option '.((!empty($this->results->link_type) && $this->results->link_type == $link_type)? 'selected' : '').' value="'.esc_attr($link_type).'">'.esc_html($link_type_name).'</option>';
|
1171 |
+
|
1172 |
+
// Check filter
|
1173 |
+
$fields['ltype'] = array(
|
1174 |
+
'type' => 'select',
|
1175 |
+
'title' => __('All link types', 'wplnst'),
|
1176 |
+
'options' => $options_ltypes,
|
1177 |
+
);
|
1178 |
+
|
1179 |
+
|
1180 |
+
// Done
|
1181 |
+
return $fields;
|
1182 |
+
}
|
1183 |
+
|
1184 |
+
|
1185 |
+
|
1186 |
+
}
|
views/scans.php
ADDED
@@ -0,0 +1,552 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Check WP constant
|
4 |
+
if (!defined('ABSPATH'))
|
5 |
+
die;
|
6 |
+
|
7 |
+
// Check dependencies
|
8 |
+
if(!class_exists('WP_List_Table'))
|
9 |
+
require_once(ABSPATH.'wp-admin/includes/class-wp-list-table.php');
|
10 |
+
|
11 |
+
/**
|
12 |
+
* WP Link Status Views Scans class
|
13 |
+
*
|
14 |
+
* @package WP Link Status
|
15 |
+
* @subpackage WP Link Status Views
|
16 |
+
*/
|
17 |
+
class WPLNST_Views_Scans extends WP_List_Table {
|
18 |
+
|
19 |
+
|
20 |
+
|
21 |
+
// Properties
|
22 |
+
// ---------------------------------------------------------------------------------------------------
|
23 |
+
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* External data
|
28 |
+
*/
|
29 |
+
private $results;
|
30 |
+
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Base URL for filters
|
34 |
+
*/
|
35 |
+
private $base_url;
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
// Initialization
|
40 |
+
// ---------------------------------------------------------------------------------------------------
|
41 |
+
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Constructor
|
46 |
+
*/
|
47 |
+
public function __construct($results) {
|
48 |
+
|
49 |
+
// Parent constructor
|
50 |
+
parent::__construct();
|
51 |
+
|
52 |
+
// Copy results
|
53 |
+
$this->results = $results;
|
54 |
+
|
55 |
+
// Base link for filters
|
56 |
+
$this->base_url = esc_url(WPLNST_Core_Plugin::get_url_scans());
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Prepare columns and data
|
63 |
+
*/
|
64 |
+
function prepare_items() {
|
65 |
+
|
66 |
+
// Columns
|
67 |
+
$this->setup_columns();
|
68 |
+
|
69 |
+
// Data items
|
70 |
+
$this->setup_items();
|
71 |
+
|
72 |
+
// Pagination
|
73 |
+
$this->setup_pagination();
|
74 |
+
}
|
75 |
+
|
76 |
+
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Setup columns
|
80 |
+
*/
|
81 |
+
private function setup_columns() {
|
82 |
+
|
83 |
+
// Initialize
|
84 |
+
$hidden = array();
|
85 |
+
$sortable = array();
|
86 |
+
|
87 |
+
// Column headers
|
88 |
+
$this->_column_headers = array($this->get_columns(), $hidden, $sortable);
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Columns array
|
95 |
+
*/
|
96 |
+
public function get_columns(){
|
97 |
+
|
98 |
+
// Checkbox column
|
99 |
+
$columns = array();
|
100 |
+
if (!$this->results->isolated)
|
101 |
+
$columns['cb'] = '<input type="checkbox" />';
|
102 |
+
|
103 |
+
// All columns
|
104 |
+
return array_merge($columns, array(
|
105 |
+
'wplnst-scans-name' => __('Scan info', 'wplnst'),
|
106 |
+
'wplnst-scans-configuration' => __('Configuration', 'wplnst'),
|
107 |
+
));
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Setup data items
|
114 |
+
*/
|
115 |
+
private function setup_items() {
|
116 |
+
|
117 |
+
// Initialize
|
118 |
+
$this->items = array();
|
119 |
+
|
120 |
+
// Warning image
|
121 |
+
$warning_img = '<img src="'.plugins_url('assets/images/scan-warning.png', WPLNST_FILE).'" width="16" height="16" border="0" style="margin-right: 5px;" title="'.__('Some critical values of this scan are not completed', 'wplnst').'">';
|
122 |
+
|
123 |
+
// Populate data
|
124 |
+
foreach ($this->results->rows as $scan) {
|
125 |
+
|
126 |
+
// Initialize
|
127 |
+
$timeinfo = false;
|
128 |
+
$linksinfo = '';
|
129 |
+
|
130 |
+
// Normalize identifiers and other data
|
131 |
+
$item = array('ID' => $scan->id, 'hash' => $scan->hash, 'status' => $scan->status, 'ready' => $scan->ready);
|
132 |
+
|
133 |
+
// Check processed posts
|
134 |
+
$message = ('play' != $scan->status)? '' : __('Waiting...', 'wplnst');
|
135 |
+
|
136 |
+
// Initialize
|
137 |
+
$processed = array();
|
138 |
+
$running_back = false;
|
139 |
+
$class_completed = ('end' == $scan->status)? 'wplnst-scan-object-completed-end' : 'wplnst-scan-object-completed';
|
140 |
+
|
141 |
+
if (isset($scan->trace['total_posts'])) {
|
142 |
+
$running_back = empty($scan->trace['populated_posts']);
|
143 |
+
$posts_index = empty($scan->trace['posts_index'])? 0 : number_format_i18n($scan->trace['posts_index']);
|
144 |
+
$processed[] = empty($scan->trace['populated_posts'])? '<span class="wplnst-scan-object-info wplnst-scan-object-running">'.$posts_index.'/'.number_format_i18n($scan->trace['total_posts']).' '.__('entries', 'wplnst').'</span>' : '<span class="wplnst-scan-object-info '.$class_completed.'">'.number_format_i18n($scan->trace['total_posts']).' '.__('entries', 'wplnst').'</span>';
|
145 |
+
}
|
146 |
+
|
147 |
+
if (isset($scan->trace['total_comments'])) {
|
148 |
+
$running = !$running_back && empty($scan->trace['populated_comments']);
|
149 |
+
$running_back = $running? true : $running_back;
|
150 |
+
$class_running = $running? 'wplnst-scan-object-running' : 'wplnst-scan-object-wait';
|
151 |
+
$comments_index = empty($scan->trace['comments_index'])? 0 : number_format_i18n($scan->trace['comments_index']);
|
152 |
+
$processed[] = empty($scan->trace['populated_comments'])? '<span class="wplnst-scan-object-info '.$class_running.'">'.$comments_index.'/'.number_format_i18n($scan->trace['total_comments']).' '.__('comments', 'wplnst').'</span>' : '<span class="wplnst-scan-object-info '.$class_completed.'">'.number_format_i18n($scan->trace['total_comments']).' '.__('comments', 'wplnst').'</span>';
|
153 |
+
}
|
154 |
+
|
155 |
+
if (isset($scan->trace['total_blogroll'])) {
|
156 |
+
$running = !$running_back && empty($scan->trace['populated_blogroll']);
|
157 |
+
$class_running = $running? 'wplnst-scan-object-running' : 'wplnst-scan-object-wait';
|
158 |
+
$blogroll_index = empty($scan->trace['blogroll_index'])? 0 : number_format_i18n($scan->trace['blogroll_index']);
|
159 |
+
$processed[] = empty($scan->trace['populated_blogroll'])? '<span class="wplnst-scan-object-info '.$class_running.'">'.$blogroll_index.'/'.number_format_i18n($scan->trace['total_blogroll']).' '.__('blogroll', 'wplnst').'</span>' : '<span class="wplnst-scan-object-info '.$class_completed.'">'.number_format_i18n($scan->trace['total_blogroll']).' '.__('blogroll', 'wplnst').'</span>';
|
160 |
+
}
|
161 |
+
|
162 |
+
// Check info
|
163 |
+
if (!empty($processed)) {
|
164 |
+
|
165 |
+
// Processed object types
|
166 |
+
$message = implode(' ', $processed);
|
167 |
+
|
168 |
+
// Check status
|
169 |
+
if ('wait' != $scan->status) {
|
170 |
+
|
171 |
+
|
172 |
+
/* Time info */
|
173 |
+
|
174 |
+
// Start and local extra time
|
175 |
+
$time_start = strtotime($scan->row->started_at.' UTC');
|
176 |
+
$offset_time = get_option('gmt_offset') * HOUR_IN_SECONDS;
|
177 |
+
|
178 |
+
// Current dates
|
179 |
+
$today_date = gmdate('d/m/Y', time() + $offset_time);
|
180 |
+
$yesterday_date = gmdate('d/m/Y', time() + $offset_time - 86400);
|
181 |
+
|
182 |
+
// Local date and hour
|
183 |
+
$start_date = gmdate('d/m/Y', $time_start + $offset_time);
|
184 |
+
$start_hour = gmdate('H:i', $time_start + $offset_time);
|
185 |
+
|
186 |
+
// Check today
|
187 |
+
if ($start_date == $today_date) {
|
188 |
+
|
189 |
+
// Today
|
190 |
+
$started_at = sprintf(__('Today from %s', 'wplnst'), $start_hour);
|
191 |
+
|
192 |
+
// Check yesterday
|
193 |
+
} elseif ($start_date == $yesterday_date) {
|
194 |
+
|
195 |
+
// Yesterday
|
196 |
+
$started_at = sprintf(__('Yesterday at %s', 'wplnst'), $start_hour);
|
197 |
+
|
198 |
+
// Other
|
199 |
+
} else {
|
200 |
+
|
201 |
+
// Date and hour
|
202 |
+
$started_at = sprintf(__('%s at %s', 'wplnst'), $start_date, $start_hour);
|
203 |
+
}
|
204 |
+
|
205 |
+
// Start date
|
206 |
+
$timeinfo = $started_at;
|
207 |
+
|
208 |
+
// Retrieve time stopped
|
209 |
+
$time_stopped = isset($scan->summary['time_stopped'])? (int) $scan->summary['time_stopped'] : 0;
|
210 |
+
|
211 |
+
// Ended scan
|
212 |
+
if ('end' == $scan->status) {
|
213 |
+
|
214 |
+
// Finished date
|
215 |
+
$time_end = $time_end_amount = strtotime($scan->row->finished_at.' UTC');
|
216 |
+
|
217 |
+
// Local date and hour
|
218 |
+
$end_date = gmdate('d/m/Y', $time_end + $offset_time);
|
219 |
+
$end_hour = gmdate('H:i', $time_end + $offset_time);
|
220 |
+
|
221 |
+
// Check today
|
222 |
+
if ($end_date == $today_date) {
|
223 |
+
|
224 |
+
// All today
|
225 |
+
if ($start_date == $today_date) {
|
226 |
+
|
227 |
+
// Started and finished today
|
228 |
+
$timeinfo .= ' '.sprintf(__('to %s', 'wplnst'), $end_hour);
|
229 |
+
|
230 |
+
// Date to today
|
231 |
+
} else {
|
232 |
+
|
233 |
+
// Started another date and finished today
|
234 |
+
$timeinfo .= ' '.sprintf(__('to today at %s', 'wplnst'), $end_hour);
|
235 |
+
}
|
236 |
+
|
237 |
+
// Check yesterday
|
238 |
+
} elseif ($end_date == $yesterday_date) {
|
239 |
+
|
240 |
+
// All yesterday
|
241 |
+
if ($start_date == $yesterday_date) {
|
242 |
+
|
243 |
+
// Started and finished today
|
244 |
+
$timeinfo .= ' '.sprintf(__('to %s', 'wplnst'), $end_hour);
|
245 |
+
|
246 |
+
// Date to yesterday
|
247 |
+
} else {
|
248 |
+
|
249 |
+
// Started another date and finished today
|
250 |
+
$timeinfo .= ' '.sprintf(__('to yesterday at %s', 'wplnst'), $end_hour);
|
251 |
+
}
|
252 |
+
|
253 |
+
// Check same day
|
254 |
+
} elseif ($end_date == $start_date) {
|
255 |
+
|
256 |
+
// Same day
|
257 |
+
$timeinfo .= ' '.sprintf(__('until %s', 'wplnst'), $end_hour);
|
258 |
+
|
259 |
+
// Before
|
260 |
+
} else {
|
261 |
+
|
262 |
+
// Different days
|
263 |
+
$timeinfo .= ' '.sprintf(__('until %s at %s', 'wplnst'), $end_date, $end_hour);
|
264 |
+
}
|
265 |
+
|
266 |
+
// Time stopped correction
|
267 |
+
if (!empty($time_stopped))
|
268 |
+
$time_end_amount -= $time_stopped;
|
269 |
+
|
270 |
+
// Total time
|
271 |
+
$timeinfo .= ' — '.human_time_diff($time_start, $time_end_amount);
|
272 |
+
|
273 |
+
// Running
|
274 |
+
} else {
|
275 |
+
|
276 |
+
// Until now or stopped
|
277 |
+
$time_end = ('stop' == $scan->status)? strtotime($scan->row->stopped_at.' UTC') : time();
|
278 |
+
|
279 |
+
// Time stopped correction
|
280 |
+
if (!empty($time_stopped))
|
281 |
+
$time_end -= $time_stopped;
|
282 |
+
|
283 |
+
// Elapsed time
|
284 |
+
$timeinfo .= ' — '.sprintf(__('Running time %s', 'wplnst'), human_time_diff($time_start, $time_end));
|
285 |
+
}
|
286 |
+
|
287 |
+
|
288 |
+
/* Links info */
|
289 |
+
|
290 |
+
// Normalize
|
291 |
+
$phases = array();
|
292 |
+
foreach ($scan->summary as $key => $value) {
|
293 |
+
if (0 === strpos($key, 'urls_phase_')) {
|
294 |
+
$phase = explode('urls_phase_', $key);
|
295 |
+
$phases[$phase[1]] = $value;
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
// Check values
|
300 |
+
if (!empty($phases)) {
|
301 |
+
|
302 |
+
// Collect data
|
303 |
+
$items = array();
|
304 |
+
|
305 |
+
// All results
|
306 |
+
$items[] = (isset($scan->summary['status_total']) && $scan->summary['status_total'] > 0)? sprintf(__('<strong>%s</strong> results', 'wplnst'), number_format_i18n((int) $scan->summary['status_total'])) : __('No results', 'wplnst');
|
307 |
+
|
308 |
+
// Total processed
|
309 |
+
if (!empty($phases['processed'])) {
|
310 |
+
|
311 |
+
// Add uniques
|
312 |
+
$items[] = sprintf(__('<strong>%s</strong> unique URLs', 'wplnst'), number_format_i18n((int) $phases['processed']));
|
313 |
+
}
|
314 |
+
|
315 |
+
// Enqueued URLs
|
316 |
+
if ('end' != $scan->status)
|
317 |
+
$items[] = sprintf(__('%s enqueued', 'wplnst'), (isset($phases['wait'])? number_format_i18n((int) $phases['wait']) : '0'));
|
318 |
+
|
319 |
+
// Waiting
|
320 |
+
if ('play' == $scan->status)
|
321 |
+
$items[] = sprintf(__('%s processing', 'wplnst'), (empty($phases['play'])? wplnst_get_nsetting('max_threads', $scan->threads->max) : (int) $phases['play']));
|
322 |
+
|
323 |
+
// End crawler
|
324 |
+
if ('end' == $scan->status)
|
325 |
+
$items[] = sprintf(__('<strong>%s</strong> Request error', 'wplnst'), (isset($scan->summary['status_level_0'])? (int) number_format_i18n($scan->summary['status_level_0']) : '0'));
|
326 |
+
|
327 |
+
// Join items
|
328 |
+
if (!empty($items))
|
329 |
+
$linksinfo = implode('<span class="wplnst-split-char">·</span>', $items);
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
// Only created
|
334 |
+
} elseif ('wait' == $scan->status || 'queued' == $scan->status || 'stop' == $scan->status) {
|
335 |
+
|
336 |
+
// Created date
|
337 |
+
$time_created = strtotime($scan->row->created_at.' UTC');
|
338 |
+
$offset_time = get_option('gmt_offset') * HOUR_IN_SECONDS;
|
339 |
+
|
340 |
+
// Current dates
|
341 |
+
$today_date = gmdate('d/m/Y', time() + $offset_time);
|
342 |
+
$yesterday_date = gmdate('d/m/Y', time() + $offset_time - 86400);
|
343 |
+
|
344 |
+
// Local date and hour
|
345 |
+
$created_date = gmdate('d/m/Y', $time_created + $offset_time);
|
346 |
+
$created_hour = gmdate('H:i', $time_created + $offset_time);
|
347 |
+
|
348 |
+
// Check today
|
349 |
+
if ($created_date == $today_date) {
|
350 |
+
|
351 |
+
// Created today
|
352 |
+
$timeinfo = sprintf(__('Created today at %s', 'wplnst'), $created_hour);
|
353 |
+
|
354 |
+
// Yesterday
|
355 |
+
} elseif ($created_date == $yesterday_date) {
|
356 |
+
|
357 |
+
// Created yesterday
|
358 |
+
$timeinfo = sprintf(__('Created yesterday at %s', 'wplnst'), $created_hour);
|
359 |
+
|
360 |
+
// Any date
|
361 |
+
} else {
|
362 |
+
|
363 |
+
// Created date and hour
|
364 |
+
$timeinfo = sprintf(__('Created %s at %s', 'wplnst'), $created_date, $created_hour);
|
365 |
+
}
|
366 |
+
}
|
367 |
+
|
368 |
+
|
369 |
+
|
370 |
+
// Item name, possible warning and link to edit
|
371 |
+
$statuses = WPLNST_Core_Types::get_scan_statuses();
|
372 |
+
$item['wplnst-scans-name'] = '<strong class="wplnst-scan-name'.($scan->ready? '' : ' wplnst-scan-name-warning').'">'.($scan->ready? '' : $warning_img);
|
373 |
+
if ('wait' != $scan->status)
|
374 |
+
$item['wplnst-scans-name'] .= '<span class="wplnst-scan-status wplnst-scan-status-'.esc_attr($scan->status).'">'.$statuses[$scan->status].'</span> ';
|
375 |
+
$item['wplnst-scans-name'] .= '<a class="row-title" href="'.esc_url(WPLNST_Core_Plugin::get_url_scans_results($scan->id)).'">'.(empty($scan->name)? __('(no name)', 'wplnst') : esc_html($scan->name)).'</a></strong>';
|
376 |
+
$item['wplnst-scans-name'] .= '<div class="wplnst-scan-status-line">'.$message.'</div>';
|
377 |
+
|
378 |
+
// Check ready message
|
379 |
+
if ('wait' == $scan->status && $scan->ready)
|
380 |
+
$item['wplnst-scans-name'] .= '<div class="wplnst-scan-ready-info">'.sprintf(__('Ready to <a href="%s">start the crawler</a>', 'wplnst'), esc_url(WPLNST_Core_Plugin::get_url_scans_crawler($scan->id, 'on', $scan->hash))).'</div>';
|
381 |
+
|
382 |
+
// Check datatime info
|
383 |
+
if (!empty($timeinfo))
|
384 |
+
$item['wplnst-scans-name'] .= '<div class="wplnst-scan-time-info">'.$timeinfo.'</div>';
|
385 |
+
|
386 |
+
// Check links info
|
387 |
+
if (!empty($linksinfo))
|
388 |
+
$item['wplnst-scans-name'] .= '<div class="wplnst-scan-links-info">'.$linksinfo.'</div>';
|
389 |
+
|
390 |
+
|
391 |
+
// Prepare configuration
|
392 |
+
$item['wplnst-scans-configuration'] = '<table>';
|
393 |
+
|
394 |
+
// Scan scope
|
395 |
+
$link_types = (empty($scan->link_types_names)? '' : implode(', ', array_map('esc_html', $scan->link_types_names)));
|
396 |
+
$item['wplnst-scans-configuration'] .= '<tr><td class="wplnst-scans-configuration-row"><strong>'.__('Scope', 'wplnst').'</strong></td><td>'.(empty($link_types)? '' : $link_types.', ').esc_html($scan->destination_type_name).', '.esc_html($scan->time_scope_name).', '.esc_html(__('Order by', 'wplnst')).' '.esc_html($scan->crawl_order_name).', '.($scan->redir_status? __('Check redirection status', 'wplnst') : __('Redirections not checked', 'wplnst')).($scan->malformed? ', '.__('Malformed', 'wplnst') : '').'</td></tr>';
|
397 |
+
|
398 |
+
// Post types and status
|
399 |
+
$item['wplnst-scans-configuration'] .= (empty($scan->post_types_names) && empty($scan->post_status_names))? '' : '<tr><td class="wplnst-scans-configuration-row"><strong>'.__('Post types', 'wplnst').'</strong></td><td>'.(empty($scan->post_types_names)? '' : implode(', ', array_map('esc_html', $scan->post_types_names))).(empty($scan->post_status_names)? '' : (empty($scan->post_types_names)? '' : ', ').__('Post status', 'wplnst').' '.implode(', ', array_map('esc_html', $scan->post_status_names))).'</td></tr>';
|
400 |
+
|
401 |
+
// Links status
|
402 |
+
$item['wplnst-scans-configuration'] .= empty($scan->links_status_names)? '' : '<tr><td class="wplnst-scans-configuration-row"><strong>'.__('Link status', 'wplnst').'</strong></td><td>'.implode(', ', array_map('esc_html', $scan->links_status_names)).'</td></tr>';
|
403 |
+
|
404 |
+
// End configuration
|
405 |
+
$item['wplnst-scans-configuration'] .= '</table>';
|
406 |
+
|
407 |
+
// Add row
|
408 |
+
$this->items[] = $item;
|
409 |
+
}
|
410 |
+
}
|
411 |
+
|
412 |
+
|
413 |
+
|
414 |
+
/**
|
415 |
+
* Default method to display a column
|
416 |
+
*
|
417 |
+
* @param array $item
|
418 |
+
* @param string $column_name
|
419 |
+
*
|
420 |
+
* @return mixed
|
421 |
+
*/
|
422 |
+
protected function column_default($item, $column_name) {
|
423 |
+
|
424 |
+
// Actions for name column
|
425 |
+
if ('wplnst-scans-name' == $column_name) {
|
426 |
+
|
427 |
+
// Initialize
|
428 |
+
$actions = array();
|
429 |
+
|
430 |
+
// Results link
|
431 |
+
$actions['results'] = '<a href="'.esc_url(WPLNST_Core_Plugin::get_url_scans_results($item['ID'])).'">'.__('Show results', 'wplnst').'</a>';
|
432 |
+
|
433 |
+
// Edit link
|
434 |
+
$actions['edit'] = '<span class="edit"><a href="'.esc_url(WPLNST_Core_Plugin::get_url_scans_edit($item['ID'])).'">'.__('Edit scan', 'wplnst').'</a></span>';
|
435 |
+
|
436 |
+
// Stop or start crawler
|
437 |
+
if ('end' != $item['status'] && ($item['ready'] || 'play' == $item['status']))
|
438 |
+
$actions['crawler'] = '<a href="'.esc_url(WPLNST_Core_Plugin::get_url_scans_crawler($item['ID'], ('play' == $item['status'] || 'queued' == $item['status'])? 'off' : 'on', $item['hash'])).'">'.(in_array($item['status'], array('wait', 'stop'))? __('Start crawler', 'wplnst') : (('queued' == $item['status'])? __('Unqueue crawling', 'wplnst') : __('Stop crawler', 'wplnst'))).'</a>';
|
439 |
+
|
440 |
+
// Remove scan
|
441 |
+
$actions['delete'] = '<span class="trash"><a href="'.esc_url(WPLNST_Core_Plugin::get_url_scans_delete($item['ID'], $item['hash'])).'" class="wplnst-scan-delete">'.esc_html(WPLNST_Admin::get_text('scan_delete')).'</a></span>';
|
442 |
+
|
443 |
+
// Done
|
444 |
+
return sprintf('%1$s %2$s', $item[$column_name], $this->row_actions($actions));
|
445 |
+
}
|
446 |
+
|
447 |
+
// Default column
|
448 |
+
return $item[$column_name];
|
449 |
+
}
|
450 |
+
|
451 |
+
|
452 |
+
|
453 |
+
/**
|
454 |
+
* Get an associative array ( option_name => option_title ) with the list
|
455 |
+
* of bulk actions available on this table.
|
456 |
+
*
|
457 |
+
* @return array
|
458 |
+
*/
|
459 |
+
protected function get_bulk_actions() {
|
460 |
+
return array(
|
461 |
+
'delete' => __('Delete', 'wplnst'),
|
462 |
+
);
|
463 |
+
}
|
464 |
+
|
465 |
+
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Handles the checkbox column output.
|
469 |
+
*/
|
470 |
+
protected function column_cb($item) {
|
471 |
+
return $this->results->isolated? null : sprintf('<input type="checkbox" class="wplnst-ck-scan-id" value="%s" />', $item['ID']);
|
472 |
+
}
|
473 |
+
|
474 |
+
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Set pagination arguments
|
478 |
+
*/
|
479 |
+
private function setup_pagination() {
|
480 |
+
$this->set_pagination_args(array(
|
481 |
+
'per_page' => $this->results->isolated? 0 : (isset($this->results->per_page)? $this->results->per_page : 1),
|
482 |
+
'total_items' => isset($this->results->total_rows)? $this->results->total_rows : count($this->results->rows),
|
483 |
+
'total_pages' => $this->results->isolated? 0 : (isset($this->results->total_pages)? $this->results->total_pages : 1),
|
484 |
+
));
|
485 |
+
}
|
486 |
+
|
487 |
+
|
488 |
+
|
489 |
+
/**
|
490 |
+
* Display the table
|
491 |
+
*
|
492 |
+
* @since 3.1.0
|
493 |
+
* @access public
|
494 |
+
*/
|
495 |
+
public function display() {
|
496 |
+
|
497 |
+
// Wrapper form
|
498 |
+
echo '<form method="get" action="'.esc_url($this->base_url).'" id="wplnst-scans" data-href-delete="'.WPLNST_Core_Plugin::get_url_scans_delete('%scan_id%', 'bulk-scans-delete').'" data-confirm-delete="'.esc_attr(WPLNST_Admin::get_text('scan_delete_confirm')).'" data-confirm-delete-bulk="'.esc_attr__('Do you want to remove these scans?', 'wplnst').'">';
|
499 |
+
|
500 |
+
// Check isolated classes
|
501 |
+
$extra_classes = array();
|
502 |
+
if ($this->results->isolated)
|
503 |
+
$extra_classes[] = 'wplnst-isolated-table';
|
504 |
+
|
505 |
+
// Check isolated display
|
506 |
+
if (!$this->results->isolated)
|
507 |
+
$this->display_tablenav('top');
|
508 |
+
|
509 |
+
?><table class="wp-list-table <?php echo implode(' ', array_merge($this->get_table_classes(), $extra_classes)); ?>">
|
510 |
+
<thead>
|
511 |
+
<tr>
|
512 |
+
<?php $this->print_column_headers(); ?>
|
513 |
+
</tr>
|
514 |
+
</thead>
|
515 |
+
<tbody id="the-list">
|
516 |
+
<?php $this->display_rows_or_placeholder(); ?>
|
517 |
+
</tbody>
|
518 |
+
<?php if (!$this->results->isolated) : ?>
|
519 |
+
<tfoot>
|
520 |
+
<tr>
|
521 |
+
<?php $this->print_column_headers( false ); ?>
|
522 |
+
</tr>
|
523 |
+
</tfoot>
|
524 |
+
<?php endif; ?>
|
525 |
+
</table><?php
|
526 |
+
|
527 |
+
// Check isolated display
|
528 |
+
if (!$this->results->isolated)
|
529 |
+
$this->display_tablenav('bottom');
|
530 |
+
|
531 |
+
// Close form
|
532 |
+
echo '</form>';
|
533 |
+
}
|
534 |
+
|
535 |
+
|
536 |
+
|
537 |
+
/**
|
538 |
+
* Generate the table navigation above or below the table
|
539 |
+
*/
|
540 |
+
protected function display_tablenav($which) {
|
541 |
+
?><div class="tablenav <?php echo esc_attr($which); ?>">
|
542 |
+
<div class="alignleft actions bulkactions wplnst-scans-bulkactions-<?php echo $which; ?>">
|
543 |
+
<?php $this->bulk_actions($which); ?>
|
544 |
+
</div>
|
545 |
+
<?php $this->pagination($which); ?>
|
546 |
+
<br class="clear" />
|
547 |
+
</div><?php
|
548 |
+
}
|
549 |
+
|
550 |
+
|
551 |
+
|
552 |
+
}
|
views/settings.php
ADDED
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Load views class
|
4 |
+
require_once(dirname(__FILE__).'/views.php');
|
5 |
+
|
6 |
+
/**
|
7 |
+
* WP Link Status Views Settings class
|
8 |
+
*
|
9 |
+
* @package WP Link Status
|
10 |
+
* @subpackage WP Link Status Views
|
11 |
+
*/
|
12 |
+
class WPLNST_Views_Settings extends WPLNST_Views {
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Show scan edit form
|
18 |
+
*/
|
19 |
+
public static function view($args) {
|
20 |
+
|
21 |
+
// Vars
|
22 |
+
extract($args);
|
23 |
+
|
24 |
+
?><form method="post" id="wplnst-form" action="<?php echo esc_url($action); ?>">
|
25 |
+
|
26 |
+
<input type="hidden" name="settings_nonce" value="<?php echo esc_attr($nonce); ?>" />
|
27 |
+
|
28 |
+
<h2 id="wplnst-tabs-nav" class="nav-tab-wrapper">
|
29 |
+
<a id="wplnst-crawling-tab" href="#top#wplnst-crawling" class="nav-tab"><?php _e('Crawling', 'wplnst'); ?></a>
|
30 |
+
<a id="wplnst-timing-tab" href="#top#wplnst-timing" class="nav-tab"><?php _e('Timing', 'wplnst'); ?></a>
|
31 |
+
<a id="wplnst-advanced-tab" href="#top#wplnst-advanced" class="nav-tab"><?php _e('Advanced', 'wplnst'); ?></a>
|
32 |
+
</h2>
|
33 |
+
|
34 |
+
<div id="wplnst-tabs">
|
35 |
+
|
36 |
+
<div id="wplnst-crawling" class="wplnst-tab wplnst-tab-default">
|
37 |
+
|
38 |
+
<table class="form-table">
|
39 |
+
<tr>
|
40 |
+
<th><label for="tx-max-threads"><?php _e('Number of crawler threads', 'wplnst'); ?></label></th>
|
41 |
+
<td class="wplnst-col-input"><input type="text" name="tx-max-threads" id="tx-max-threads" value="<?php echo esc_attr(wplnst_get_nsetting('max_threads')); ?>" maxlength="3" class="small-text" /></td>
|
42 |
+
<td class="wplnst-col-info"><?php _e('One thread means an HTTP request to your site only used for crawling purposes.', 'wplnst'); ?></td>
|
43 |
+
</tr>
|
44 |
+
<tr>
|
45 |
+
<th><label for="tx-max-scans"><?php _e('Max crawlers running', 'wplnst'); ?></label></th>
|
46 |
+
<td class="wplnst-col-input"><input type="text" name="tx-max-scans" id="tx-max-scans" value="<?php echo esc_attr(wplnst_get_nsetting('max_scans')); ?>" maxlength="3" class="small-text" /></td>
|
47 |
+
<td class="wplnst-col-info"><?php _e('Number of crawlers allowed to run simultaneously, each one with its own threads.', 'wplnst'); ?></td>
|
48 |
+
</tr>
|
49 |
+
<tr>
|
50 |
+
<th><label for="tx-max-pack"><?php _e('Max pack items', 'wplnst'); ?></label></th>
|
51 |
+
<td class="wplnst-col-input"><input type="text" name="tx-max-pack" id="tx-max-pack" value="<?php echo esc_attr(wplnst_get_nsetting('max_pack')); ?>" maxlength="3" class="small-text" /></td>
|
52 |
+
<td class="wplnst-col-info"><?php _e('Total objects (posts, comments or blogroll) processed in one single thread.', 'wplnst'); ?></td>
|
53 |
+
</tr>
|
54 |
+
<tr>
|
55 |
+
<th><label for="tx-max-scans"><?php _e('Max URL request attempts', 'wplnst'); ?></label></th>
|
56 |
+
<td class="wplnst-col-input"><input type="text" name="tx-max-requests" id="tx-max-requests" value="<?php echo esc_attr(wplnst_get_nsetting('max_requests')); ?>" maxlength="3" class="small-text" /></td>
|
57 |
+
<td class="wplnst-col-info"><?php _e('Number of HTTP requests attempts before set an URL as wrong.', 'wplnst'); ?></td>
|
58 |
+
</tr>
|
59 |
+
<tr>
|
60 |
+
<th><label for="tx-max-redirs"><?php _e('Max redirections allowed', 'wplnst'); ?></label></th>
|
61 |
+
<td class="wplnst-col-input"><input type="text" name="tx-max-redirs" id="tx-max-redirs" value="<?php echo esc_attr(wplnst_get_nsetting('max_redirs')); ?>" maxlength="3" class="small-text" /></td>
|
62 |
+
<td class="wplnst-col-info"><?php _e('Total redirections steps allowed to follow from original URL.', 'wplnst'); ?></td>
|
63 |
+
</tr>
|
64 |
+
<tr>
|
65 |
+
<th><label for="tx-max-download"><?php _e('Max download size', 'wplnst'); ?></label></th>
|
66 |
+
<td class="wplnst-col-input"><input type="text" name="tx-max-download" id="tx-max-download" value="<?php echo esc_attr(wplnst_get_nsetting('max_download')); ?>" maxlength="5" class="small-text" /></td>
|
67 |
+
<td class="wplnst-col-info"><?php _e('KB', 'wplnst'); ?> <?php echo sprintf(__('(minimum value of %s KB and max value of %s KB).', 'wplnst'), number_format_i18n(wplnst_get_nsetting('max_download', 'min')), number_format_i18n(wplnst_get_nsetting('max_download', 'max'))); ?></td>
|
68 |
+
</tr>
|
69 |
+
<tr>
|
70 |
+
<th><label for="tx-user-agent"><?php _e('Default User Agent', 'wplnst'); ?></label></th>
|
71 |
+
<td colspan="3" class="wplnst-col-input"><input type="text" name="tx-user-agent" id="tx-user-agent" value="<?php echo esc_attr(wplnst_get_tsetting('user_agent')); ?>" maxlength="255" class="regular-text" style="width: 75%;" /></td>
|
72 |
+
</tr>
|
73 |
+
</table>
|
74 |
+
|
75 |
+
</div>
|
76 |
+
|
77 |
+
<div id="wplnst-timing" class="wplnst-tab">
|
78 |
+
|
79 |
+
<table class="form-table">
|
80 |
+
<tr>
|
81 |
+
<th><label for="tx-connect-timeout"><?php _e('URL Connection timeout', 'wplnst'); ?></label></th>
|
82 |
+
<td class="wplnst-col-input"><input type="text" name="tx-connect-timeout" id="tx-connect-timeout" value="<?php echo esc_attr(wplnst_get_nsetting('connect_timeout')); ?>" maxlength="3" class="small-text" /></td>
|
83 |
+
<td class="wplnst-col-info"><?php _e('seconds', 'wplnst'); ?>. <?php _e('Max time allowed to establish a connection with the URL host.', 'wplnst'); ?></td>
|
84 |
+
</tr>
|
85 |
+
<tr>
|
86 |
+
<th><label for="tx-request-timeout"><?php _e('URL Request timeout', 'wplnst'); ?></label></th>
|
87 |
+
<td class="wplnst-col-input"><input type="text" name="tx-request-timeout" id="tx-request-timeout" value="<?php echo esc_attr(wplnst_get_nsetting('request_timeout')); ?>" maxlength="3" class="small-text" /></td>
|
88 |
+
<td class="wplnst-col-info"><?php _e('seconds', 'wplnst'); ?>. <?php _e('Max time allowed to retrieve headers and body from one URL.', 'wplnst'); ?></td>
|
89 |
+
</tr>
|
90 |
+
<tr>
|
91 |
+
<th><label for="tx-extra-timeout"><?php _e('URL Extra timeout check', 'wplnst'); ?></label></th>
|
92 |
+
<td class="wplnst-col-input"><input type="text" name="tx-extra-timeout" id="tx-extra-timeout" value="<?php echo esc_attr(wplnst_get_nsetting('extra_timeout')); ?>" maxlength="3" class="small-text" /></td>
|
93 |
+
<td class="wplnst-col-info"><?php _e('seconds', 'wplnst'); ?> <?php printf(__('(mininum value of %d seconds)', 'wplnst'), wplnst_get_nsetting('extra_timeout', 'min')); ?>. <?php _e('A little grace period to avoid timeouts conflicts.', 'wplnst'); ?></td>
|
94 |
+
</tr>
|
95 |
+
<tr>
|
96 |
+
<th><label for="tx-crawler-alive"><?php _e('Check crawler alive each', 'wplnst'); ?></label></th>
|
97 |
+
<td class="wplnst-col-input"><input type="text" name="tx-crawler-alive" id="tx-crawler-alive" value="<?php echo esc_attr(wplnst_get_nsetting('crawler_alive')); ?>" maxlength="3" class="small-text" /></td>
|
98 |
+
<td class="wplnst-col-info"><?php _e('seconds', 'wplnst'); ?> <?php printf(__('(mininum value of %d seconds)', 'wplnst'), wplnst_get_nsetting('crawler_alive', 'min')); ?>. <?php _e('Checks if a crawler is interrupted and if so restart it.', 'wplnst'); ?></td>
|
99 |
+
</tr>
|
100 |
+
<tr>
|
101 |
+
<th><label for="tx-total-objects"><?php _e('Total objects check each', 'wplnst'); ?></label></th>
|
102 |
+
<td class="wplnst-col-input"><input type="text" name="tx-total-objects" id="tx-total-objects" value="<?php echo esc_attr(wplnst_get_nsetting('total_objects')); ?>" maxlength="3" class="small-text" /></td>
|
103 |
+
<td class="wplnst-col-info"><?php _e('seconds', 'wplnst'); ?> <?php printf(__('(mininum value of %d seconds)', 'wplnst'), wplnst_get_nsetting('total_objects', 'min')); ?>. <?php _e('Total of objects (posts, comments or blogroll) to check links.', 'wplnst'); ?></td>
|
104 |
+
</tr>
|
105 |
+
<tr>
|
106 |
+
<th><label for="tx-summary-status"><?php _e('Summary of status each', 'wplnst'); ?></label></th>
|
107 |
+
<td class="wplnst-col-input"><input type="text" name="tx-summary-status" id="tx-summary-status" value="<?php echo esc_attr(wplnst_get_nsetting('summary_status')); ?>" maxlength="3" class="small-text" /></td>
|
108 |
+
<td class="wplnst-col-info"><?php _e('seconds', 'wplnst'); ?> <?php printf(__('(mininum value of %d seconds)', 'wplnst'), wplnst_get_nsetting('summary_status', 'min')); ?>. <?php _e('Calculate status code totals to display data in real time.', 'wplnst'); ?></td>
|
109 |
+
</tr>
|
110 |
+
<tr>
|
111 |
+
<th><label for="tx-summary-phases"><?php _e('Summary of URLs each', 'wplnst'); ?></label></th>
|
112 |
+
<td><input type="text" name="tx-summary-phases" id="tx-summary-phases" value="<?php echo esc_attr(wplnst_get_nsetting('summary_phases')); ?>" maxlength="3" class="small-text" /></td>
|
113 |
+
<td class="wplnst-col-info"><?php _e('seconds', 'wplnst'); ?> <?php printf(__('(mininum value of %d seconds)', 'wplnst'), wplnst_get_nsetting('summary_phases', 'min')); ?>. <?php _e('Current number of URLs processed or waiting to be checked.', 'wplnst'); ?></td>
|
114 |
+
</tr>
|
115 |
+
<tr>
|
116 |
+
<th><label for="tx-summary-objects"><?php _e('Summary of objects each', 'wplnst'); ?></label></th>
|
117 |
+
<td><input type="text" name="tx-summary-objects" id="tx-summary-objects" value="<?php echo esc_attr(wplnst_get_nsetting('summary_objects')); ?>" maxlength="3" class="small-text" /></td>
|
118 |
+
<td class="wplnst-col-info"><?php _e('seconds', 'wplnst'); ?> <?php printf(__('(mininum value of %d seconds)', 'wplnst'), wplnst_get_nsetting('summary_objects', 'min')); ?>. <?php _e('Summary of objects (posts, comments or blogroll) with processed URLs.', 'wplnst'); ?></td>
|
119 |
+
</tr>
|
120 |
+
</table>
|
121 |
+
|
122 |
+
</div>
|
123 |
+
|
124 |
+
|
125 |
+
<div id="wplnst-advanced" class="wplnst-tab">
|
126 |
+
|
127 |
+
<table class="form-table">
|
128 |
+
<tr>
|
129 |
+
<th><label for="tx-recursion-limit"><?php _e('Recursion limit', 'wplnst'); ?></label></th>
|
130 |
+
<td colspan="2"><input type="text" name="tx-recursion-limit" id="tx-recursion-limit" value="<?php echo esc_attr(wplnst_get_nsetting('recursion_limit')); ?>" maxlength="5" class="small-text" /> <?php _e('function calls', 'wplnst'); ?></td>
|
131 |
+
</tr>
|
132 |
+
<tr>
|
133 |
+
<th><?php _e('Data results pagination', 'wplnst'); ?></th>
|
134 |
+
<td colspan="2" class="wplnst-list"><input type="checkbox" <?php echo wplnst_get_bsetting('mysql_calc_rows')? 'checked' : ''; ?> name="ck-mysql-calc-rows" id="ck-mysql-calc-rows" value="on" /><label for="ck-mysql-calc-rows"> <?php _e('Use <code>SQL_CALC_FOUND_ROWS</code> to calculate total rows.', 'wplnst'); ?></label></td>
|
135 |
+
</tr>
|
136 |
+
<tr>
|
137 |
+
<th><?php _e('Data on uninstall', 'wplnst'); ?></th>
|
138 |
+
<td colspan="2" class="wplnst-list"><input type="checkbox" <?php echo wplnst_get_bsetting('uninstall_data')? 'checked' : ''; ?> name="ck-uninstall-data" id="ck-uninstall-data" value="on" /><label for="ck-uninstall-data"> <?php _e('Options and exclusive MySQL tables will be removed when uninstall this plugin.', 'wplnst'); ?></label></td>
|
139 |
+
</tr>
|
140 |
+
</table>
|
141 |
+
|
142 |
+
</div>
|
143 |
+
|
144 |
+
|
145 |
+
<p><input type="submit" value="<?php _e('Save settings', 'wplnst'); ?>" class="button button-primary" /></p>
|
146 |
+
|
147 |
+
</div>
|
148 |
+
|
149 |
+
</form><?php
|
150 |
+
}
|
151 |
+
|
152 |
+
|
153 |
+
|
154 |
+
}
|
views/views.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Link Status Views class
|
5 |
+
*
|
6 |
+
* @package WP Link Status
|
7 |
+
* @subpackage WP Link Status Views
|
8 |
+
*/
|
9 |
+
abstract class WPLNST_Views {
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Compose select option values
|
15 |
+
*/
|
16 |
+
public static function options($options, $values, $display = true, $space = false) {
|
17 |
+
$inner = '';
|
18 |
+
foreach ($options as $key => $name)
|
19 |
+
$inner .= '<option'.(self::selected($key, $values, false)? ' selected' : '').' value="'.esc_attr($key).'">'.esc_html($name).'</option>';
|
20 |
+
if ($display)
|
21 |
+
echo $inner;
|
22 |
+
return $inner;
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Check a checked value
|
29 |
+
*/
|
30 |
+
public static function checked($current, $values, $display = true) {
|
31 |
+
$checked = self::is_value($current, $values);
|
32 |
+
if ($checked && $display)
|
33 |
+
echo 'checked';
|
34 |
+
return $checked;
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Check a selected value
|
41 |
+
*/
|
42 |
+
public static function selected($current, $values, $display = true, $space = false) {
|
43 |
+
$selected = self::is_value($current, $values);
|
44 |
+
if ($selected && $display)
|
45 |
+
echo ($space? ' ' : '').'selected';
|
46 |
+
return $selected;
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Check if value match an array of values
|
53 |
+
*/
|
54 |
+
public static function is_value($current, $values) {
|
55 |
+
if (empty($values) && false !== $values)
|
56 |
+
return false;
|
57 |
+
return is_array($values)? in_array($current, $values) : ($current == $values);
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Encode and sanitize a json list
|
64 |
+
*/
|
65 |
+
public static function esc_attr_elist($json) {
|
66 |
+
$json_new = array();
|
67 |
+
foreach ($json as $json_item) {
|
68 |
+
$json_item_new = array();
|
69 |
+
foreach ($json_item as $key => $value)
|
70 |
+
$json_item_new[esc_attr($key)] = esc_attr($value);
|
71 |
+
$json_new[] = $json_item_new;
|
72 |
+
}
|
73 |
+
return str_replace('"', '%quot%', @json_encode($json_new));
|
74 |
+
}
|
75 |
+
|
76 |
+
|
77 |
+
|
78 |
+
}
|
wp-link-status.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: WP Broken Link Status Checker
|
4 |
+
Plugin URI: http://seedplugins.com/wp-link-status/
|
5 |
+
Description: Check and manage HTTP response codes of all your content site links and images.
|
6 |
+
Version: 1.0
|
7 |
+
Author: SeedPlugins
|
8 |
+
License: GPLv2 or later
|
9 |
+
Text Domain: wplnst
|
10 |
+
Domain Path: /languages
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Avoid script calls via plugin URL
|
14 |
+
if (!function_exists('add_action'))
|
15 |
+
die;
|
16 |
+
|
17 |
+
// Boot checks
|
18 |
+
require(dirname(__FILE__).'/core/boot.php');
|
19 |
+
|
20 |
+
// This plugin constants
|
21 |
+
define('WPLNST_FILE', __FILE__);
|
22 |
+
define('WPLNST_PATH', dirname(WPLNST_FILE));
|
23 |
+
define('WPLNST_VERSION', '1.0');
|
24 |
+
|
25 |
+
// Check scan crawling action
|
26 |
+
require_once(WPLNST_PATH.'/core/alive.php');
|
27 |
+
WPLNST_Core_Alive::check();
|
28 |
+
|
29 |
+
// Check context
|
30 |
+
if (is_admin()) {
|
31 |
+
|
32 |
+
// Admin area
|
33 |
+
wplnst_require('admin', 'admin');
|
34 |
+
WPLNST_Admin::instantiate();
|
35 |
+
|
36 |
+
// Plugin activation
|
37 |
+
register_activation_hook(WPLNST_FILE, 'wplnst_plugin_activation');
|
38 |
+
function wplnst_plugin_activation() {
|
39 |
+
wplnst_require('core', 'register');
|
40 |
+
WPLNST_Core_Register::activation();
|
41 |
+
}
|
42 |
+
|
43 |
+
// Plugin deactivation
|
44 |
+
register_deactivation_hook(WPLNST_FILE, 'wplnst_plugin_deactivation');
|
45 |
+
function wplnst_plugin_deactivation() {
|
46 |
+
wplnst_require('core', 'register');
|
47 |
+
WPLNST_Core_Register::deactivation();
|
48 |
+
}
|
49 |
+
|
50 |
+
// Plugin uninstall
|
51 |
+
register_uninstall_hook(WPLNST_FILE, 'wplnst_plugin_uninstall');
|
52 |
+
function wplnst_plugin_uninstall() {
|
53 |
+
wplnst_require('core', 'register');
|
54 |
+
WPLNST_Core_Register::uninstall();
|
55 |
+
}
|
56 |
+
}
|