Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16a3d54cb6 | ||
|
|
9677dcd978 | ||
|
|
17ea42f918 | ||
|
|
bd8915918d | ||
|
|
91db6773a0 | ||
|
|
f50680b61f | ||
|
|
3fb5d33333 | ||
|
|
f70bbb2660 | ||
|
|
589c1ac9bb | ||
|
|
d458fa1b89 | ||
|
|
dc2c99434f | ||
|
|
bbf36562d0 | ||
|
|
c458edf3e4 | ||
|
|
99c2aaef7a | ||
|
|
921096ca10 | ||
|
|
b0fbd6fa36 | ||
|
|
21bd67c44f | ||
|
|
4f142985a2 | ||
|
|
bfa89b44bc | ||
|
|
eba876e72b | ||
|
|
f1a7413e20 | ||
|
|
4d32749489 | ||
|
|
d911a16684 | ||
|
|
d7193bc755 | ||
|
|
aee9ffdb9c | ||
|
|
1f627d5e49 | ||
|
|
bb67626d09 | ||
|
|
4e0153e94a | ||
|
|
065142ff19 | ||
|
|
8bb6fae52f | ||
|
|
8cb7b81903 | ||
|
|
cb214ccda9 | ||
|
|
3fa7b96f27 | ||
|
|
7c8e259072 | ||
|
|
743d067042 | ||
|
|
50ea410718 | ||
|
|
e71182aed2 | ||
|
|
97f7963e0b | ||
|
|
6cea6a10bd | ||
|
|
344d41e365 | ||
|
|
597a8adfed | ||
|
|
5682e5483a | ||
|
|
18779edd7d | ||
|
|
63aeaea77a | ||
|
|
f51e48cb40 | ||
|
|
193372c79c | ||
|
|
34d0afe7e5 | ||
|
|
d33a9dd56d | ||
|
|
af2be90176 | ||
|
|
701fb21544 | ||
|
|
c8f010d9a6 | ||
|
|
c1ca7580e2 | ||
|
|
11d3c2cbf1 | ||
|
|
412f576aee | ||
|
|
ff98a7b23b | ||
|
|
507bac8542 | ||
|
|
3bd6cf4805 | ||
|
|
5712b31869 | ||
|
|
b0f9a0b18f | ||
|
|
f7665b460e | ||
|
|
100029b640 | ||
|
|
2b89bddf0f | ||
|
|
ca46bad8ec | ||
|
|
1ecd2600a3 | ||
|
|
28306b126b | ||
|
|
5c842e192b | ||
|
|
f9f307118d | ||
|
|
2266fa4f4b | ||
|
|
6df2564d1a | ||
|
|
b2a62ebd26 | ||
|
|
2fca30752a | ||
|
|
210eced369 | ||
|
|
08c574aff8 | ||
|
|
f4db2d65f1 | ||
|
|
23b02ade96 | ||
|
|
71d35b16ac | ||
|
|
200058c52a | ||
|
|
edb5fb202a | ||
|
|
d114c25cdb | ||
|
|
64e469568b | ||
|
|
c63d777372 | ||
|
|
ae343b8cb0 | ||
|
|
86eb5d2d57 | ||
|
|
b562d241db | ||
|
|
49b1829b78 | ||
|
|
1a5bf4035c | ||
|
|
f3810a1504 | ||
|
|
4831760c11 | ||
|
|
f375d8991e | ||
|
|
8145a4a3a6 | ||
|
|
12c9b49d4c | ||
|
|
c8eb81161e | ||
|
|
8ab246a66c | ||
|
|
8dfc4797fa | ||
|
|
7888fe1176 | ||
|
|
8a6f3056a3 | ||
|
|
5fbdf9e013 | ||
|
|
1da2f5e823 | ||
|
|
888779f81b | ||
|
|
352286e497 |
@@ -1,3 +1,14 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Before submitting an issue, please make sure you fully read any potential error messages output and did some research on your own.
|
||||
|
||||
### Subject of the issue
|
||||
Describe your issue here.
|
||||
|
||||
@@ -24,4 +35,4 @@ Things you have tried (where relevant):
|
||||
* Update Ruby to the latest version [ ]
|
||||
* Ensure you can reach the target site using cURL [ ]
|
||||
* Proxied WPScan through a HTTP proxy to view the raw traffic [ ]
|
||||
* Ensure you are using a supported Operating System (Linux and macOS) [ ]
|
||||
* Ensure you are using a supported Operating System (Linux and macOS) [ ]
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
10
.github/ISSUE_TEMPLATE/other-issue.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/other-issue.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Other Issue
|
||||
about: Create a report which is not a related to a Bug or Feature
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Before submitting an issue, please make sure you fully read any potential error messages output and did some research on your own.
|
||||
@@ -1,5 +1,6 @@
|
||||
require: rubocop-performance
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.3
|
||||
TargetRubyVersion: 2.4
|
||||
Exclude:
|
||||
- '*.gemspec'
|
||||
- 'vendor/**/*'
|
||||
@@ -9,6 +10,8 @@ LineLength:
|
||||
Max: 120
|
||||
MethodLength:
|
||||
Max: 20
|
||||
Exclude:
|
||||
- 'app/controllers/enumeration/cli_options.rb'
|
||||
Lint/UriEscapeUnescape:
|
||||
Enabled: false
|
||||
Metrics/AbcSize:
|
||||
@@ -18,6 +21,8 @@ Metrics/BlockLength:
|
||||
- 'spec/**/*'
|
||||
Metrics/ClassLength:
|
||||
Max: 150
|
||||
Exclude:
|
||||
- 'app/controllers/enumeration/cli_options.rb'
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 8
|
||||
Style/Documentation:
|
||||
|
||||
11
.travis.yml
11
.travis.yml
@@ -2,20 +2,12 @@ language: ruby
|
||||
sudo: false
|
||||
cache: bundler
|
||||
rvm:
|
||||
- 2.3.0
|
||||
- 2.3.1
|
||||
- 2.3.2
|
||||
- 2.3.3
|
||||
- 2.3.4
|
||||
- 2.3.5
|
||||
- 2.3.6
|
||||
- 2.3.7
|
||||
- 2.3.8
|
||||
- 2.4.1
|
||||
- 2.4.2
|
||||
- 2.4.3
|
||||
- 2.4.4
|
||||
- 2.4.5
|
||||
- 2.4.6
|
||||
- 2.5.0
|
||||
- 2.5.1
|
||||
- 2.5.2
|
||||
@@ -25,6 +17,7 @@ rvm:
|
||||
- 2.6.0
|
||||
- 2.6.1
|
||||
- 2.6.2
|
||||
- 2.6.3
|
||||
- ruby-head
|
||||
before_install:
|
||||
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
||||
|
||||
@@ -25,13 +25,16 @@ LABEL maintainer="WPScan Team <team@wpscan.org>"
|
||||
RUN adduser -h /wpscan -g WPScan -D wpscan
|
||||
|
||||
COPY --from=builder /usr/local/bundle /usr/local/bundle
|
||||
|
||||
RUN chown -R wpscan:wpscan /wpscan
|
||||
|
||||
# runtime dependencies
|
||||
RUN apk add --no-cache libcurl procps sqlite-libs
|
||||
|
||||
WORKDIR /wpscan
|
||||
|
||||
USER wpscan
|
||||
|
||||
RUN /usr/local/bundle/bin/wpscan --update --verbose
|
||||
|
||||
ENTRYPOINT ["/usr/local/bundle/bin/wpscan"]
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -2,3 +2,5 @@
|
||||
|
||||
source 'https://rubygems.org'
|
||||
gemspec
|
||||
|
||||
# gem 'cms_scanner', branch: 'xxx', git: 'https://github.com/wpscanteam/CMSScanner.git'
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
- Curl >= 7.21 - Recommended: latest
|
||||
- The 7.29 has a segfault
|
||||
- RubyGems - Recommended: latest
|
||||
- Nokogiri might require packages to be installed via your package manager depending on your OS, see https://nokogiri.org/tutorials/installing_nokogiri.html
|
||||
|
||||
### From RubyGems (Recommended)
|
||||
|
||||
|
||||
@@ -27,38 +27,41 @@ module WPScan
|
||||
# @return [ Boolean ]
|
||||
def update_db_required?
|
||||
if local_db.missing_files?
|
||||
raise Error::MissingDatabaseFile if parsed_options[:update] == false
|
||||
raise Error::MissingDatabaseFile if ParsedCli.update == false
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return parsed_options[:update] unless parsed_options[:update].nil?
|
||||
return ParsedCli.update unless ParsedCli.update.nil?
|
||||
|
||||
return false unless user_interaction? && local_db.outdated?
|
||||
|
||||
output('@notice', msg: 'It seems like you have not updated the database for some time.')
|
||||
print '[?] Do you want to update now? [Y]es [N]o, default: [N]'
|
||||
|
||||
Readline.readline =~ /^y/i ? true : false
|
||||
/^y/i.match?(Readline.readline) ? true : false
|
||||
end
|
||||
|
||||
def update_db
|
||||
output('db_update_started')
|
||||
output('db_update_finished', updated: local_db.update, verbose: parsed_options[:verbose])
|
||||
output('db_update_finished', updated: local_db.update, verbose: ParsedCli.verbose)
|
||||
|
||||
exit(0) unless parsed_options[:url]
|
||||
exit(0) unless ParsedCli.url
|
||||
end
|
||||
|
||||
def before_scan
|
||||
@last_update = local_db.last_update
|
||||
|
||||
maybe_output_banner_help_and_version # From CMS Scanner
|
||||
maybe_output_banner_help_and_version # From CMSScanner
|
||||
|
||||
update_db if update_db_required?
|
||||
setup_cache
|
||||
check_target_availability
|
||||
load_server_module
|
||||
check_wordpress_state
|
||||
rescue Error::NotWordPress => e
|
||||
target.maybe_add_cookies
|
||||
raise e unless target.wordpress?(ParsedCli.detection_mode)
|
||||
end
|
||||
|
||||
# Raises errors if the target is hosted on wordpress.com or is not running WordPress
|
||||
@@ -66,14 +69,14 @@ module WPScan
|
||||
def check_wordpress_state
|
||||
raise Error::WordPressHosted if target.wordpress_hosted?
|
||||
|
||||
if Addressable::URI.parse(target.homepage_url).path =~ %r{/wp-admin/install.php$}i
|
||||
if %r{/wp-admin/install.php$}i.match?(Addressable::URI.parse(target.homepage_url).path)
|
||||
|
||||
output('not_fully_configured', url: target.homepage_url)
|
||||
|
||||
exit(WPScan::ExitCode::VULNERABLE)
|
||||
end
|
||||
|
||||
raise Error::NotWordPress unless target.wordpress?(parsed_options[:detection_mode]) || parsed_options[:force]
|
||||
raise Error::NotWordPress unless target.wordpress?(ParsedCli.detection_mode) || ParsedCli.force
|
||||
end
|
||||
|
||||
# Loads the related server module in the target
|
||||
@@ -85,7 +88,7 @@ module WPScan
|
||||
server = target.server || :Apache # Tries to auto detect the server
|
||||
|
||||
# Force a specific server module to be loaded if supplied
|
||||
case parsed_options[:server]
|
||||
case ParsedCli.server
|
||||
when :apache
|
||||
server = :Apache
|
||||
when :iis
|
||||
|
||||
@@ -7,16 +7,18 @@ module WPScan
|
||||
class CustomDirectories < CMSScanner::Controller::Base
|
||||
def cli_options
|
||||
[
|
||||
OptString.new(['--wp-content-dir DIR']),
|
||||
OptString.new(['--wp-plugins-dir DIR'])
|
||||
OptString.new(['--wp-content-dir DIR',
|
||||
'The wp-content directory if custom or not detected, such as "wp-content"']),
|
||||
OptString.new(['--wp-plugins-dir DIR',
|
||||
'The plugins directory if custom or not detected, such as "wp-content/plugins"'])
|
||||
]
|
||||
end
|
||||
|
||||
def before_scan
|
||||
target.content_dir = parsed_options[:wp_content_dir] if parsed_options[:wp_content_dir]
|
||||
target.plugins_dir = parsed_options[:wp_plugins_dir] if parsed_options[:wp_plugins_dir]
|
||||
target.content_dir = ParsedCli.wp_content_dir if ParsedCli.wp_content_dir
|
||||
target.plugins_dir = ParsedCli.wp_plugins_dir if ParsedCli.wp_plugins_dir
|
||||
|
||||
return if target.content_dir
|
||||
return if target.content_dir(ParsedCli.detection_mode)
|
||||
|
||||
raise Error::WpContentDirNotDetected
|
||||
end
|
||||
|
||||
@@ -7,17 +7,8 @@ module WPScan
|
||||
module Controller
|
||||
# Enumeration Controller
|
||||
class Enumeration < CMSScanner::Controller::Base
|
||||
def before_scan
|
||||
DB::DynamicFinders::Plugin.create_versions_finders
|
||||
DB::DynamicFinders::Theme.create_versions_finders
|
||||
|
||||
# Force the Garbage Collector to run due to the above method being
|
||||
# quite heavy in objects allocation
|
||||
GC.start
|
||||
end
|
||||
|
||||
def run
|
||||
enum = parsed_options[:enumerate] || {}
|
||||
enum = ParsedCli.enumerate || {}
|
||||
|
||||
enum_plugins if enum_plugins?(enum)
|
||||
enum_themes if enum_themes?(enum)
|
||||
|
||||
@@ -11,7 +11,6 @@ module WPScan
|
||||
end
|
||||
|
||||
# @return [ Array<OptParseValidator::OptBase> ]
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def cli_enum_choices
|
||||
[
|
||||
OptMultiChoices.new(
|
||||
@@ -45,7 +44,6 @@ module WPScan
|
||||
)
|
||||
]
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
# @return [ Array<OptParseValidator::OptBase> ]
|
||||
def cli_plugins_opts
|
||||
@@ -67,6 +65,11 @@ module WPScan
|
||||
'Use the supplied mode to check plugins versions instead of the --detection-mode ' \
|
||||
'or --plugins-detection modes.'],
|
||||
choices: %w[mixed passive aggressive], normalize: :to_sym, default: :mixed
|
||||
),
|
||||
OptInteger.new(
|
||||
['--plugins-threshold THRESHOLD',
|
||||
'Raise an error when the number of detected plugins via known locations reaches the threshold. ' \
|
||||
'Set to 0 to ignore the threshold.'], default: 100
|
||||
)
|
||||
]
|
||||
end
|
||||
@@ -91,6 +94,11 @@ module WPScan
|
||||
'Use the supplied mode to check themes versions instead of the --detection-mode ' \
|
||||
'or --themes-detection modes.'],
|
||||
choices: %w[mixed passive aggressive], normalize: :to_sym, advanced: true
|
||||
),
|
||||
OptInteger.new(
|
||||
['--themes-threshold THRESHOLD',
|
||||
'Raise an error when the number of detected themes via known locations reaches the threshold. ' \
|
||||
'Set to 0 to ignore the threshold.'], default: 20
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
@@ -7,13 +7,13 @@ module WPScan
|
||||
# @param [ String ] type (plugins or themes)
|
||||
# @param [ Symbol ] detection_mode
|
||||
#
|
||||
# @return [ String ] The related enumration message depending on the parsed_options and type supplied
|
||||
# @return [ String ] The related enumration message depending on the ParsedCli and type supplied
|
||||
def enum_message(type, detection_mode)
|
||||
return unless %w[plugins themes].include?(type)
|
||||
|
||||
details = if parsed_options[:enumerate][:"vulnerable_#{type}"]
|
||||
details = if ParsedCli.enumerate[:"vulnerable_#{type}"]
|
||||
'Vulnerable'
|
||||
elsif parsed_options[:enumerate][:"all_#{type}"]
|
||||
elsif ParsedCli.enumerate[:"all_#{type}"]
|
||||
'All'
|
||||
else
|
||||
'Most Popular'
|
||||
@@ -39,15 +39,15 @@ module WPScan
|
||||
#
|
||||
# @return [ Hash ]
|
||||
def default_opts(type)
|
||||
mode = parsed_options[:"#{type}_detection"] || parsed_options[:detection_mode]
|
||||
mode = ParsedCli.options[:"#{type}_detection"] || ParsedCli.detection_mode
|
||||
|
||||
{
|
||||
mode: mode,
|
||||
exclude_content: parsed_options[:exclude_content_based],
|
||||
exclude_content: ParsedCli.exclude_content_based,
|
||||
show_progression: user_interaction?,
|
||||
version_detection: {
|
||||
mode: parsed_options[:"#{type}_version_detection"] || mode,
|
||||
confidence_threshold: parsed_options[:"#{type}_version_all"] ? 0 : 100
|
||||
mode: ParsedCli.options[:"#{type}_version_detection"] || mode,
|
||||
confidence_threshold: ParsedCli.options[:"#{type}_version_all"] ? 0 : 100
|
||||
}
|
||||
}
|
||||
end
|
||||
@@ -61,7 +61,8 @@ module WPScan
|
||||
|
||||
def enum_plugins
|
||||
opts = default_opts('plugins').merge(
|
||||
list: plugins_list_from_opts(parsed_options),
|
||||
list: plugins_list_from_opts(ParsedCli.options),
|
||||
threshold: ParsedCli.plugins_threshold,
|
||||
sort: true
|
||||
)
|
||||
|
||||
@@ -77,7 +78,7 @@ module WPScan
|
||||
|
||||
plugins.each(&:version)
|
||||
|
||||
plugins.select!(&:vulnerable?) if parsed_options[:enumerate][:vulnerable_plugins]
|
||||
plugins.select!(&:vulnerable?) if ParsedCli.enumerate[:vulnerable_plugins]
|
||||
|
||||
output('plugins', plugins: plugins)
|
||||
end
|
||||
@@ -107,7 +108,8 @@ module WPScan
|
||||
|
||||
def enum_themes
|
||||
opts = default_opts('themes').merge(
|
||||
list: themes_list_from_opts(parsed_options),
|
||||
list: themes_list_from_opts(ParsedCli.options),
|
||||
threshold: ParsedCli.themes_threshold,
|
||||
sort: true
|
||||
)
|
||||
|
||||
@@ -123,7 +125,7 @@ module WPScan
|
||||
|
||||
themes.each(&:version)
|
||||
|
||||
themes.select!(&:vulnerable?) if parsed_options[:enumerate][:vulnerable_themes]
|
||||
themes.select!(&:vulnerable?) if ParsedCli.enumerate[:vulnerable_themes]
|
||||
|
||||
output('themes', themes: themes)
|
||||
end
|
||||
@@ -145,28 +147,28 @@ module WPScan
|
||||
end
|
||||
|
||||
def enum_timthumbs
|
||||
opts = default_opts('timthumbs').merge(list: parsed_options[:timthumbs_list])
|
||||
opts = default_opts('timthumbs').merge(list: ParsedCli.timthumbs_list)
|
||||
|
||||
output('@info', msg: "Enumerating Timthumbs #{enum_detection_message(opts[:mode])}") if user_interaction?
|
||||
output('timthumbs', timthumbs: target.timthumbs(opts))
|
||||
end
|
||||
|
||||
def enum_config_backups
|
||||
opts = default_opts('config_backups').merge(list: parsed_options[:config_backups_list])
|
||||
opts = default_opts('config_backups').merge(list: ParsedCli.config_backups_list)
|
||||
|
||||
output('@info', msg: "Enumerating Config Backups #{enum_detection_message(opts[:mode])}") if user_interaction?
|
||||
output('config_backups', config_backups: target.config_backups(opts))
|
||||
end
|
||||
|
||||
def enum_db_exports
|
||||
opts = default_opts('db_exports').merge(list: parsed_options[:db_exports_list])
|
||||
opts = default_opts('db_exports').merge(list: ParsedCli.db_exports_list)
|
||||
|
||||
output('@info', msg: "Enumerating DB Exports #{enum_detection_message(opts[:mode])}") if user_interaction?
|
||||
output('db_exports', db_exports: target.db_exports(opts))
|
||||
end
|
||||
|
||||
def enum_medias
|
||||
opts = default_opts('medias').merge(range: parsed_options[:enumerate][:medias])
|
||||
opts = default_opts('medias').merge(range: ParsedCli.enumerate[:medias])
|
||||
|
||||
if user_interaction?
|
||||
output('@info',
|
||||
@@ -181,13 +183,13 @@ module WPScan
|
||||
#
|
||||
# @return [ Boolean ] Wether or not to enumerate the users
|
||||
def enum_users?(opts)
|
||||
opts[:users] || (parsed_options[:passwords] && !parsed_options[:username] && !parsed_options[:usernames])
|
||||
opts[:users] || (ParsedCli.passwords && !ParsedCli.username && !ParsedCli.usernames)
|
||||
end
|
||||
|
||||
def enum_users
|
||||
opts = default_opts('users').merge(
|
||||
range: enum_users_range,
|
||||
list: parsed_options[:users_list]
|
||||
list: ParsedCli.users_list
|
||||
)
|
||||
|
||||
output('@info', msg: "Enumerating Users #{enum_detection_message(opts[:mode])}") if user_interaction?
|
||||
@@ -198,7 +200,7 @@ module WPScan
|
||||
# If the --enumerate is used, the default value is handled by the Option
|
||||
# However, when using --passwords alone, the default has to be set by the code below
|
||||
def enum_users_range
|
||||
parsed_options[:enumerate][:users] || cli_enum_choices[0].choices[:u].validate(nil)
|
||||
ParsedCli.enumerate[:users] || cli_enum_choices[0].choices[:u].validate(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,9 +18,9 @@ module WPScan
|
||||
output(
|
||||
'theme',
|
||||
theme: target.main_theme(
|
||||
mode: parsed_options[:main_theme_detection] || parsed_options[:detection_mode]
|
||||
mode: ParsedCli.main_theme_detection || ParsedCli.detection_mode
|
||||
),
|
||||
verbose: parsed_options[:verbose]
|
||||
verbose: ParsedCli.verbose
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,7 +24,7 @@ module WPScan
|
||||
end
|
||||
|
||||
def run
|
||||
return unless parsed_options[:passwords]
|
||||
return unless ParsedCli.passwords
|
||||
|
||||
if user_interaction?
|
||||
output('@info',
|
||||
@@ -33,13 +33,13 @@ module WPScan
|
||||
|
||||
attack_opts = {
|
||||
show_progression: user_interaction?,
|
||||
multicall_max_passwords: parsed_options[:multicall_max_passwords]
|
||||
multicall_max_passwords: ParsedCli.multicall_max_passwords
|
||||
}
|
||||
|
||||
begin
|
||||
found = []
|
||||
|
||||
attacker.attack(users, passwords(parsed_options[:passwords]), attack_opts) do |user|
|
||||
attacker.attack(users, passwords(ParsedCli.passwords), attack_opts) do |user|
|
||||
found << user
|
||||
|
||||
attacker.progress_bar.log("[SUCCESS] - #{user.username} / #{user.password}")
|
||||
@@ -61,42 +61,55 @@ module WPScan
|
||||
|
||||
# @return [ CMSScanner::Finders::Finder ]
|
||||
def attacker_from_cli_options
|
||||
return unless parsed_options[:password_attack]
|
||||
return unless ParsedCli.password_attack
|
||||
|
||||
case parsed_options[:password_attack]
|
||||
case ParsedCli.password_attack
|
||||
when :wp_login
|
||||
WPScan::Finders::Passwords::WpLogin.new(target)
|
||||
Finders::Passwords::WpLogin.new(target)
|
||||
when :xmlrpc
|
||||
raise Error::XMLRPCNotDetected unless xmlrpc
|
||||
|
||||
WPScan::Finders::Passwords::XMLRPC.new(xmlrpc)
|
||||
Finders::Passwords::XMLRPC.new(xmlrpc)
|
||||
when :xmlrpc_multicall
|
||||
raise Error::XMLRPCNotDetected unless xmlrpc
|
||||
|
||||
WPScan::Finders::Passwords::XMLRPCMulticall.new(xmlrpc)
|
||||
Finders::Passwords::XMLRPCMulticall.new(xmlrpc)
|
||||
end
|
||||
end
|
||||
|
||||
# @return [ Boolean ]
|
||||
def xmlrpc_get_users_blogs_enabled?
|
||||
if xmlrpc&.enabled? &&
|
||||
xmlrpc.available_methods.include?('wp.getUsersBlogs') &&
|
||||
xmlrpc.method_call('wp.getUsersBlogs', [SecureRandom.hex[0, 6], SecureRandom.hex[0, 4]])
|
||||
.run.body !~ /XML\-RPC services are disabled/
|
||||
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# @return [ CMSScanner::Finders::Finder ]
|
||||
def attacker_from_automatic_detection
|
||||
if xmlrpc&.enabled? && xmlrpc.available_methods.include?('wp.getUsersBlogs')
|
||||
if xmlrpc_get_users_blogs_enabled?
|
||||
wp_version = target.wp_version
|
||||
|
||||
if wp_version && wp_version < '4.4'
|
||||
WPScan::Finders::Passwords::XMLRPCMulticall.new(xmlrpc)
|
||||
Finders::Passwords::XMLRPCMulticall.new(xmlrpc)
|
||||
else
|
||||
WPScan::Finders::Passwords::XMLRPC.new(xmlrpc)
|
||||
Finders::Passwords::XMLRPC.new(xmlrpc)
|
||||
end
|
||||
else
|
||||
WPScan::Finders::Passwords::WpLogin.new(target)
|
||||
Finders::Passwords::WpLogin.new(target)
|
||||
end
|
||||
end
|
||||
|
||||
# @return [ Array<Users> ] The users to brute force
|
||||
def users
|
||||
return target.users unless parsed_options[:usernames]
|
||||
return target.users unless ParsedCli.usernames
|
||||
|
||||
parsed_options[:usernames].reduce([]) do |acc, elem|
|
||||
ParsedCli.usernames.reduce([]) do |acc, elem|
|
||||
acc << Model::User.new(elem.chomp)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,15 +17,15 @@ module WPScan
|
||||
end
|
||||
|
||||
def before_scan
|
||||
WPScan::DB::DynamicFinders::Wordpress.create_versions_finders
|
||||
DB::DynamicFinders::Wordpress.create_versions_finders
|
||||
end
|
||||
|
||||
def run
|
||||
output(
|
||||
'version',
|
||||
version: target.wp_version(
|
||||
mode: parsed_options[:wp_version_detection] || parsed_options[:detection_mode],
|
||||
confidence_threshold: parsed_options[:wp_version_all] ? 0 : 100,
|
||||
mode: ParsedCli.wp_version_detection || ParsedCli.detection_mode,
|
||||
confidence_threshold: ParsedCli.wp_version_all ? 0 : 100,
|
||||
show_progression: user_interaction?
|
||||
)
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ module WPScan
|
||||
|
||||
Model::EmergencyPwdResetScript.new(
|
||||
target.url(path),
|
||||
confidence: res.body =~ /password/i ? 100 : 40,
|
||||
confidence: /password/i.match?(res.body) ? 100 : 40,
|
||||
found_by: DIRECT_ACCESS,
|
||||
references: {
|
||||
url: 'https://codex.wordpress.org/Resetting_Your_Password#Using_the_Emergency_Password_Reset_Script'
|
||||
|
||||
@@ -9,11 +9,13 @@ module WPScan
|
||||
def passive(_opts = {})
|
||||
pattern = %r{#{target.content_dir}/mu\-plugins/}i
|
||||
|
||||
target.in_scope_urls(target.homepage_res) do |url|
|
||||
next unless Addressable::URI.parse(url).path =~ pattern
|
||||
target.in_scope_uris(target.homepage_res) do |uri|
|
||||
next unless uri.path =~ pattern
|
||||
|
||||
url = target.url('wp-content/mu-plugins/')
|
||||
|
||||
target.mu_plugins = true
|
||||
|
||||
return Model::MuPlugins.new(
|
||||
url,
|
||||
confidence: 70,
|
||||
@@ -33,8 +35,6 @@ module WPScan
|
||||
return unless [200, 401, 403].include?(res.code)
|
||||
return if target.homepage_or_404?(res)
|
||||
|
||||
# TODO: add the check for --exclude-content once implemented ?
|
||||
|
||||
target.mu_plugins = true
|
||||
|
||||
Model::MuPlugins.new(
|
||||
|
||||
@@ -20,10 +20,10 @@ module WPScan
|
||||
end
|
||||
|
||||
def passive_from_css_href(res, opts)
|
||||
target.in_scope_urls(res, '//style/@src|//link/@href') do |url|
|
||||
next unless Addressable::URI.parse(url).path =~ %r{/themes/([^\/]+)/style.css\z}i
|
||||
target.in_scope_uris(res, '//style/@src|//link/@href') do |uri|
|
||||
next unless uri.path =~ %r{/themes/([^\/]+)/style.css\z}i
|
||||
|
||||
return create_theme(Regexp.last_match[1], url, opts)
|
||||
return create_theme(Regexp.last_match[1], uri.to_s, opts)
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -13,25 +13,15 @@ module WPScan
|
||||
def initialize(plugin)
|
||||
finders << PluginVersion::Readme.new(plugin)
|
||||
|
||||
load_specific_finders(plugin)
|
||||
create_and_load_dynamic_versions_finders(plugin)
|
||||
end
|
||||
|
||||
# Load the finders associated with the plugin
|
||||
# Create the dynamic version finders related to the plugin and register them
|
||||
#
|
||||
# @param [ Model::Plugin ] plugin
|
||||
def load_specific_finders(plugin)
|
||||
module_name = plugin.classify
|
||||
|
||||
return unless Finders::PluginVersion.constants.include?(module_name)
|
||||
|
||||
mod = Finders::PluginVersion.const_get(module_name)
|
||||
|
||||
mod.constants.each do |constant|
|
||||
c = mod.const_get(constant)
|
||||
|
||||
next unless c.is_a?(Class)
|
||||
|
||||
finders << c.new(plugin)
|
||||
def create_and_load_dynamic_versions_finders(plugin)
|
||||
DB::DynamicFinders::Plugin.create_versions_finders(plugin.slug).each do |finder|
|
||||
finders << finder.new(plugin)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ module WPScan
|
||||
|
||||
# The target(plugin)#readme_url can't be used directly here
|
||||
# as if the --detection-mode is passive, it will always return nil
|
||||
Model::WpItem::READMES.each do |file|
|
||||
target.potential_readme_filenames.each do |file|
|
||||
res = target.head_and_get(file)
|
||||
|
||||
next unless res.code == 200 && !(numbers = version_numbers(res.body)).empty?
|
||||
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module Finders
|
||||
module Plugins
|
||||
# Plugins finder from Dynamic Finder 'BodyPattern'
|
||||
class BodyPattern < WPScan::Finders::DynamicFinder::WpItems::Finder
|
||||
class BodyPattern < Finders::DynamicFinder::WpItems::Finder
|
||||
DEFAULT_CONFIDENCE = 30
|
||||
|
||||
# @param [ Hash ] opts The options from the #passive, #aggressive methods
|
||||
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module Finders
|
||||
module Plugins
|
||||
# Plugins finder from the Dynamic Finder 'Comment'
|
||||
class Comment < WPScan::Finders::DynamicFinder::WpItems::Finder
|
||||
class Comment < Finders::DynamicFinder::WpItems::Finder
|
||||
DEFAULT_CONFIDENCE = 30
|
||||
|
||||
# @param [ Hash ] opts The options from the #passive, #aggressive methods
|
||||
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module Finders
|
||||
module Plugins
|
||||
# Plugins finder from Dynamic Finder 'ConfigParser'
|
||||
class ConfigParser < WPScan::Finders::DynamicFinder::WpItems::Finder
|
||||
class ConfigParser < Finders::DynamicFinder::WpItems::Finder
|
||||
DEFAULT_CONFIDENCE = 40
|
||||
|
||||
# @param [ Hash ] opts The options from the #passive, #aggressive methods
|
||||
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module Finders
|
||||
module Plugins
|
||||
# Plugins finder from Dynamic Finder 'HeaderPattern'
|
||||
class HeaderPattern < WPScan::Finders::DynamicFinder::WpItems::Finder
|
||||
class HeaderPattern < Finders::DynamicFinder::WpItems::Finder
|
||||
DEFAULT_CONFIDENCE = 30
|
||||
|
||||
# @param [ Hash ] opts
|
||||
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module Finders
|
||||
module Plugins
|
||||
# Plugins finder from the Dynamic Finder 'JavascriptVar'
|
||||
class JavascriptVar < WPScan::Finders::DynamicFinder::WpItems::Finder
|
||||
class JavascriptVar < Finders::DynamicFinder::WpItems::Finder
|
||||
DEFAULT_CONFIDENCE = 60
|
||||
|
||||
# @param [ Hash ] opts The options from the #passive, #aggressive methods
|
||||
|
||||
@@ -9,7 +9,7 @@ module WPScan
|
||||
|
||||
# @return [ Array<Integer> ]
|
||||
def valid_response_codes
|
||||
@valid_response_codes ||= [200, 401, 403, 301, 500].freeze
|
||||
@valid_response_codes ||= [200, 401, 403, 500].freeze
|
||||
end
|
||||
|
||||
# @param [ Hash ] opts
|
||||
@@ -19,8 +19,10 @@ module WPScan
|
||||
def aggressive(opts = {})
|
||||
found = []
|
||||
|
||||
enumerate(target_urls(opts), opts.merge(check_full_response: [200, 401, 403, 500])) do |_res, slug|
|
||||
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |_res, slug|
|
||||
found << Model::Plugin.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
||||
|
||||
raise Error::PluginsThresholdReached if opts[:threshold].positive? && found.size >= opts[:threshold]
|
||||
end
|
||||
|
||||
found
|
||||
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module Finders
|
||||
module Plugins
|
||||
# Plugins finder from Dynamic Finder 'QueryParameter'
|
||||
class QueryParameter < WPScan::Finders::DynamicFinder::WpItems::Finder
|
||||
class QueryParameter < Finders::DynamicFinder::WpItems::Finder
|
||||
DEFAULT_CONFIDENCE = 10
|
||||
|
||||
def passive(_opts = {})
|
||||
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module Finders
|
||||
module Plugins
|
||||
# Plugins finder from the Dynamic Finder 'Xpath'
|
||||
class Xpath < WPScan::Finders::DynamicFinder::WpItems::Finder
|
||||
class Xpath < Finders::DynamicFinder::WpItems::Finder
|
||||
DEFAULT_CONFIDENCE = 40
|
||||
|
||||
# @param [ Hash ] opts The options from the #passive, #aggressive methods
|
||||
|
||||
@@ -16,25 +16,15 @@ module WPScan
|
||||
ThemeVersion::Style.new(theme) <<
|
||||
ThemeVersion::WooFrameworkMetaGenerator.new(theme)
|
||||
|
||||
load_specific_finders(theme)
|
||||
create_and_load_dynamic_versions_finders(theme)
|
||||
end
|
||||
|
||||
# Load the finders associated with the theme
|
||||
# Create the dynamic version finders related to the theme and register them
|
||||
#
|
||||
# @param [ Model::Theme ] theme
|
||||
def load_specific_finders(theme)
|
||||
module_name = theme.classify
|
||||
|
||||
return unless Finders::ThemeVersion.constants.include?(module_name)
|
||||
|
||||
mod = Finders::ThemeVersion.const_get(module_name)
|
||||
|
||||
mod.constants.each do |constant|
|
||||
c = mod.const_get(constant)
|
||||
|
||||
next unless c.is_a?(Class)
|
||||
|
||||
finders << c.new(theme)
|
||||
def create_and_load_dynamic_versions_finders(theme)
|
||||
DB::DynamicFinders::Theme.create_versions_finders(theme.slug).each do |finder|
|
||||
finders << finder.new(theme)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@ module WPScan
|
||||
|
||||
# @return [ Array<Integer> ]
|
||||
def valid_response_codes
|
||||
@valid_response_codes ||= [200, 401, 403, 301, 500].freeze
|
||||
@valid_response_codes ||= [200, 401, 403, 500].freeze
|
||||
end
|
||||
|
||||
# @param [ Hash ] opts
|
||||
@@ -19,8 +19,10 @@ module WPScan
|
||||
def aggressive(opts = {})
|
||||
found = []
|
||||
|
||||
enumerate(target_urls(opts), opts.merge(check_full_response: [200, 401, 403, 500])) do |_res, slug|
|
||||
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |_res, slug|
|
||||
found << Model::Theme.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
||||
|
||||
raise Error::ThemesThresholdReached if opts[:threshold].positive? && found.size >= opts[:threshold]
|
||||
end
|
||||
|
||||
found
|
||||
|
||||
@@ -7,6 +7,11 @@ module WPScan
|
||||
class AuthorIdBruteForcing < CMSScanner::Finders::Finder
|
||||
include CMSScanner::Finders::Finder::Enumerator
|
||||
|
||||
# @return [ Array<Integer> ]
|
||||
def valid_response_codes
|
||||
@valid_response_codes ||= [200, 301, 302]
|
||||
end
|
||||
|
||||
# @param [ Hash ] opts
|
||||
# @option opts [ Range ] :range Mandatory
|
||||
#
|
||||
@@ -15,7 +20,7 @@ module WPScan
|
||||
found = []
|
||||
found_by_msg = 'Author Id Brute Forcing - %s (Aggressive Detection)'
|
||||
|
||||
enumerate(target_urls(opts), opts) do |res, id|
|
||||
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |res, id|
|
||||
username, found_by, confidence = potential_username(res)
|
||||
|
||||
next unless username
|
||||
@@ -49,7 +54,7 @@ module WPScan
|
||||
super(opts.merge(title: ' Brute Forcing Author IDs -'))
|
||||
end
|
||||
|
||||
def request_params
|
||||
def full_request_params
|
||||
{ followlocation: true }
|
||||
end
|
||||
|
||||
@@ -78,8 +83,8 @@ module WPScan
|
||||
# @return [ String, nil ] The username found
|
||||
def username_from_response(res)
|
||||
# Permalink enabled
|
||||
target.in_scope_urls(res, '//link/@href|//a/@href') do |url|
|
||||
username = username_from_author_url(url)
|
||||
target.in_scope_uris(res, '//link/@href|//a/@href') do |uri|
|
||||
username = username_from_author_url(uri.to_s)
|
||||
return username if username
|
||||
end
|
||||
|
||||
|
||||
@@ -45,12 +45,10 @@ module WPScan
|
||||
def potential_usernames(res)
|
||||
usernames = []
|
||||
|
||||
target.in_scope_urls(res, '//a/@href') do |url, node|
|
||||
uri = Addressable::URI.parse(url)
|
||||
|
||||
target.in_scope_uris(res, '//a/@href') do |uri, node|
|
||||
if uri.path =~ %r{/author/([^/\b]+)/?\z}i
|
||||
usernames << [Regexp.last_match[1], 'Author Pattern', 100]
|
||||
elsif uri.query =~ /author=[0-9]+/
|
||||
elsif /author=[0-9]+/.match?(uri.query)
|
||||
usernames << [node.text.to_s.strip, 'Display Name', 30]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ module WPScan
|
||||
# Users disclosed from the dc:creator field in the RSS
|
||||
# The names disclosed are display names, however depending on the configuration of the blog,
|
||||
# they can be the same than usernames
|
||||
class RSSGenerator < WPScan::Finders::WpVersion::RSSGenerator
|
||||
class RSSGenerator < Finders::WpVersion::RSSGenerator
|
||||
def process_urls(urls, _opts = {})
|
||||
found = []
|
||||
|
||||
|
||||
@@ -57,9 +57,7 @@ module WPScan
|
||||
def api_url
|
||||
return @api_url if @api_url
|
||||
|
||||
target.in_scope_urls(target.homepage_res, "//link[@rel='https://api.w.org/']/@href").each do |url, _tag|
|
||||
uri = Addressable::URI.parse(url.strip)
|
||||
|
||||
target.in_scope_uris(target.homepage_res, "//link[@rel='https://api.w.org/']/@href").each do |uri|
|
||||
return @api_url = uri.join('wp/v2/users/').to_s if uri.path.include?('wp-json')
|
||||
end
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ module WPScan
|
||||
def items_from_links(type, uniq = true)
|
||||
found = []
|
||||
|
||||
target.in_scope_urls(target.homepage_res) do |url|
|
||||
next unless url =~ item_attribute_pattern(type)
|
||||
target.in_scope_uris(target.homepage_res) do |uri|
|
||||
next unless uri.to_s =~ item_attribute_pattern(type)
|
||||
|
||||
found << Regexp.last_match[1]
|
||||
end
|
||||
|
||||
@@ -28,7 +28,7 @@ module WPScan
|
||||
# @param [ WPScan::Target ] target
|
||||
def initialize(target)
|
||||
(%w[RSSGenerator AtomGenerator RDFGenerator] +
|
||||
WPScan::DB::DynamicFinders::Wordpress.versions_finders_configs.keys +
|
||||
DB::DynamicFinders::Wordpress.versions_finders_configs.keys +
|
||||
%w[Readme UniqueFingerprinting]
|
||||
).each do |finder_name|
|
||||
finders << WpVersion.const_get(finder_name.to_sym).new(target)
|
||||
|
||||
@@ -28,6 +28,11 @@ module WPScan
|
||||
|
||||
@version
|
||||
end
|
||||
|
||||
# @return [ Array<String> ]
|
||||
def potential_readme_filenames
|
||||
@potential_readme_filenames ||= [*(DB::DynamicFinders::Plugin.df_data.dig(slug, 'Readme', 'path') || super)]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -63,7 +63,7 @@ module WPScan
|
||||
def webshot_enabled?
|
||||
res = Browser.get(url, params: { webshot: 1, src: "http://#{default_allowed_domains.sample}" })
|
||||
|
||||
res.body =~ /WEBSHOT_ENABLED == true/ ? false : true
|
||||
/WEBSHOT_ENABLED == true/.match?(res.body) ? false : true
|
||||
end
|
||||
|
||||
# @return [ Array<String> ] The default allowed domains (between the 2.0 and 2.8.13)
|
||||
|
||||
@@ -9,11 +9,12 @@ module WPScan
|
||||
include CMSScanner::Target::Platform::PHP
|
||||
include CMSScanner::Target::Server::Generic
|
||||
|
||||
# Most common readme filenames, based on checking all public plugins and themes.
|
||||
READMES = %w[readme.txt README.txt README.md readme.md Readme.txt].freeze
|
||||
|
||||
attr_reader :uri, :slug, :detection_opts, :version_detection_opts, :blog, :path_from_blog, :db_data
|
||||
|
||||
delegate :homepage_res, :xpath_pattern_from_page, :in_scope_urls, :head_or_get_params, to: :blog
|
||||
delegate :homepage_res, :xpath_pattern_from_page, :in_scope_uris, :head_or_get_params, to: :blog
|
||||
|
||||
# @param [ String ] slug The plugin/theme slug
|
||||
# @param [ Target ] blog The targeted blog
|
||||
@@ -117,7 +118,7 @@ module WPScan
|
||||
|
||||
return @readme_url unless @readme_url.nil?
|
||||
|
||||
READMES.each do |path|
|
||||
potential_readme_filenames.each do |path|
|
||||
t_url = url(path)
|
||||
|
||||
return @readme_url = t_url if Browser.forge_request(t_url, blog.head_or_get_params).run.code == 200
|
||||
@@ -126,6 +127,10 @@ module WPScan
|
||||
@readme_url = false
|
||||
end
|
||||
|
||||
def potential_readme_filenames
|
||||
@potential_readme_filenames ||= READMES
|
||||
end
|
||||
|
||||
# @param [ String ] path
|
||||
# @param [ Hash ] params The request params
|
||||
#
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<%= notice_icon %> Config Backup(s) Identified:
|
||||
<% @config_backups.each do |config_backup| -%>
|
||||
|
||||
<%= info_icon %> <%= config_backup %>
|
||||
<%= critical_icon %> <%= config_backup %>
|
||||
<%= render('@finding', item: config_backup) -%>
|
||||
<% end -%>
|
||||
<% end %>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<%= notice_icon %> Db Export(s) Identified:
|
||||
<% @db_exports.each do |db_export| -%>
|
||||
|
||||
<%= info_icon %> <%= db_export %>
|
||||
<%= critical_icon %> <%= db_export %>
|
||||
<%= render('@finding', item: db_export) -%>
|
||||
<% end -%>
|
||||
<% end %>
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
}<% unless index == last_index %>,<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
},
|
||||
"vulnerabilities": [
|
||||
<% if @item.respond_to?(:vulnerabilities) && !(vulns = @item.vulnerabilities).empty? -%>
|
||||
}
|
||||
<% if @item.respond_to?(:vulnerabilities) -%>
|
||||
,"vulnerabilities": [
|
||||
<% unless (vulns = @item.vulnerabilities).empty? -%>
|
||||
<% last_index = vulns.size - 1 -%>
|
||||
<% vulns.each_with_index do |v, index| -%>
|
||||
{
|
||||
@@ -23,4 +24,5 @@
|
||||
}<% unless index == last_index -%>,<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
]
|
||||
]
|
||||
<% end -%>
|
||||
@@ -19,6 +19,7 @@ require 'wpscan/helper'
|
||||
require 'wpscan/db'
|
||||
require 'wpscan/version'
|
||||
require 'wpscan/errors'
|
||||
require 'wpscan/parsed_cli'
|
||||
require 'wpscan/browser'
|
||||
require 'wpscan/target'
|
||||
require 'wpscan/finders'
|
||||
|
||||
@@ -5,11 +5,6 @@ module WPScan
|
||||
class Browser < CMSScanner::Browser
|
||||
extend Actions
|
||||
|
||||
# @return [ String ] The path to the user agents list
|
||||
def user_agents_list
|
||||
@user_agents_list ||= DB_DIR.join('user-agents.txt').to_s
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def default_user_agent
|
||||
"WPScan v#{VERSION} (https://wpscan.org/)"
|
||||
|
||||
@@ -5,18 +5,19 @@ module WPScan
|
||||
module DynamicFinders
|
||||
class Base
|
||||
# @return [ String ]
|
||||
def self.db_file
|
||||
@db_file ||= DB_DIR.join('dynamic_finders.yml').to_s
|
||||
def self.df_file
|
||||
@df_file ||= DB_DIR.join('dynamic_finders.yml').to_s
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.db_data
|
||||
# true allows aliases to be loaded
|
||||
@db_data ||= YAML.safe_load(File.read(db_file), [Regexp], [], true)
|
||||
def self.all_df_data
|
||||
@all_df_data ||= YAML.safe_load(File.read(df_file), [Regexp])
|
||||
end
|
||||
|
||||
# @return [ Array<Symbol> ]
|
||||
def self.allowed_classes
|
||||
# The Readme is not put in there as it's not a Real DF, but rather using the DF system
|
||||
# to get the list of potential filenames for a given slug
|
||||
@allowed_classes ||= %i[Comment Xpath HeaderPattern BodyPattern JavascriptVar QueryParameter ConfigParser]
|
||||
end
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ module WPScan
|
||||
module DynamicFinders
|
||||
class Plugin < Base
|
||||
# @return [ Hash ]
|
||||
def self.db_data
|
||||
@db_data ||= super['plugins'] || {}
|
||||
def self.df_data
|
||||
@df_data ||= all_df_data['plugins'] || {}
|
||||
end
|
||||
|
||||
def self.version_finder_module
|
||||
@@ -21,7 +21,7 @@ module WPScan
|
||||
|
||||
return configs unless allowed_classes.include?(finder_class)
|
||||
|
||||
db_data.each do |slug, finders|
|
||||
df_data.each do |slug, finders|
|
||||
# Quite sure better can be done with some kind of logic statement in the select
|
||||
fs = if aggressive
|
||||
finders.reject { |_f, c| c['path'].nil? }
|
||||
@@ -48,7 +48,7 @@ module WPScan
|
||||
|
||||
@versions_finders_configs = {}
|
||||
|
||||
db_data.each do |slug, finders|
|
||||
df_data.each do |slug, finders|
|
||||
finders.each do |finder_name, config|
|
||||
next unless config.key?('version')
|
||||
|
||||
@@ -73,23 +73,33 @@ module WPScan
|
||||
version_finder_module.const_get(constant_name)
|
||||
end
|
||||
|
||||
def self.create_versions_finders
|
||||
versions_finders_configs.each do |slug, finders|
|
||||
mod = maybe_create_module(slug)
|
||||
# Create the dynamic finders related to the given slug, and return the created classes
|
||||
#
|
||||
# @param [ String ] slug
|
||||
#
|
||||
# @return [ Array<Class> ] The created classes
|
||||
def self.create_versions_finders(slug)
|
||||
created = []
|
||||
mod = maybe_create_module(slug)
|
||||
|
||||
finders.each do |finder_class, config|
|
||||
klass = config['class'] || finder_class
|
||||
versions_finders_configs[slug]&.each do |finder_class, config|
|
||||
klass = config['class'] || finder_class
|
||||
|
||||
# Instead of raising exceptions, skip unallowed/already defined finders
|
||||
# So that, when new DF configs are put in the .yml
|
||||
# users with old version of WPScan will still be able to scan blogs
|
||||
# when updating the DB but not the tool
|
||||
next if mod.constants.include?(finder_class.to_sym) ||
|
||||
!allowed_classes.include?(klass.to_sym)
|
||||
# Instead of raising exceptions, skip unallowed/already defined finders
|
||||
# So that, when new DF configs are put in the .yml
|
||||
# users with old version of WPScan will still be able to scan blogs
|
||||
# when updating the DB but not the tool
|
||||
|
||||
version_finder_super_class(klass).create_child_class(mod, finder_class.to_sym, config)
|
||||
end
|
||||
next unless allowed_classes.include?(klass.to_sym)
|
||||
|
||||
created << if mod.constants.include?(finder_class.to_sym)
|
||||
mod.const_get(finder_class.to_sym)
|
||||
else
|
||||
version_finder_super_class(klass).create_child_class(mod, finder_class.to_sym, config)
|
||||
end
|
||||
end
|
||||
|
||||
created
|
||||
end
|
||||
|
||||
# The idea here would be to check if the class exist in
|
||||
|
||||
@@ -5,8 +5,8 @@ module WPScan
|
||||
module DynamicFinders
|
||||
class Theme < Plugin
|
||||
# @return [ Hash ]
|
||||
def self.db_data
|
||||
@db_data ||= super['themes'] || {}
|
||||
def self.df_data
|
||||
@df_data ||= all_df_data['themes'] || {}
|
||||
end
|
||||
|
||||
def self.version_finder_module
|
||||
|
||||
@@ -5,8 +5,8 @@ module WPScan
|
||||
module DynamicFinders
|
||||
class Wordpress < Base
|
||||
# @return [ Hash ]
|
||||
def self.db_data
|
||||
@db_data ||= super['wordpress'] || {}
|
||||
def self.df_data
|
||||
@df_data ||= all_df_data['wordpress'] || {}
|
||||
end
|
||||
|
||||
# @return [ Constant ]
|
||||
@@ -30,9 +30,9 @@ module WPScan
|
||||
return configs unless allowed_classes.include?(finder_class)
|
||||
|
||||
finders = if aggressive
|
||||
db_data.reject { |_f, c| c['path'].nil? }
|
||||
df_data.reject { |_f, c| c['path'].nil? }
|
||||
else
|
||||
db_data.select { |_f, c| c['path'].nil? }
|
||||
df_data.select { |_f, c| c['path'].nil? }
|
||||
end
|
||||
|
||||
finders.each do |finder_name, config|
|
||||
@@ -48,7 +48,7 @@ module WPScan
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.versions_finders_configs
|
||||
@versions_finders_configs ||= db_data.select { |_finder_name, config| config.key?('version') }
|
||||
@versions_finders_configs ||= df_data.select { |_finder_name, config| config.key?('version') }
|
||||
end
|
||||
|
||||
def self.create_versions_finders
|
||||
|
||||
@@ -8,11 +8,11 @@ module WPScan
|
||||
# /!\ Might want to also update the Enumeration#cli_options when some filenames are changed here
|
||||
FILES = %w[
|
||||
plugins.json themes.json wordpresses.json
|
||||
timthumbs-v3.txt user-agents.txt config_backups.txt
|
||||
db_exports.txt dynamic_finders.yml wp_fingerprints.json LICENSE
|
||||
timthumbs-v3.txt config_backups.txt db_exports.txt
|
||||
dynamic_finders.yml wp_fingerprints.json LICENSE
|
||||
].freeze
|
||||
|
||||
OLD_FILES = %w[wordpress.db dynamic_finders_01.yml].freeze
|
||||
OLD_FILES = %w[wordpress.db user-agents.txt dynamic_finders_01.yml].freeze
|
||||
|
||||
attr_reader :repo_directory
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ module WPScan
|
||||
end
|
||||
end
|
||||
|
||||
require_relative 'errors/enumeration'
|
||||
require_relative 'errors/http'
|
||||
require_relative 'errors/update'
|
||||
require_relative 'errors/wordpress'
|
||||
|
||||
21
lib/wpscan/errors/enumeration.rb
Normal file
21
lib/wpscan/errors/enumeration.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
module Error
|
||||
class PluginsThresholdReached < Standard
|
||||
def to_s
|
||||
"The number of plugins detected reached the threshold of #{ParsedCli.plugins_threshold} " \
|
||||
'which might indicate False Positive. It would be recommended to use the --exclude-content-based ' \
|
||||
'option to ignore the bad responses.'
|
||||
end
|
||||
end
|
||||
|
||||
class ThemesThresholdReached < Standard
|
||||
def to_s
|
||||
"The number of themes detected reached the threshold of #{ParsedCli.themes_threshold} " \
|
||||
'which might indicate False Positive. It would be recommended to use the --exclude-content-based ' \
|
||||
'option to ignore the bad responses.'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,7 +5,7 @@ module WPScan
|
||||
# WordPress hosted (*.wordpress.com)
|
||||
class WordPressHosted < Standard
|
||||
def to_s
|
||||
'Scanning *.wordpress.com hosted blogs is not supported.'
|
||||
'The target appears to be hosted on WordPress.com. Scanning such site is not supported.'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,7 +25,8 @@ module WPScan
|
||||
|
||||
class WpContentDirNotDetected < Standard
|
||||
def to_s
|
||||
'Unable to identify the wp-content dir, please supply it with --wp-content-dir'
|
||||
'Unable to identify the wp-content dir, please supply it with --wp-content-dir,' \
|
||||
' use the --scope option or make sure the --url value given is the correct one'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ module WPScan
|
||||
module Version
|
||||
# Version finder using Body Pattern method. Tipically used when the response is not
|
||||
# an HTML doc and Xpath can't be used
|
||||
class BodyPattern < WPScan::Finders::DynamicFinder::Version::Finder
|
||||
class BodyPattern < Finders::DynamicFinder::Version::Finder
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(PATTERN: nil, CONFIDENCE: 60)
|
||||
|
||||
@@ -6,7 +6,7 @@ module WPScan
|
||||
module Version
|
||||
# Version finder in Comment, which is basically an Xpath one with a default
|
||||
# Xpath of //comment()
|
||||
class Comment < WPScan::Finders::DynamicFinder::Version::Xpath
|
||||
class Comment < Finders::DynamicFinder::Version::Xpath
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(PATTERN: nil, XPATH: '//comment()')
|
||||
|
||||
@@ -6,7 +6,7 @@ module WPScan
|
||||
module Version
|
||||
# Version finder using by parsing config files, such as composer.json
|
||||
# and so on
|
||||
class ConfigParser < WPScan::Finders::DynamicFinder::Version::Finder
|
||||
class ConfigParser < Finders::DynamicFinder::Version::Finder
|
||||
ALLOWED_PARSERS = [JSON, YAML].freeze
|
||||
|
||||
def self.child_class_constants
|
||||
|
||||
@@ -5,7 +5,7 @@ module WPScan
|
||||
module DynamicFinder
|
||||
module Version
|
||||
# Version finder using Header Pattern method
|
||||
class HeaderPattern < WPScan::Finders::DynamicFinder::Version::Finder
|
||||
class HeaderPattern < Finders::DynamicFinder::Version::Finder
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(HEADER: nil, PATTERN: nil, CONFIDENCE: 60)
|
||||
|
||||
@@ -5,7 +5,7 @@ module WPScan
|
||||
module DynamicFinder
|
||||
module Version
|
||||
# Version finder using JavaScript Variable method
|
||||
class JavascriptVar < WPScan::Finders::DynamicFinder::Version::Finder
|
||||
class JavascriptVar < Finders::DynamicFinder::Version::Finder
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(
|
||||
|
||||
@@ -5,7 +5,7 @@ module WPScan
|
||||
module DynamicFinder
|
||||
module Version
|
||||
# Version finder using QueryParameter method
|
||||
class QueryParameter < WPScan::Finders::DynamicFinder::Version::Finder
|
||||
class QueryParameter < Finders::DynamicFinder::Version::Finder
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(
|
||||
@@ -35,15 +35,13 @@ module WPScan
|
||||
def scan_response(response)
|
||||
found = {}
|
||||
|
||||
target.in_scope_urls(response, xpath) do |url, _tag|
|
||||
uri = Addressable::URI.parse(url)
|
||||
|
||||
target.in_scope_uris(response, xpath) do |uri|
|
||||
next unless uri.path =~ path_pattern && uri.query&.match(self.class::PATTERN)
|
||||
|
||||
version = Regexp.last_match[:v].to_s
|
||||
|
||||
found[version] ||= []
|
||||
found[version] << url
|
||||
found[version] << uri.to_s
|
||||
end
|
||||
|
||||
found
|
||||
|
||||
@@ -5,7 +5,7 @@ module WPScan
|
||||
module DynamicFinder
|
||||
module Version
|
||||
# Version finder using Xpath method
|
||||
class Xpath < WPScan::Finders::DynamicFinder::Version::Finder
|
||||
class Xpath < Finders::DynamicFinder::Version::Finder
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(
|
||||
|
||||
@@ -4,22 +4,22 @@ module WPScan
|
||||
module Finders
|
||||
module DynamicFinder
|
||||
module WpItemVersion
|
||||
class BodyPattern < WPScan::Finders::DynamicFinder::Version::BodyPattern
|
||||
class BodyPattern < Finders::DynamicFinder::Version::BodyPattern
|
||||
end
|
||||
|
||||
class Comment < WPScan::Finders::DynamicFinder::Version::Comment
|
||||
class Comment < Finders::DynamicFinder::Version::Comment
|
||||
end
|
||||
|
||||
class ConfigParser < WPScan::Finders::DynamicFinder::Version::ConfigParser
|
||||
class ConfigParser < Finders::DynamicFinder::Version::ConfigParser
|
||||
end
|
||||
|
||||
class HeaderPattern < WPScan::Finders::DynamicFinder::Version::HeaderPattern
|
||||
class HeaderPattern < Finders::DynamicFinder::Version::HeaderPattern
|
||||
end
|
||||
|
||||
class JavascriptVar < WPScan::Finders::DynamicFinder::Version::JavascriptVar
|
||||
class JavascriptVar < Finders::DynamicFinder::Version::JavascriptVar
|
||||
end
|
||||
|
||||
class QueryParameter < WPScan::Finders::DynamicFinder::Version::QueryParameter
|
||||
class QueryParameter < Finders::DynamicFinder::Version::QueryParameter
|
||||
# @return [ Regexp ]
|
||||
def path_pattern
|
||||
# TODO: consider the target.blog.themes_dir if the target is a Theme (maybe implement a WpItem#item_dir ?)
|
||||
@@ -37,7 +37,7 @@ module WPScan
|
||||
end
|
||||
end
|
||||
|
||||
class Xpath < WPScan::Finders::DynamicFinder::Version::Xpath
|
||||
class Xpath < Finders::DynamicFinder::Version::Xpath
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,23 +12,23 @@ module WPScan
|
||||
end
|
||||
end
|
||||
|
||||
class BodyPattern < WPScan::Finders::DynamicFinder::Version::BodyPattern
|
||||
class BodyPattern < Finders::DynamicFinder::Version::BodyPattern
|
||||
include Finder
|
||||
end
|
||||
|
||||
class Comment < WPScan::Finders::DynamicFinder::Version::Comment
|
||||
class Comment < Finders::DynamicFinder::Version::Comment
|
||||
include Finder
|
||||
end
|
||||
|
||||
class HeaderPattern < WPScan::Finders::DynamicFinder::Version::HeaderPattern
|
||||
class HeaderPattern < Finders::DynamicFinder::Version::HeaderPattern
|
||||
include Finder
|
||||
end
|
||||
|
||||
class JavascriptVar < WPScan::Finders::DynamicFinder::Version::JavascriptVar
|
||||
class JavascriptVar < Finders::DynamicFinder::Version::JavascriptVar
|
||||
include Finder
|
||||
end
|
||||
|
||||
class QueryParameter < WPScan::Finders::DynamicFinder::Version::QueryParameter
|
||||
class QueryParameter < Finders::DynamicFinder::Version::QueryParameter
|
||||
include Finder
|
||||
|
||||
# @return [ Hash ]
|
||||
|
||||
7
lib/wpscan/parsed_cli.rb
Normal file
7
lib/wpscan/parsed_cli.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
# To be able to use ParsedCli directly, rather than having to access it via WPscan::ParsedCli
|
||||
class ParsedCli < CMSScanner::ParsedCli
|
||||
end
|
||||
end
|
||||
@@ -24,8 +24,8 @@ module WPScan
|
||||
#
|
||||
# @return [ Boolean ]
|
||||
def wordpress?(detection_mode)
|
||||
in_scope_urls(homepage_res) do |url|
|
||||
return true if Addressable::URI.parse(url).path.match(WORDPRESS_PATTERN)
|
||||
in_scope_uris(homepage_res) do |uri|
|
||||
return true if uri.path.match(WORDPRESS_PATTERN)
|
||||
end
|
||||
|
||||
homepage_res.html.css('meta[name="generator"]').each do |node|
|
||||
@@ -36,8 +36,8 @@ module WPScan
|
||||
|
||||
if %i[mixed aggressive].include?(detection_mode)
|
||||
%w[wp-admin/install.php wp-login.php].each do |path|
|
||||
in_scope_urls(Browser.get_and_follow_location(url(path))).each do |url|
|
||||
return true if Addressable::URI.parse(url).path.match(WORDPRESS_PATTERN)
|
||||
in_scope_uris(Browser.get_and_follow_location(url(path))).each do |uri|
|
||||
return true if uri.path.match(WORDPRESS_PATTERN)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -45,13 +45,52 @@ module WPScan
|
||||
false
|
||||
end
|
||||
|
||||
COOKIE_PATTERNS = {
|
||||
'vjs' => /createCookie\('vjs','(?<c_value>\d+)',\d+\);/i
|
||||
}.freeze
|
||||
|
||||
# Sometimes there is a mechanism in place on the blog, which requires a specific
|
||||
# cookie and value to be added to requests. Lets try to detect and add them
|
||||
def maybe_add_cookies
|
||||
COOKIE_PATTERNS.each do |cookie_key, pattern|
|
||||
next unless homepage_res.body =~ pattern
|
||||
|
||||
browser = Browser.instance
|
||||
|
||||
cookie_string = "#{cookie_key}=#{Regexp.last_match[:c_value]}"
|
||||
|
||||
cookie_string += "; #{browser.cookie_string}" if browser.cookie_string
|
||||
|
||||
browser.cookie_string = cookie_string
|
||||
|
||||
# Force recheck of the homepage when retying wordpress?
|
||||
# No need to clear the cache, as the request (which will contain the cookies)
|
||||
# will be different
|
||||
@homepage_res = nil
|
||||
@homepage_url = nil
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def registration_url
|
||||
multisite? ? url('wp-signup.php') : url('wp-login.php?action=register')
|
||||
end
|
||||
|
||||
# @return [ Boolean ] Whether or not the target is hosted on wordpress.com
|
||||
def wordpress_hosted?
|
||||
uri.host =~ /\.wordpress\.com$/i ? true : false
|
||||
return true if /\.wordpress\.com$/i.match?(uri.host)
|
||||
|
||||
unless content_dir(:passive)
|
||||
pattern = %r{https?://s\d\.wp\.com#{WORDPRESS_PATTERN}}i.freeze
|
||||
|
||||
uris_from_page(homepage_res) do |uri|
|
||||
return true if uri.to_s.match?(pattern)
|
||||
end
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
# @param [ String ] username
|
||||
|
||||
@@ -13,24 +13,36 @@ module WPScan
|
||||
@plugins_dir = dir.chomp('/')
|
||||
end
|
||||
|
||||
# @param [ Symbol ] detection_mode
|
||||
# @return [ String ] The wp-content directory
|
||||
def content_dir
|
||||
def content_dir(detection_mode = :mixed)
|
||||
unless @content_dir
|
||||
escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
|
||||
pattern = %r{#{escaped_url}([\w\s\-\/]+)\/(?:themes|plugins|uploads|cache)\/}i
|
||||
# scope_url_pattern is from CMSScanner::Target
|
||||
pattern = %r{#{scope_url_pattern}([\w\s\-/]+)\\?/(?:themes|plugins|uploads|cache)\\?/}i
|
||||
|
||||
in_scope_urls(homepage_res) do |url|
|
||||
return @content_dir = Regexp.last_match[1] if url.match(pattern)
|
||||
in_scope_uris(homepage_res) do |uri|
|
||||
return @content_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
|
||||
end
|
||||
|
||||
xpath_pattern_from_page('//script[not(@src)]', pattern, homepage_res) do |match|
|
||||
# Checks for the pattern in raw JS code, as well as @content attributes of meta tags
|
||||
xpath_pattern_from_page('//script[not(@src)]|//meta/@content', pattern, homepage_res) do |match|
|
||||
return @content_dir = match[1]
|
||||
end
|
||||
|
||||
unless detection_mode == :passive
|
||||
return @content_dir = 'wp-content' if default_content_dir_exists?
|
||||
end
|
||||
end
|
||||
|
||||
@content_dir
|
||||
end
|
||||
|
||||
def default_content_dir_exists?
|
||||
# url('wp-content') can't be used here as the folder has not yet been identified
|
||||
# and the method would try to replace it by nil which would raise an error
|
||||
[200, 401, 403].include?(Browser.forge_request(uri.join('wp-content/').to_s, head_or_get_params).run.code)
|
||||
end
|
||||
|
||||
# @return [ Addressable::URI ]
|
||||
def content_uri
|
||||
uri.join("#{content_dir}/")
|
||||
@@ -85,23 +97,21 @@ module WPScan
|
||||
themes_uri.join("#{URI.encode(slug)}/").to_s
|
||||
end
|
||||
|
||||
# TODO: Factorise the code and the content_dir one ?
|
||||
# @return [ String, False ] String of the sub_dir found, false otherwise
|
||||
# @note: nil can not be returned here, otherwise if there is no sub_dir
|
||||
# the check would be done each time
|
||||
# the check would be done each time, which would make enumeration of
|
||||
# long list of items very slow to generate
|
||||
def sub_dir
|
||||
unless @sub_dir
|
||||
escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
|
||||
pattern = %r{#{escaped_url}(.+?)\/(?:xmlrpc\.php|wp\-includes\/)}i
|
||||
return @sub_dir unless @sub_dir.nil?
|
||||
|
||||
in_scope_urls(homepage_res) do |url|
|
||||
return @sub_dir = Regexp.last_match[1] if url.match(pattern)
|
||||
end
|
||||
# url_pattern is from CMSScanner::Target
|
||||
pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp\-includes/)}i
|
||||
|
||||
@sub_dir = false
|
||||
in_scope_uris(homepage_res) do |uri|
|
||||
return @sub_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
|
||||
end
|
||||
|
||||
@sub_dir
|
||||
@sub_dir = false
|
||||
end
|
||||
|
||||
# Override of the WebSite#url to consider the custom WP directories
|
||||
@@ -112,9 +122,9 @@ module WPScan
|
||||
def url(path = nil)
|
||||
return @uri.to_s unless path
|
||||
|
||||
if path =~ %r{wp\-content/plugins}i
|
||||
if %r{wp\-content/plugins}i.match?(path)
|
||||
path = +path.gsub('wp-content/plugins', plugins_dir)
|
||||
elsif path =~ /wp\-content/i
|
||||
elsif /wp\-content/i.match?(path)
|
||||
path = +path.gsub('wp-content', content_dir)
|
||||
elsif path[0] != '/' && sub_dir
|
||||
path = "#{sub_dir}/#{path}"
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
# Version
|
||||
module WPScan
|
||||
VERSION = '3.5.0'
|
||||
VERSION = '3.6.0'
|
||||
end
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
describe WPScan::Controller::Aliases do
|
||||
subject(:controller) { described_class.new }
|
||||
let(:target_url) { 'http://ex.lo/' }
|
||||
let(:parsed_options) { rspec_parsed_options(cli_args) }
|
||||
let(:cli_args) { "--url #{target_url}" }
|
||||
|
||||
before do
|
||||
WPScan::Browser.reset
|
||||
described_class.parsed_options = parsed_options
|
||||
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
|
||||
end
|
||||
|
||||
describe '#cli_options' do
|
||||
@@ -22,14 +20,18 @@ describe WPScan::Controller::Aliases do
|
||||
|
||||
describe 'parsed_options' do
|
||||
context 'when no --stealthy supplied' do
|
||||
its(:parsed_options) { should eql parsed_options }
|
||||
it 'contains the correct options' do
|
||||
expect(WPScan::ParsedCli.options).to include(
|
||||
detection_mode: :mixed, plugins_version_detection: :mixed
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when --stealthy supplied' do
|
||||
let(:cli_args) { "#{super()} --stealthy" }
|
||||
|
||||
it 'contains the correct options' do
|
||||
expect(controller.parsed_options).to include(
|
||||
expect(WPScan::ParsedCli.options).to include(
|
||||
random_user_agent: true, detection_mode: :passive, plugins_version_detection: :passive
|
||||
)
|
||||
end
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
describe WPScan::Controller::Core do
|
||||
subject(:core) { described_class.new }
|
||||
let(:target_url) { 'http://ex.lo/' }
|
||||
let(:parsed_options) { rspec_parsed_options(cli_args) }
|
||||
let(:cli_args) { "--url #{target_url}" }
|
||||
|
||||
before do
|
||||
WPScan::Browser.reset
|
||||
described_class.reset
|
||||
described_class.parsed_options = parsed_options
|
||||
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
|
||||
end
|
||||
|
||||
describe '#cli_options' do
|
||||
@@ -140,7 +138,7 @@ describe WPScan::Controller::Core do
|
||||
|
||||
expect(core.formatter).to receive(:output).with('banner', hash_including(verbose: nil), 'core')
|
||||
|
||||
expect(core).to receive(:update_db_required?).and_return(false) unless parsed_options[:update]
|
||||
expect(core).to receive(:update_db_required?).and_return(false) unless WPScan::ParsedCli.update
|
||||
end
|
||||
|
||||
context 'when --update' do
|
||||
@@ -218,7 +216,7 @@ describe WPScan::Controller::Core do
|
||||
|
||||
context 'when not wordpress' do
|
||||
it 'raises an error' do
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
|
||||
expect(core.target).to receive(:wordpress?).twice.with(:mixed).and_return(false)
|
||||
|
||||
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
|
||||
end
|
||||
@@ -250,12 +248,26 @@ describe WPScan::Controller::Core do
|
||||
context 'when not wordpress' do
|
||||
before do
|
||||
expect(core).to receive(:load_server_module)
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
|
||||
end
|
||||
|
||||
context 'when no --force' do
|
||||
it 'raises an error' do
|
||||
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
|
||||
before { expect(core.target).to receive(:maybe_add_cookies) }
|
||||
|
||||
context 'when no cookies added or still not wordpress after being added' do
|
||||
it 'raises an error' do
|
||||
expect(core.target).to receive(:wordpress?).twice.with(:mixed).and_return(false)
|
||||
|
||||
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the added cookies solved it' do
|
||||
it 'does not raise an error' do
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false).ordered
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true).ordered
|
||||
|
||||
expect { core.before_scan }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -263,6 +275,8 @@ describe WPScan::Controller::Core do
|
||||
let(:cli_args) { "#{super()} --force" }
|
||||
|
||||
it 'does not raise any error' do
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
|
||||
|
||||
expect { core.before_scan }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
describe WPScan::Controller::CustomDirectories do
|
||||
subject(:controller) { described_class.new }
|
||||
let(:target_url) { 'http://ex.lo/' }
|
||||
let(:parsed_options) { rspec_parsed_options(cli_args) }
|
||||
let(:cli_args) { "--url #{target_url}" }
|
||||
|
||||
before do
|
||||
WPScan::Browser.reset
|
||||
described_class.parsed_options = parsed_options
|
||||
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
|
||||
end
|
||||
|
||||
describe '#cli_options' do
|
||||
@@ -21,8 +19,8 @@ describe WPScan::Controller::CustomDirectories do
|
||||
end
|
||||
|
||||
describe '#before_scan' do
|
||||
context 'when the content_dir is not found and not supply' do
|
||||
before { expect(controller.target).to receive(:content_dir) }
|
||||
context 'when the content_dir is not found and not supplied' do
|
||||
before { expect(controller.target).to receive(:content_dir).with(:mixed) }
|
||||
|
||||
it 'raises an exception' do
|
||||
expect { controller.before_scan }.to raise_error(WPScan::Error::WpContentDirNotDetected)
|
||||
@@ -34,7 +32,7 @@ describe WPScan::Controller::CustomDirectories do
|
||||
|
||||
it 'does not raise any error' do
|
||||
expect { controller.before_scan }.to_not raise_error
|
||||
expect(controller.target.content_dir).to eq parsed_options[:wp_content_dir]
|
||||
expect(controller.target.content_dir).to eq WPScan::ParsedCli.wp_content_dir
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,16 +3,13 @@
|
||||
describe WPScan::Controller::Enumeration do
|
||||
subject(:controller) { described_class.new }
|
||||
let(:target_url) { 'http://wp.lab/' }
|
||||
let(:parsed_options) { rspec_parsed_options(cli_args) }
|
||||
let(:cli_args) { "--url #{target_url}" }
|
||||
|
||||
before do
|
||||
WPScan::Browser.reset
|
||||
|
||||
## For the --passwords options
|
||||
allow_any_instance_of(OptParseValidator::OptPath).to receive(:check_file)
|
||||
|
||||
described_class.parsed_options = parsed_options
|
||||
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
|
||||
end
|
||||
|
||||
describe '#enum_message' do
|
||||
@@ -73,8 +70,8 @@ describe WPScan::Controller::Enumeration do
|
||||
it 'contains the correct options' do
|
||||
expect(controller.cli_options.map(&:to_sym)).to eql(
|
||||
%i[enumerate exclude_content_based
|
||||
plugins_list plugins_detection plugins_version_all plugins_version_detection
|
||||
themes_list themes_detection themes_version_all themes_version_detection
|
||||
plugins_list plugins_detection plugins_version_all plugins_version_detection plugins_threshold
|
||||
themes_list themes_detection themes_version_all themes_version_detection themes_threshold
|
||||
timthumbs_list timthumbs_detection
|
||||
config_backups_list config_backups_detection
|
||||
db_exports_list db_exports_detection
|
||||
@@ -105,22 +102,13 @@ describe WPScan::Controller::Enumeration do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#before_scan' do
|
||||
it 'creates the Dynamic Finders' do
|
||||
expect(WPScan::DB::DynamicFinders::Plugin).to receive(:create_versions_finders)
|
||||
expect(WPScan::DB::DynamicFinders::Theme).to receive(:create_versions_finders)
|
||||
|
||||
controller.before_scan
|
||||
end
|
||||
end
|
||||
|
||||
describe '#run' do
|
||||
context 'when no :enumerate' do
|
||||
before do
|
||||
expect(controller).to receive(:enum_plugins)
|
||||
expect(controller).to receive(:enum_config_backups)
|
||||
|
||||
expect(parsed_options[:plugins_detection]).to eql :passive
|
||||
expect(WPScan::ParsedCli.plugins_detection).to eql :passive
|
||||
end
|
||||
|
||||
it 'calls enum_plugins and enum_config_backups' do
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
describe WPScan::Controller::PasswordAttack do
|
||||
subject(:controller) { described_class.new }
|
||||
let(:target_url) { 'http://ex.lo/' }
|
||||
let(:parsed_options) { rspec_parsed_options(cli_args) }
|
||||
let(:cli_args) { "--url #{target_url}" }
|
||||
|
||||
before do
|
||||
WPScan::Browser.reset
|
||||
described_class.parsed_options = parsed_options
|
||||
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
|
||||
end
|
||||
|
||||
describe '#cli_options' do
|
||||
@@ -54,6 +52,60 @@ describe WPScan::Controller::PasswordAttack do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#xmlrpc_get_users_blogs_enabled?' do
|
||||
before { expect(controller.target).to receive(:xmlrpc).and_return(xmlrpc) }
|
||||
|
||||
context 'when xmlrpc not found' do
|
||||
let(:xmlrpc) { nil }
|
||||
|
||||
its(:xmlrpc_get_users_blogs_enabled?) { should be false }
|
||||
end
|
||||
|
||||
context 'when xmlrpc not enabled' do
|
||||
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php") }
|
||||
|
||||
it 'returns false' do
|
||||
expect(xmlrpc).to receive(:enabled?).and_return(false)
|
||||
|
||||
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when xmlrpc enabled' do
|
||||
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php") }
|
||||
|
||||
before { expect(xmlrpc).to receive(:enabled?).and_return(true) }
|
||||
|
||||
context 'when wp.getUsersBlogs methods not listed' do
|
||||
it 'returns false' do
|
||||
expect(xmlrpc).to receive(:available_methods).and_return(%w[m1 m2])
|
||||
|
||||
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when wp.getUsersBlogs method listed' do
|
||||
before { expect(xmlrpc).to receive(:available_methods).and_return(%w[wp.getUsersBlogs m2]) }
|
||||
|
||||
context 'when wp.getUsersBlogs method disabled' do
|
||||
it 'returns false' do
|
||||
stub_request(:post, xmlrpc.url).to_return(body: 'XML-RPC services are disabled on this site.')
|
||||
|
||||
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when wp.getUsersBlogs method enabled' do
|
||||
it 'returns true' do
|
||||
stub_request(:post, xmlrpc.url).to_return(body: 'Incorrect username or password.')
|
||||
|
||||
expect(controller.xmlrpc_get_users_blogs_enabled?).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#attacker' do
|
||||
context 'when --password-attack provided' do
|
||||
let(:cli_args) { "#{super()} --password-attack #{attack}" }
|
||||
@@ -94,7 +146,7 @@ describe WPScan::Controller::PasswordAttack do
|
||||
before do
|
||||
expect(controller.target)
|
||||
.to receive(:xmlrpc)
|
||||
.and_return(WPScan::Model::XMLRPC.new("#{target_url}/xmlrpc.php"))
|
||||
.and_return(WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php"))
|
||||
end
|
||||
|
||||
context 'when single xmlrpc' do
|
||||
@@ -119,73 +171,50 @@ describe WPScan::Controller::PasswordAttack do
|
||||
end
|
||||
|
||||
context 'when automatic detection' do
|
||||
before { expect(controller.target).to receive(:xmlrpc).and_return(xmlrpc) }
|
||||
|
||||
context 'when xmlrpc not found' do
|
||||
let(:xmlrpc) { nil }
|
||||
|
||||
context 'when xmlrpc_get_users_blogs_enabled? is false' do
|
||||
it 'returns the WpLogin' do
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
||||
expect(controller.attacker.target).to be_a WPScan::Target
|
||||
end
|
||||
end
|
||||
|
||||
context 'when xmlrpc not enabled' do
|
||||
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}/xmlrpc.php") }
|
||||
|
||||
it 'returns the WpLogin' do
|
||||
expect(xmlrpc).to receive(:enabled?).and_return(false)
|
||||
expect(controller).to receive(:xmlrpc_get_users_blogs_enabled?).and_return(false)
|
||||
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
||||
expect(controller.attacker.target).to be_a WPScan::Target
|
||||
end
|
||||
end
|
||||
|
||||
context 'when xmlrpc enabled' do
|
||||
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}/xmlrpc.php") }
|
||||
context 'when xmlrpc_get_users_blogs_enabled? is true' do
|
||||
before do
|
||||
expect(controller).to receive(:xmlrpc_get_users_blogs_enabled?).and_return(true)
|
||||
|
||||
before { expect(xmlrpc).to receive(:enabled?).and_return(true) }
|
||||
expect(controller.target)
|
||||
.to receive(:xmlrpc).and_return(WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php"))
|
||||
end
|
||||
|
||||
context 'when wp.getUsersBlogs methods not available' do
|
||||
it 'returns the WpLogin' do
|
||||
expect(xmlrpc).to receive(:available_methods).and_return(%w[m1 m2])
|
||||
context 'when WP version not found' do
|
||||
it 'returns the XMLRPC' do
|
||||
expect(controller.target).to receive(:wp_version).and_return(false)
|
||||
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
||||
expect(controller.attacker.target).to be_a WPScan::Target
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
|
||||
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
||||
end
|
||||
end
|
||||
|
||||
context 'when wp.getUsersBlogs method evailable' do
|
||||
before { expect(xmlrpc).to receive(:available_methods).and_return(%w[wp.getUsersBlogs m2]) }
|
||||
context 'when WP version found' do
|
||||
before { expect(controller.target).to receive(:wp_version).and_return(wp_version) }
|
||||
|
||||
context 'when WP version not found' do
|
||||
it 'returns the XMLRPC' do
|
||||
expect(controller.target).to receive(:wp_version).and_return(false)
|
||||
context 'when WP < 4.4' do
|
||||
let(:wp_version) { WPScan::Model::WpVersion.new('3.8.1') }
|
||||
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
|
||||
it 'returns the XMLRPCMulticall' do
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPCMulticall
|
||||
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
||||
end
|
||||
end
|
||||
|
||||
context 'when WP version found' do
|
||||
before { expect(controller.target).to receive(:wp_version).and_return(wp_version) }
|
||||
context 'when WP >= 4.4' do
|
||||
let(:wp_version) { WPScan::Model::WpVersion.new('4.4') }
|
||||
|
||||
context 'when WP < 4.4' do
|
||||
let(:wp_version) { WPScan::Model::WpVersion.new('3.8.1') }
|
||||
|
||||
it 'returns the XMLRPCMulticall' do
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPCMulticall
|
||||
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
||||
end
|
||||
end
|
||||
|
||||
context 'when WP >= 4.4' do
|
||||
let(:wp_version) { WPScan::Model::WpVersion.new('4.4') }
|
||||
|
||||
it 'returns the XMLRPC' do
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
|
||||
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
||||
end
|
||||
it 'returns the XMLRPC' do
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
|
||||
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,12 +24,10 @@ end
|
||||
describe WPScan::Controller::WpVersion do
|
||||
subject(:controller) { described_class.new }
|
||||
let(:target_url) { 'http://ex.lo/' }
|
||||
let(:parsed_options) { rspec_parsed_options(cli_args) }
|
||||
let(:cli_args) { "--url #{target_url}" }
|
||||
|
||||
before do
|
||||
WPScan::Browser.reset
|
||||
described_class.parsed_options = parsed_options
|
||||
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
|
||||
end
|
||||
|
||||
describe '#cli_options' do
|
||||
@@ -46,8 +44,8 @@ describe WPScan::Controller::WpVersion do
|
||||
expect(controller.target).to receive(:wp_version)
|
||||
.with(
|
||||
hash_including(
|
||||
mode: parsed_options[:wp_version_detection] || parsed_options[:detection_mode],
|
||||
confidence_threshold: parsed_options[:wp_version_all] ? 0 : 100
|
||||
mode: WPScan::ParsedCli.wp_version_detection || WPScan::ParsedCli.detection_mode,
|
||||
confidence_threshold: WPScan::ParsedCli.wp_version_all ? 0 : 100
|
||||
)
|
||||
).and_return(stubbed)
|
||||
end
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# If this file is tested alone (rspec path-to-this-file), then there will be an error about
|
||||
# constants not being intilialized. This is due to the Dynamic Finders.
|
||||
|
||||
describe WPScan::Finders::PluginVersion::Base do
|
||||
subject(:plugin_version) { described_class.new(plugin) }
|
||||
let(:plugin) { WPScan::Model::Plugin.new(slug, target) }
|
||||
@@ -15,7 +12,7 @@ describe WPScan::Finders::PluginVersion::Base do
|
||||
expect(plugin_version.finders.map { |f| f.class.to_s.demodulize }).to match_array @expected
|
||||
end
|
||||
|
||||
context 'when no related specific finders' do
|
||||
context 'when no related dynamic finders' do
|
||||
let(:slug) { 'spec' }
|
||||
|
||||
it 'contains the default finders' do
|
||||
@@ -25,19 +22,13 @@ describe WPScan::Finders::PluginVersion::Base do
|
||||
|
||||
# Dynamic Version Finders are not tested here, they are in
|
||||
# spec/lib/finders/dynamic_finder/plugin_versions_spec
|
||||
context 'when specific finders' do
|
||||
let(:specific) do
|
||||
{
|
||||
# None so far
|
||||
}
|
||||
end
|
||||
|
||||
context 'when dynamic finders' do
|
||||
WPScan::DB::DynamicFinders::Plugin.versions_finders_configs.each do |plugin_slug, configs|
|
||||
context "when #{plugin_slug} plugin" do
|
||||
let(:slug) { plugin_slug }
|
||||
|
||||
it 'contains the expected finders (default + specific + the dynamic ones)' do
|
||||
@expected = default_finders + [*specific[plugin_slug]] + configs.keys
|
||||
it 'contains the expected finders (default + the dynamic ones)' do
|
||||
@expected = default_finders + configs.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,20 +13,21 @@ describe WPScan::Finders::ThemeVersion::Base do
|
||||
expect(theme_version.finders.map { |f| f.class.to_s.demodulize }).to eql @expected
|
||||
end
|
||||
|
||||
context 'when no related specific finders' do
|
||||
context 'when no related dynamic finders' do
|
||||
it 'contains the default finders' do
|
||||
@expected = default_finders
|
||||
end
|
||||
end
|
||||
|
||||
context 'when specific finders' do
|
||||
{
|
||||
}.each do |theme_slug, specific_finders|
|
||||
# Dynamic Version Finders are not tested here, they are in
|
||||
# spec/lib/finders/dynamic_finder/theme_versions_spec
|
||||
context 'when dynamic finders' do
|
||||
WPScan::DB::DynamicFinders::Theme.versions_finders_configs.each do |theme_slug, configs|
|
||||
context "when #{theme_slug} theme" do
|
||||
let(:slug) { theme_slug }
|
||||
|
||||
it 'contains the expected finders' do
|
||||
@expected = default_finders + specific_finders
|
||||
it 'contains the expected finders (default + the dynamic ones)' do
|
||||
@expected = default_finders + configs.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,6 +60,26 @@ describe WPScan::Model::Plugin do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'potential_readme_filenames' do
|
||||
context 'when not set in the DF file' do
|
||||
its(:potential_readme_filenames) { should eql described_class::READMES }
|
||||
end
|
||||
|
||||
context 'when set in the DF file' do
|
||||
context 'as a string' do
|
||||
let(:slug) { 'photoblocks-grid-gallery' }
|
||||
|
||||
its(:potential_readme_filenames) { should eql %w[README.txt] }
|
||||
end
|
||||
|
||||
context 'as an array' do
|
||||
let(:slug) { 'customerlabs-actionrecorder' }
|
||||
|
||||
its(:potential_readme_filenames) { should eql %w[Readme.txt Readme.md] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#latest_version, #last_updated, #popular' do
|
||||
context 'when none' do
|
||||
let(:slug) { 'vulnerable-not-popular' }
|
||||
|
||||
@@ -16,7 +16,7 @@ describe 'App::Views' do
|
||||
let(:parsed_options) { { url: target_url, format: formatter.to_s.underscore.dasherize } }
|
||||
|
||||
before do
|
||||
controller.class.parsed_options = parsed_options
|
||||
WPScan::ParsedCli.options = parsed_options
|
||||
# Resets the formatter to ensure the correct one is loaded
|
||||
controller.class.class_variable_set(:@@formatter, nil)
|
||||
end
|
||||
|
||||
6218
spec/fixtures/db/dynamic_finders.yml
vendored
6218
spec/fixtures/db/dynamic_finders.yml
vendored
File diff suppressed because it is too large
Load Diff
3
spec/fixtures/db/user-agents.txt
vendored
3
spec/fixtures/db/user-agents.txt
vendored
@@ -1,3 +0,0 @@
|
||||
# Coments should be ignored
|
||||
UA-1
|
||||
UA-2
|
||||
3101
spec/fixtures/dynamic_finders/expected.yml
vendored
3101
spec/fixtures/dynamic_finders/expected.yml
vendored
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
# Copyright (C) 2019 Jörn Lund
|
||||
# This file is distributed under the same license as the ACF Dropzone plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ACF Dropzone 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/acf-dropzone\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-07-04T10:29:43+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.1.0\n"
|
||||
"X-Domain: acf-dropzone\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "ACF Dropzone"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://github.com/mcguffin/acf-dropzone"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Drag and drop file upload for ACF-Fields."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Jörn Lund"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://github.com/mcguffin"
|
||||
msgstr ""
|
||||
|
||||
#: include/AcfDropzone/Compat/ACF.php:47
|
||||
#: tmp/svn/tags/1.0.0/include/AcfDropzone/Compat/ACF.php:47
|
||||
#: tmp/svn/trunk/include/AcfDropzone/Compat/ACF.php:47
|
||||
#: tmp/git/include/AcfDropzone/Compat/ACF.php:47
|
||||
msgid "Enable Dropzone"
|
||||
msgstr ""
|
||||
|
||||
#: include/AcfDropzone/Compat/ACF.php:103
|
||||
#: tmp/svn/tags/1.0.0/include/AcfDropzone/Compat/ACF.php:103
|
||||
#: tmp/svn/trunk/include/AcfDropzone/Compat/ACF.php:103
|
||||
#: tmp/git/include/AcfDropzone/Compat/ACF.php:103
|
||||
msgid "Dismiss this notice."
|
||||
msgstr ""
|
||||
|
||||
#: include/AcfDropzone/Compat/ACF.php:107
|
||||
#: tmp/svn/tags/1.0.0/include/AcfDropzone/Compat/ACF.php:107
|
||||
#: tmp/svn/trunk/include/AcfDropzone/Compat/ACF.php:107
|
||||
#: tmp/git/include/AcfDropzone/Compat/ACF.php:107
|
||||
msgid "Drop files here"
|
||||
msgstr ""
|
||||
|
||||
#: include/AcfDropzone/Compat/ACF.php:108
|
||||
#: tmp/svn/tags/1.0.0/include/AcfDropzone/Compat/ACF.php:108
|
||||
#: tmp/svn/trunk/include/AcfDropzone/Compat/ACF.php:108
|
||||
#: tmp/git/include/AcfDropzone/Compat/ACF.php:108
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,225 @@
|
||||
# Copyright (C) 2019 Jörn Lund
|
||||
# This file is distributed under the same license as the ACF OpenStreetMap Field plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ACF OpenStreetMap Field 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/acf-field-openstreetmap\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-07-05T08:37:19+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.1.0\n"
|
||||
"X-Domain: acf-openstreetmap-field\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "ACF OpenStreetMap Field"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://wordpress.org/plugins/acf-openstreetmap-field"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "A configurable OpenStreetMap Field for ACF."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Jörn Lund"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://github.com/mcguffin"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
msgid "OpenStreetMap Settings"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:51
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:51
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:51
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:51
|
||||
msgid "OpenStreetMap"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:51
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:51
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:51
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:51
|
||||
msgid "acf-openstreetmap-field Settings"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:57
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:57
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:57
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:57
|
||||
msgid "Save Settings"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:86
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:86
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:86
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:86
|
||||
msgid "Access Tokens"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:139
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:139
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:139
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:139
|
||||
msgid "Enter Access Tokens for various Map Tile providers."
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:125
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:125
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:125
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:125
|
||||
msgid "Raw Data"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:126
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:126
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:126
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:126
|
||||
msgid "Leaflet JS"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:127
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:127
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:127
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:127
|
||||
msgid "iFrame (OpenStreetMap.org)"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:146
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:146
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:146
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:146
|
||||
msgid "Map Appearance"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:147
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:147
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:147
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:147
|
||||
msgid "Set zoom, center and select layers being displayed."
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:167
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:167
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:167
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:167
|
||||
msgid "Map Position"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:168
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:179
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:168
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:179
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:168
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:179
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:168
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:179
|
||||
msgid "Center the initial map"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:171
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:171
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:171
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:171
|
||||
msgid "lat"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:178
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:178
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:178
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:178
|
||||
msgid "Center"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:182
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:182
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:182
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:182
|
||||
msgid "lng"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:190
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:190
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:190
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:190
|
||||
msgid "Zoom"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:191
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:191
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:191
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:191
|
||||
msgid "Set the initial zoom level"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:196
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:196
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:196
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:196
|
||||
msgid "zoom"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:203
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:203
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:203
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:203
|
||||
msgid "Allow layer selection"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:213
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:213
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:213
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:213
|
||||
msgid "Customise the map height"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:222
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:222
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:222
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:222
|
||||
msgid "Max. number of Markers"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:223
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:223
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:223
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:223
|
||||
msgid "Leave empty for infinite markers"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:380
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:380
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:380
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:380
|
||||
msgid "Locate Marker"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:407
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:407
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:407
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:407
|
||||
msgid "Remove Marker"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:734
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:734
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:734
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:734
|
||||
msgid "View Larger Map"
|
||||
msgstr ""
|
||||
37
spec/fixtures/dynamic_finders/plugin_version/acf-options-for-polylang/change_log/CHANGELOG.md
vendored
Normal file
37
spec/fixtures/dynamic_finders/plugin_version/acf-options-for-polylang/change_log/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# Changelog
|
||||
|
||||
## 1.1.6 - 19 Mar 2019
|
||||
* FIX [#32](https://github.com/BeAPI/acf-options-for-polylang/issues/32) & [#40](https://github.com/BeAPI/acf-options-for-polylang/issues/40) : fix `get_field()` if an object is provided (WP Term, WP Post, WP Comment)
|
||||
|
||||
## 1.1.5 - 11 Dec 2018
|
||||
* FIX wrong constant
|
||||
|
||||
## 1.1.4 - 13 Nov 2018
|
||||
* Refactor by adding the Helpers class
|
||||
* FEATURE [#26](https://github.com/BeAPI/acf-options-for-polylang/issues/26) : allow to precise to show or hide default values for a specific option page
|
||||
* FEATURE [#21](https://github.com/BeAPI/acf-options-for-polylang/pull/21) : handle custom option id
|
||||
|
||||
## 1.1.3 - 2 Aug 2018
|
||||
* FEATURE [#23](https://github.com/BeAPI/acf-options-for-polylang/pull/23) : requirement to php5.6 whereas namespace are 5.3
|
||||
|
||||
## 1.1.2 - 31 Jul 2018
|
||||
* FIX [#22](https://github.com/BeAPI/acf-options-for-polylang/pull/22) : error with repeater fields default values
|
||||
|
||||
## 1.1.1 - 9 Mai 2018
|
||||
* FIX [#15](https://github.com/BeAPI/acf-options-for-polylang/issues/15) : way requirements are checked to trigger on front / admin
|
||||
|
||||
## 1.1.0 - Mar 2018
|
||||
* True (complet) plugin.
|
||||
* Add check for ACF 5.6.
|
||||
|
||||
## 1.0.2 - 23 Dec 2017
|
||||
* Refactor and reformat.
|
||||
* Handle all options page and custom post_id.
|
||||
* Now load only if ACF & Polylang are activated.
|
||||
* Load later at plugins loaded.
|
||||
|
||||
## 1.0.1 - 19 Sep 2016
|
||||
* Plugin update.
|
||||
|
||||
## 1.0.0 - 8 Mar 2016
|
||||
* Init plugin.
|
||||
146
spec/fixtures/dynamic_finders/plugin_version/admin-atlex-cloud/translation_file/languages/ru_RU.pot
vendored
Normal file
146
spec/fixtures/dynamic_finders/plugin_version/admin-atlex-cloud/translation_file/languages/ru_RU.pot
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) 2019 Atlex
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Atlex developer@atlex.ru, 2019.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Admin Atlex Cloud Plugin 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-03-05 21:53+0400\n"
|
||||
"PO-Revision-Date: 2019-03-20 21:53+0400\n"
|
||||
"Last-Translator: ATLEX developer@atlex.ru\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: ru_RU\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
|
||||
#msgfmt ru_RU.pot --output-file=ru_RU.mo
|
||||
|
||||
msgid "Host"
|
||||
msgstr "Адрес"
|
||||
|
||||
msgid "Cloud Adapter"
|
||||
msgstr "Тип Адаптера"
|
||||
|
||||
msgid "Project"
|
||||
msgstr "Проект"
|
||||
|
||||
msgid "User"
|
||||
msgstr "Пользователь"
|
||||
|
||||
msgid "Password"
|
||||
msgstr "Пароль"
|
||||
|
||||
msgid "Backup Container"
|
||||
msgstr "Удаленный Контейнер"
|
||||
|
||||
msgid "Local Directory"
|
||||
msgstr "Локальный Каталог"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Сохранить"
|
||||
|
||||
msgid "Atlex Cloud Settings"
|
||||
msgstr "Настройки Облака Атлекс"
|
||||
|
||||
msgid "Cloud Tools"
|
||||
msgstr "Инструменты Облака"
|
||||
|
||||
msgid "Settings"
|
||||
msgstr "Настройки"
|
||||
|
||||
msgid "Atlex Cloud"
|
||||
msgstr "Атлекс Облако"
|
||||
|
||||
msgid "Atlex Settings"
|
||||
msgstr "Атлекс Настройки"
|
||||
|
||||
msgid "Backup Batabase"
|
||||
msgstr "Резервная Копия Базы Данных"
|
||||
|
||||
msgid "Archive Name"
|
||||
msgstr "Имя Архива"
|
||||
|
||||
msgid "Backup"
|
||||
msgstr "Резервная Копия"
|
||||
|
||||
msgid "Remote Archive"
|
||||
msgstr "Удаленный Архив"
|
||||
|
||||
msgid "Restore"
|
||||
msgstr "Восстановить"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Удалить"
|
||||
|
||||
msgid "Backup Wordpress Files"
|
||||
msgstr "Резервная Копия Wordpress Файлов"
|
||||
|
||||
msgid "Wordpress Directory"
|
||||
msgstr "Директория Wordpress"
|
||||
|
||||
msgid "Cloud Directory Name"
|
||||
msgstr "Имя каталога в облаке"
|
||||
|
||||
msgid "Remote Directories Archive"
|
||||
msgstr "Удаленный Архив Каталогов"
|
||||
|
||||
msgid "Download"
|
||||
msgstr "Скачать"
|
||||
|
||||
msgid "You need configurate cloud setting for connection"
|
||||
msgstr "Вам необходимо настроить параметры облака для подключения"
|
||||
|
||||
msgid "Loading"
|
||||
msgstr "Загружается"
|
||||
|
||||
msgid "Do you want to delete sql archive from cloud?"
|
||||
msgstr "Вы хотите удалить архив sql из облака?"
|
||||
|
||||
msgid "Do you want to restore database from sql archive?"
|
||||
msgstr "Хотите восстановить базу данных из sql архива?"
|
||||
|
||||
msgid "Do you want to delete files archive from cloud?"
|
||||
msgstr "Хотите удалить архив файлов из облака?"
|
||||
|
||||
msgid "File success downloaded to "
|
||||
msgstr "Файл успешно загружен в "
|
||||
|
||||
msgid "Error on connection"
|
||||
msgstr "Ошибка при подключении"
|
||||
|
||||
msgid "Successfully connected"
|
||||
msgstr "Успешное подключение"
|
||||
|
||||
msgid "Use CDN for Mediafiles"
|
||||
msgstr "Использовать CDN для Медиафайлов"
|
||||
|
||||
msgid "CDN Mediafiles Status"
|
||||
msgstr "CDN Статус Медиафайлов"
|
||||
|
||||
msgid "Synchronization process"
|
||||
msgstr "Процесс Синхронизации"
|
||||
|
||||
msgid "Cloud Public URL"
|
||||
msgstr "URL-адрес public облака"
|
||||
|
||||
msgid "Synchronized"
|
||||
msgstr "Синхронизирован"
|
||||
|
||||
msgid "Synchronization Off"
|
||||
msgstr "Выключено"
|
||||
|
||||
msgid "Started Mediafiles Synchronization Process"
|
||||
msgstr "Запущен процесс синхронизации медиафайлов"
|
||||
|
||||
msgid "Synchronize Again"
|
||||
msgstr "Синхронизировать Повторно"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Copyright (C) 2019 Andy Fragen
|
||||
# This file is distributed under the same license as the Admin Only Jetpack plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Admin Only Jetpack 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/admin-only-jetpack\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-04-26T14:33:28+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.1.0\n"
|
||||
"X-Domain: admin-only-jetpack\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Admin Only Jetpack"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://github.com/afragen/admin-only-jetpack"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Show Jetpack menu for Admin users only."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Andy Fragen"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,39 @@
|
||||
# Copyright (C) 2019 JSM's Adobe XMP / IPTC for WordPress
|
||||
# This file is distributed under the same license as the JSM's Adobe XMP / IPTC for WordPress package.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: JSM's Adobe XMP / IPTC for WordPress 1.3.3\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/adobe-xmp-for-wp\n"
|
||||
"POT-Creation-Date: 2019-MO-DA HO:MI+ZONE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
||||
#: lib/shortcode.php:87
|
||||
msgid "No XMP found for image ID %s."
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "JSM's Adobe XMP / IPTC for WordPress"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "https://surniaulula.com/extend/plugins/adobe-xmp-for-wp/"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid ""
|
||||
"Read Adobe XMP / IPTC information from Media Library and NextGEN Gallery "
|
||||
"images, using a Shortcode or PHP Class Method."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "JS Morisset"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "https://surniaulula.com/"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,238 @@
|
||||
# Copyright (C) 2019 Palbo Capello
|
||||
# This file is distributed under the GPL-2.0+.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Advanced Custom Types for Divi 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: "
|
||||
"https://wordpress.org/support/plugin/advanced-custom-types-divi\n"
|
||||
"POT-Creation-Date: 2019-06-29 00:00:14+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: en\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-Country: United States\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: "
|
||||
"__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
|
||||
"attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
|
||||
"X-Poedit-Basepath: ../\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"X-Poedit-Bookmarks: \n"
|
||||
"X-Textdomain-Support: yes\n"
|
||||
"X-Generator: grunt-wp-i18n1.0.2\n"
|
||||
|
||||
#: advanced-custom-types-divi.php:32
|
||||
msgid ""
|
||||
"Advanced Custom Types for Divi was deactivated because <span "
|
||||
"style='font-weight: bold;'>ACT for Divi PRO</span> is active"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-act-divi.php:266
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-act-divi.php:267
|
||||
msgid "License"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:15
|
||||
msgid "ACT Post Type Grid"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:81
|
||||
msgid "View more button"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:116
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:124
|
||||
msgid "Body"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:127
|
||||
msgid "Button"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:153
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:157
|
||||
msgid "Query"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:165
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:339
|
||||
msgid "Layout"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:169
|
||||
msgid "Card"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:182
|
||||
msgid "Show title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:185
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:201
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:233
|
||||
msgid "Toggle whether mushroom will be added to the pizza."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:189
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:205
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:237
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:396
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:190
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:206
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:238
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:397
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:198
|
||||
msgid "Show thumbnail"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:213
|
||||
msgid "Thumbnail size"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:218
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:250
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:269
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:343
|
||||
msgid "Content entered here will appear inside the module."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:230
|
||||
msgid "Show content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:245
|
||||
msgid "Content length"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:265
|
||||
msgid "Post type"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:276
|
||||
msgid "Posts limit"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:279
|
||||
msgid "Posts limit."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:286
|
||||
msgid "Posts offset"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:289
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:301
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:313
|
||||
msgid "Posts offset."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:296
|
||||
msgid "Order"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:308
|
||||
msgid "Order by"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:323
|
||||
msgid "View more text"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:326
|
||||
msgid "Post button."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:352
|
||||
msgid "Heading Level"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:356
|
||||
msgid "H1"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:357
|
||||
msgid "H2"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:358
|
||||
msgid "H3"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:359
|
||||
msgid "H4"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:360
|
||||
msgid "H5"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:361
|
||||
msgid "H6"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:371
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:375
|
||||
msgid "1 Column"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:376
|
||||
msgid "2 Columns"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:377
|
||||
msgid "3 Columns"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:378
|
||||
msgid "4 Columns"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:389
|
||||
msgid "Card inner padding"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:392
|
||||
msgid "Card inner padding."
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "Advanced Custom Types for Divi"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "https://www.advancedcustomtypes.io"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid "Advanced custom types for Divi theme and Divi builder."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "Palbo Capello"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "http://capellopablo.com/"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,231 @@
|
||||
# Copyright (C) 2019 Idenovasi
|
||||
# This file is distributed under the same license as the Advanced Random Posts Widget package.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Advanced Random Posts Widget 2.2.0\n"
|
||||
"Report-Msgid-Bugs-To: https://idenovasi.com/contact/\n"
|
||||
"POT-Creation-Date: 2019-03-07 16:09:37+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Idenovasi\n"
|
||||
"Language-Team: Idenovasi\n"
|
||||
"X-Generator: grunt-wp-i18n 1.0.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-Language: English\n"
|
||||
"X-Poedit-Country: UNITED STATES\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"X-Poedit-KeywordsList: "
|
||||
"__;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c;_nc:4c,1,2;_"
|
||||
"x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n"
|
||||
"X-Textdomain-Support: yes\n"
|
||||
|
||||
#: includes/form.php:48
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:55
|
||||
msgid "Title URL"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:62
|
||||
msgid "CSS Class"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:69
|
||||
msgid "HTML or text before the random posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:76
|
||||
msgid "HTML or text after the random posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:88
|
||||
msgid "Ignore sticky posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:94
|
||||
msgid "Number of posts to show"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:97
|
||||
msgid "to show all posts."
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:102
|
||||
msgid "Offset"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:105
|
||||
msgid "The number of posts to skip"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:110
|
||||
msgid "Post type"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:121
|
||||
msgid "Post status"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:136
|
||||
msgid "Limit to Category"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:152
|
||||
msgid "Limit to Tag"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:168
|
||||
msgid "Limit to Taxonomy"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:171
|
||||
msgid "Ex: category=1,2,4&post_tag=6,12"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:172
|
||||
msgid "Available: "
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:184
|
||||
msgid "Display thumbnail"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:190
|
||||
msgid "Thumbnail Size "
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:197
|
||||
msgid "Please read %1$sFAQ%2$s for more information."
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:203
|
||||
msgid "Use custom thumbnail sizes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:209
|
||||
msgid "Width & Height"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:217
|
||||
msgid "Thumbnail Alignment"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:220
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:221
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:222
|
||||
msgid "Center"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:227
|
||||
msgid ""
|
||||
"Your theme does not support Post Thumbnail feature, please go to "
|
||||
"%1$shttp://codex.wordpress.org/Post_Thumbnails%2$s to read more info and "
|
||||
"how to activate it in your theme."
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:237
|
||||
msgid "Display full post"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:244
|
||||
msgid "Display excerpt"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:250
|
||||
msgid "Excerpt Length"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:258
|
||||
msgid "Display Date"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:265
|
||||
msgid "Display Modified Date"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:272
|
||||
msgid "Use Relative Date. eg: 5 days ago"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:282
|
||||
msgid "Custom CSS"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:285
|
||||
msgid "You can find the plugin css selector on %1$sFAQ page%2$s."
|
||||
msgstr ""
|
||||
|
||||
#: includes/functions.php:14 includes/widget.php:27
|
||||
msgid "Random Posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/posts.php:101 includes/posts.php:107
|
||||
msgid "%s ago"
|
||||
msgstr ""
|
||||
|
||||
#: includes/widget.php:17
|
||||
msgid ""
|
||||
"An advanced widget that gives you total control over the output of the "
|
||||
"random posts."
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "Advanced Random Posts Widget"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "https://github.com/idenovasi/advanced-random-posts-widget"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid "Easily to display advanced random posts via shortcode or widget."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "Idenovasi"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "https://idenovasi.com/"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:34
|
||||
msgctxt "widget tab name"
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:35
|
||||
msgctxt "widget tab name"
|
||||
msgid "Posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:36
|
||||
msgctxt "widget tab name"
|
||||
msgid "Taxonomy"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:37
|
||||
msgctxt "widget tab name"
|
||||
msgid "Thumbnail"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:38
|
||||
msgctxt "widget tab name"
|
||||
msgid "Extras"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:39
|
||||
msgctxt "widget tab name"
|
||||
msgid "Custom CSS"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,49 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: xq-xe-xt-xy 1.0\n"
|
||||
"POT-Creation-Date: 2018-07-11 09:44+0300\n"
|
||||
"PO-Revision-Date: 2018-07-11 09:44+0300\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Marko Maksym\n"
|
||||
"Language: uk_UA\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
"X-Poedit-Basepath: ../includes\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Poedit-KeywordsList: __;_e\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: admin/class-admin-main.php:66
|
||||
msgid "Title of the page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-admin-main.php:66
|
||||
msgid "Link Name"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-admin-main.php:69
|
||||
msgid "Submenu title"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-admin-main.php:69
|
||||
msgid "Submenu item"
|
||||
msgstr ""
|
||||
|
||||
#: admin/templates/index.php:8
|
||||
msgid "Settings Page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/templates/main_module_menu.php:10
|
||||
msgid "Main page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/templates/main_module_menu.php:13 admin/templates/page1.php:8
|
||||
msgid "Page 1"
|
||||
msgstr ""
|
||||
|
||||
#: admin/templates/main_module_menu.php:16 admin/templates/page2.php:8
|
||||
msgid "Page 2"
|
||||
msgstr ""
|
||||
1127
spec/fixtures/dynamic_finders/plugin_version/aio-for-divi/translation_file/languages/en_US.po
vendored
Normal file
1127
spec/fixtures/dynamic_finders/plugin_version/aio-for-divi/translation_file/languages/en_US.po
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
spec/fixtures/dynamic_finders/plugin_version/ali2woo-lite/change_log/changelog.txt
vendored
Normal file
6
spec/fixtures/dynamic_finders/plugin_version/ali2woo-lite/change_log/changelog.txt
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
1.0.0
|
||||
- Initial release
|
||||
|
||||
1.0.2
|
||||
- Fixed issues with the chrome extension
|
||||
- Simpliy way to connect your store to the chrome extension
|
||||
9
spec/fixtures/dynamic_finders/plugin_version/astra-widgets/change_log/changelog.txt
vendored
Normal file
9
spec/fixtures/dynamic_finders/plugin_version/astra-widgets/change_log/changelog.txt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
v1.1.1
|
||||
- Fix: PHP Notice for address fixed.
|
||||
|
||||
v1.1.0
|
||||
- New: Add support for full FontAwesome library in widgets.
|
||||
- Fix: JS error in the WordPress admin panel causing errors in
|
||||
|
||||
v1.0.0
|
||||
- Initial release
|
||||
File diff suppressed because it is too large
Load Diff
34
spec/fixtures/dynamic_finders/plugin_version/avangpress/change_log/CHANGELOG.md
vendored
Normal file
34
spec/fixtures/dynamic_finders/plugin_version/avangpress/change_log/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
#### 1.0.1 - May 10, 2019
|
||||
|
||||
**Fixed**
|
||||
- AffiliateWP integration subscribing the wrong user if affiliate ID differs from user ID.
|
||||
- Broken url
|
||||
|
||||
**Improvements**
|
||||
- Test by latest wordpress 5.2
|
||||
|
||||
#### 1.0.0 - September 21, 2018
|
||||
|
||||
**Changes**
|
||||
|
||||
- Change module name from AvangEmail to AvangPress
|
||||
- Change logo
|
||||
|
||||
**Additions**
|
||||
|
||||
- Fix bug on detect connection
|
||||
- Fix bug saved list to database.
|
||||
|
||||
|
||||
#### 0.0.1 - August 8, 2018
|
||||
|
||||
**Improvements**
|
||||
|
||||
- Init project based on AvangPress for wordpress plugin
|
||||
|
||||
**Additions**
|
||||
|
||||
- Add AvangPress php api to project.
|
||||
18
spec/fixtures/dynamic_finders/plugin_version/awesome-hooks/composer_file/package.json
vendored
Normal file
18
spec/fixtures/dynamic_finders/plugin_version/awesome-hooks/composer_file/package.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "awesome-hooks",
|
||||
"version": "0.0.2",
|
||||
"main": "Gruntfile.js",
|
||||
"author": "Surror",
|
||||
"devDependencies": {
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-contrib-clean": "^1.1.0",
|
||||
"grunt-contrib-compress": "^1.4.3",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
"grunt-contrib-copy": "^1.0.0",
|
||||
"grunt-contrib-cssmin": "^2.2.1",
|
||||
"grunt-contrib-uglify": "^3.3.0",
|
||||
"grunt-postcss": "^0.9.0",
|
||||
"grunt-rtlcss": "^2.0.1",
|
||||
"grunt-wp-i18n": "~1.0.0"
|
||||
}
|
||||
}
|
||||
9
spec/fixtures/dynamic_finders/plugin_version/awp-booking-calendar/change_log/CHANGELOG.md
vendored
Normal file
9
spec/fixtures/dynamic_finders/plugin_version/awp-booking-calendar/change_log/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## 1.0.1
|
||||
|
||||
- Updated readme
|
||||
|
||||
## 1.0.0
|
||||
|
||||
- Initial
|
||||
@@ -0,0 +1,135 @@
|
||||
# Copyright (C) 2019 Benjamin Lu
|
||||
# This file is distributed under the same license as the Backdrop Post Types plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Backdrop Post Types 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/backdrop-post-types\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-04-16T18:19:05+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.1.0\n"
|
||||
"X-Domain: backdrop-post-types\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Backdrop Post Types"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Backdrop Post Types registers post types of your choice."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Benjamin Lu"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://benjlu.com"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a single label for a post type
|
||||
#: includes/register-post-type.php:75
|
||||
msgid "Add New %s"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a single label for a post type
|
||||
#: includes/register-post-type.php:78
|
||||
msgid "Add New %s Item"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a single label for a post type
|
||||
#: includes/register-post-type.php:81
|
||||
msgid "Edit %s Item"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a single label for a post type
|
||||
#: includes/register-post-type.php:87
|
||||
msgid "View %s Item"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a single label for a post type
|
||||
#: includes/register-post-type.php:90
|
||||
msgid "Search %s Item"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:92
|
||||
#: includes/register-post-type.php:135
|
||||
msgid "Not Found"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:93
|
||||
msgid "Not Found in Trash"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:95
|
||||
msgid "Parent Item: "
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:119
|
||||
msgctxt "Taxonomy General Name"
|
||||
msgid "Categories"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:120
|
||||
msgctxt "Taxonomy Singular Name"
|
||||
msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:121
|
||||
msgid "Categories"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:122
|
||||
msgid "All Categories"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:123
|
||||
msgid "Parent Category"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:124
|
||||
msgid "Parent Category:"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:125
|
||||
msgid "New Category Name"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:126
|
||||
msgid "Add New Category"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:127
|
||||
msgid "Edit Categories"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:128
|
||||
msgid "Update Categories"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:129
|
||||
msgid "View Categories"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:130
|
||||
msgid "Separate categories with commas"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:131
|
||||
msgid "Add or remove categories"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:132
|
||||
msgid "Choose from the most used"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:133
|
||||
msgid "Popular Categories"
|
||||
msgstr ""
|
||||
|
||||
#: includes/register-post-type.php:134
|
||||
msgid "Search Categories"
|
||||
msgstr ""
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
||||
# Copyright (C) 2019 Applelo
|
||||
# This file is distributed under the GPL-3.0+.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Better Admin Users Search 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: "
|
||||
"http://wordpress.org/support/plugin/better-admin-users-search\n"
|
||||
"POT-Creation-Date: 2019-04-06 23:45:45+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-4-6 23:45+240\n"
|
||||
"Last-Translator: Applelo boubaultlois@gmail.com\n"
|
||||
"Language-Team: Applelo boubaultlois@gmail.com\n"
|
||||
"Language: en_US\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-Country: United States\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: "
|
||||
"__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
|
||||
"attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
|
||||
"X-Poedit-Basepath: ../\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"X-Poedit-Bookmarks: \n"
|
||||
"X-Textdomain-Support: yes\n"
|
||||
"X-Generator: grunt-wp-i18n 1.0.3\n"
|
||||
|
||||
#: better-admin-users-search.php:33
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-better-admin-users-search-admin-page.php:34
|
||||
msgid "Default search values"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-better-admin-users-search-admin-page.php:35
|
||||
msgid "Default values used by WordPress to do the search"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-better-admin-users-search-admin-page.php:47
|
||||
msgid "For you, this data is \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-better-admin-users-search-admin-page.php:54
|
||||
msgid "Additionals metas"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-better-admin-users-search-admin-page.php:55
|
||||
msgid "Add additional user metas to the admin user search"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-better-admin-users-search-admin-page.php:55
|
||||
msgid "Note: Some metas won't work because their are not string."
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-better-admin-users-search-admin-page.php:63
|
||||
msgid "User meta(s)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-better-admin-users-search-admin-page.php:65
|
||||
msgid "Select metas you want to add to your search."
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "Better Admin Users Search"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "https://github.com/Applelo/Better-Admin-Users-Search"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid "A plugin to improve users admin search"
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "Applelo"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "https://lois-boubault.me/"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,9 @@
|
||||
# Better Reviews for WooCommerce Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file, according to [the Keep a Changelog standards](http://keepachangelog.com/).
|
||||
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [0.1.0]
|
||||
|
||||
* Initial public release.
|
||||
@@ -0,0 +1,895 @@
|
||||
# Copyright (C) 2019 Liquid Web
|
||||
# This file is distributed under the MIT.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Better Reviews For WooCommerce 0.1.0\n"
|
||||
"Report-Msgid-Bugs-To: "
|
||||
"https://wordpress.org/support/plugin/woo-better-reviews\n"
|
||||
"POT-Creation-Date: 2019-04-03 12:33:05+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: en\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-Country: United States\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: "
|
||||
"__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
|
||||
"attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
|
||||
"X-Poedit-Basepath: ../\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"X-Poedit-Bookmarks: \n"
|
||||
"X-Textdomain-Support: yes\n"
|
||||
"X-Generator: grunt-wp-i18n1.0.2\n"
|
||||
|
||||
#: includes/admin/admin-notices.php:100
|
||||
msgid "Return to the main list"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:60 includes/admin/admin-pages.php:84
|
||||
#: includes/admin/admin-pages.php:336 includes/admin/admin-pages.php:377
|
||||
#: includes/admin/admin-pages.php:473 includes/admin/admin-pages.php:497
|
||||
#: includes/admin/admin-pages.php:638 includes/admin/admin-pages.php:679
|
||||
#: includes/admin/admin-pages.php:793 includes/admin/admin-pages.php:817
|
||||
msgid "You are not permitted to view this page."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:119 includes/admin/list-reviews.php:106
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:135
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:151 includes/admin/list-reviews.php:113
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:167
|
||||
msgid "Scoring"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:180
|
||||
msgid "Total Rating:"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:201
|
||||
msgid "%s out of 7"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:230
|
||||
msgid "Update Review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:234 includes/admin/admin-pages.php:611
|
||||
#: includes/admin/admin-pages.php:959
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:274 includes/admin/admin-pages.php:312
|
||||
msgid "Search results for “%s”"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:390 includes/admin/admin-pages.php:451
|
||||
msgid "Add New Attribute"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:406 includes/admin/admin-pages.php:527
|
||||
#: includes/admin/admin-pages.php:708 includes/admin/admin-pages.php:847
|
||||
#: includes/admin/list-attributes.php:102 includes/admin/list-charstcs.php:103
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:410 includes/admin/admin-pages.php:537
|
||||
#: includes/admin/admin-pages.php:712 includes/admin/admin-pages.php:857
|
||||
msgid "The name is how it appears on your site."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:419 includes/admin/admin-pages.php:549
|
||||
#: includes/admin/admin-pages.php:721 includes/admin/admin-pages.php:869
|
||||
#: includes/admin/list-attributes.php:104 includes/admin/list-charstcs.php:105
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:423 includes/admin/admin-pages.php:559
|
||||
#: includes/admin/admin-pages.php:725 includes/admin/admin-pages.php:879
|
||||
msgid "The description is optional and may not be displayed based on your theme."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:432 includes/admin/admin-pages.php:571
|
||||
msgid "Rating Labels"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:437 includes/admin/admin-pages.php:580
|
||||
msgid "Minimum"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:443 includes/admin/admin-pages.php:586
|
||||
msgid "Maximum"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:607
|
||||
msgid "Update Attribute"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:692 includes/admin/admin-pages.php:771
|
||||
msgid "Add New Characteristic"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:734 includes/admin/admin-pages.php:891
|
||||
#: includes/admin/list-charstcs.php:106
|
||||
msgid "Values"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:738 includes/admin/admin-pages.php:901
|
||||
msgid "Separate individual values with commas."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:955
|
||||
msgid "Update Characteristic"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:994
|
||||
msgid "(select)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/admin-pages.php:1022 includes/helpers.php:524
|
||||
msgid "Overall Score: %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:37
|
||||
msgid "Product Attribute"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:38 includes/admin/menu-items.php:161
|
||||
#: includes/admin/woo-settings.php:95 includes/helpers.php:29
|
||||
msgid "Product Attributes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:103 includes/admin/list-charstcs.php:104
|
||||
msgid "Slug"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:105
|
||||
msgid "Min Label"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:106
|
||||
msgid "Max Label"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:121 includes/admin/list-charstcs.php:122
|
||||
msgid "Search Attributes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:283
|
||||
msgid "Delete Attributes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:309 includes/admin/list-charstcs.php:311
|
||||
#: includes/admin/list-reviews.php:493 includes/admin/list-reviews.php:741
|
||||
#: includes/admin/list-reviews.php:1374 includes/admin/list-reviews.php:1406
|
||||
#: includes/admin/product-meta.php:169 includes/helpers.php:222
|
||||
#: includes/process/admin-process.php:46 includes/process/admin-process.php:122
|
||||
#: includes/process/admin-process.php:180
|
||||
#: includes/process/admin-process.php:238
|
||||
#: includes/process/admin-process.php:301
|
||||
#: includes/process/admin-process.php:375
|
||||
#: includes/process/admin-process.php:423 includes/process/form-process.php:37
|
||||
msgid "Your security nonce failed."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:383
|
||||
msgid "Select attribute"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:399 includes/admin/list-charstcs.php:401
|
||||
msgid "\"%s\" (Edit)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:430 includes/admin/list-charstcs.php:432
|
||||
msgid "No description"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:692 includes/admin/list-charstcs.php:724
|
||||
#: includes/admin/list-reviews.php:932 includes/admin/list-reviews.php:1561
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:693 includes/admin/menu-items.php:161
|
||||
msgid "Edit Attribute"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:703 includes/admin/list-charstcs.php:735
|
||||
#: includes/admin/list-reviews.php:1573
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:704
|
||||
msgid "Delete Attribute"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-attributes.php:766
|
||||
msgid "No attributes found."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:38
|
||||
msgid "Product Characteristic"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:39
|
||||
msgid "Product Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:107
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:285
|
||||
msgid "Delete Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:385
|
||||
msgid "Select characteristic"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:448
|
||||
msgid "No values"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:464
|
||||
msgid "No type"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:725 includes/admin/menu-items.php:167
|
||||
msgid "Edit Characteristic"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:736
|
||||
msgid "Delete Characteristic"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-charstcs.php:798
|
||||
msgid "No characteristics found."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:38
|
||||
msgid "Product Review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:39
|
||||
msgid "Product Reviews"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:107
|
||||
msgid "Product"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:108
|
||||
msgid "Review Date"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:109
|
||||
msgid "Total Score"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:110
|
||||
msgid "Attribute Ratings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:111
|
||||
msgid "Author"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:112
|
||||
msgid "Verified"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:131
|
||||
msgid "Search Reviews"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:313
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:466
|
||||
msgid "Approve Pending"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:467
|
||||
msgid "Delete Selected"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:875
|
||||
msgid "Select review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:930
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:995
|
||||
msgid "%s / 7"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1020
|
||||
msgid "Unknown Reviewer"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1021
|
||||
msgid "unknown email"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1036
|
||||
msgid "Email this review author."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1047
|
||||
msgid "View the user profile"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1055
|
||||
msgid "User ID: %d"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1096
|
||||
#: includes/display/layout-single-review.php:190
|
||||
msgid "This review is verified."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1562 includes/admin/menu-items.php:155
|
||||
msgid "Edit Review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1574
|
||||
msgid "Delete Review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1590
|
||||
msgid "Approve"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1591
|
||||
msgid "Approve Review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1655
|
||||
msgid "No reviews avaliable."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1675 includes/admin/list-reviews.php:1692
|
||||
msgid "Change Selected Reviews"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/list-reviews.php:1681
|
||||
msgid "Select Status"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/menu-items.php:58
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/menu-items.php:59 includes/admin/menu-items.php:81
|
||||
#: includes/admin/menu-items.php:155
|
||||
msgid "Reviews"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/menu-items.php:93
|
||||
msgid "Attributes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/menu-items.php:103
|
||||
msgid "Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/menu-items.php:167
|
||||
msgid "Review Author Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/post-columns.php:87
|
||||
msgid "none"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/post-columns.php:123
|
||||
msgid "Review Count"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/post-columns.php:128
|
||||
#: includes/display/layout-review-aggregate.php:49
|
||||
msgid "Average Rating"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/product-meta.php:51
|
||||
msgid "Review Attributes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/product-meta.php:68
|
||||
msgid "No product attributes have been created yet."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/product-meta.php:78
|
||||
msgid "Product attributes have been enabled globally by the site administrator."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/product-meta.php:174
|
||||
msgid "You do not have the capability to perform this action."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/woo-settings.php:75
|
||||
msgid "Enable reviews using Woo Better Reviews"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/woo-settings.php:81
|
||||
msgid "Anonymous Reviews"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/woo-settings.php:82
|
||||
msgid "Allow non-logged in users to leave product reviews."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/woo-settings.php:96
|
||||
msgid "Apply attributes to every product."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:73
|
||||
msgid "The required column name is missing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:137 includes/database.php:182
|
||||
#: includes/database.php:229 includes/database.php:276
|
||||
msgid "The required table name was not provided."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:187
|
||||
msgid "The required arguments were was not provided."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:195 includes/database.php:242
|
||||
msgid "No required arguments could be found."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:210
|
||||
msgid "The required %s argument is missing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:234 includes/database.php:281
|
||||
msgid "The required arguments were not provided."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:257
|
||||
msgid "The %s argument is not valid for this table."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:289
|
||||
msgid "No argument formatting could be found."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:502 includes/database.php:572
|
||||
#: includes/database.php:652
|
||||
msgid "The required table name is missing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:507 includes/database.php:520
|
||||
#: includes/database.php:577 includes/tables/data-authormeta.php:118
|
||||
#: includes/tables/data-authormeta.php:160 includes/tables/data-content.php:134
|
||||
#: includes/tables/data-content.php:181 includes/tables/data-ratings.php:100
|
||||
#: includes/tables/data-ratings.php:142 includes/tables/tax-attributes.php:115
|
||||
#: includes/tables/tax-attributes.php:162
|
||||
#: includes/tables/tax-characteristics.php:98
|
||||
#: includes/tables/tax-characteristics.php:140
|
||||
msgid "The required database arguments are missing or invalid."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:515 includes/database.php:590
|
||||
#: includes/database.php:660
|
||||
msgid "The provided table name is not valid."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:582 includes/database.php:665
|
||||
msgid "The required ID was missing or invalid."
|
||||
msgstr ""
|
||||
|
||||
#: includes/database.php:601 includes/database.php:676
|
||||
msgid "The provided ID does not exist in the database."
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-data.php:30
|
||||
msgid "Review Title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-data.php:33
|
||||
msgid "Example: This product has great features!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-data.php:37 includes/helpers.php:26
|
||||
msgid "Review Content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-data.php:70
|
||||
msgid "Your Name"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-data.php:77
|
||||
msgid "Your Email"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-data.php:138
|
||||
msgid "Submit Review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-data.php:146
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-fields.php:78 includes/display/form-fields.php:216
|
||||
#: includes/display/form-fields.php:273 includes/display/form-fields.php:335
|
||||
#: includes/display/form-fields.php:402
|
||||
#: includes/display/layout-new-review-form.php:63
|
||||
#: includes/display/layout-new-review-form.php:160
|
||||
msgid "This is a required field"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-fields.php:260
|
||||
msgid "(Select)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/form-fields.php:449
|
||||
msgid "Click Here"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-new-review-form.php:29
|
||||
msgid "Leave a Review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-new-review-form.php:60
|
||||
msgid "Overall Rating"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-new-review-form.php:81
|
||||
msgid "Select a %d star rating"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-new-review-form.php:140
|
||||
#: includes/display/layout-review-aggregate.php:177
|
||||
#: includes/display/layout-single-review.php:92
|
||||
msgid "Min."
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-new-review-form.php:141
|
||||
#: includes/display/layout-review-aggregate.php:178
|
||||
#: includes/display/layout-single-review.php:93
|
||||
msgid "Max."
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-new-review-form.php:174
|
||||
msgid "Select a %d rating for this attribute"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-new-review-form.php:330
|
||||
msgid "Tell us about yourself"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-aggregate.php:58
|
||||
msgid "Average Rating: %s stars"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-aggregate.php:61
|
||||
msgid "%s reviews total"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-aggregate.php:96
|
||||
msgid "Rating Breakdown"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-aggregate.php:117
|
||||
msgid "%d Star:"
|
||||
msgid_plural "%d Stars:"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: includes/display/layout-review-aggregate.php:164
|
||||
msgid "Review Summary"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-list.php:92
|
||||
#. translators: 1: reviews count 2: product name
|
||||
msgid "%1$s review for %2$s"
|
||||
msgid_plural "%1$s reviews for %2$s"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: includes/display/layout-review-list.php:96
|
||||
msgid "Leave a review"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-list.php:155
|
||||
msgid "Sort By:"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-list.php:180
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-list.php:230
|
||||
msgid "« Previous %s Reviews"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-review-list.php:231
|
||||
msgid "Next %s Reviews »"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-single-review.php:55
|
||||
msgid "Posted on %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/layout-single-review.php:193
|
||||
msgid "by %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/view-output.php:221
|
||||
msgid "No reviews matched your criteria. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/view-output.php:221
|
||||
msgid "There are no reviews yet. Be the first!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/display/woo-filters.php:46
|
||||
msgid "Reviews (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:27
|
||||
msgid "Author Meta"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:28
|
||||
msgid "Review Ratings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:30
|
||||
msgid "Author Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:31
|
||||
msgid "Author Setup"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:354
|
||||
msgid "Approved"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:355
|
||||
msgid "Pending Approval"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:356
|
||||
msgid "Rejected"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:357
|
||||
msgid "Hidden"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:651
|
||||
msgid "Dropdown"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:652
|
||||
msgid "Radio"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:653
|
||||
msgid "Boolean (Yes / No)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:673
|
||||
msgid "Your review has been submitted and is pending approval."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:677
|
||||
msgid "There was an error attempting to save your review."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:681
|
||||
msgid "The selected review has been updated."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:685
|
||||
msgid "The selected review has been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:689
|
||||
msgid "The new attribute has been added."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:693
|
||||
msgid "The selected attribute has been updated."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:697
|
||||
msgid "The selected attribute has been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:701
|
||||
msgid "The selected attributes have been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:705
|
||||
msgid "The required attribute arguments were not provided."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:709
|
||||
msgid "The attribute could not be updated at this time."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:713
|
||||
msgid "The selected attribute could not be deleted at this time."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:717
|
||||
msgid "The new characteristic has been added."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:721
|
||||
msgid "The selected characteristic has been updated."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:725
|
||||
msgid "The selected characteristic has been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:729
|
||||
msgid "The selected characteristics have been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:733
|
||||
msgid "The required characteristic arguments were not provided."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:737
|
||||
msgid "The characteristic could not be updated at this time."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:741
|
||||
msgid "The selected characteristic could not be deleted at this time."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:745
|
||||
msgid "The required ID was not posted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:749
|
||||
msgid "The required arguments were not posted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:753
|
||||
msgid "The required arguments could not be formatted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:757
|
||||
msgid "The selected reviews have been updated."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:761
|
||||
msgid "The selected review has been approved."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:765
|
||||
msgid "The selected reviews have been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:769
|
||||
msgid "The selected review statuses have been updated."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:774
|
||||
msgid "There was an unknown error with your request."
|
||||
msgstr ""
|
||||
|
||||
#: includes/helpers.php:778
|
||||
msgid "There was an error with your request."
|
||||
msgstr ""
|
||||
|
||||
#: includes/process/admin-process.php:563
|
||||
msgid "The required arguments to create a link were not provided."
|
||||
msgstr ""
|
||||
|
||||
#: includes/process/admin-process.php:592
|
||||
msgid "The base link for editing this item could not be determined."
|
||||
msgstr ""
|
||||
|
||||
#: includes/process/form-process.php:255 includes/process/form-process.php:313
|
||||
#: includes/process/form-process.php:367
|
||||
msgid "The required data to format."
|
||||
msgstr ""
|
||||
|
||||
#: includes/process/form-process.php:260
|
||||
msgid "Review on %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/process/form-process.php:308 includes/process/form-process.php:362
|
||||
#: includes/process/form-process.php:407
|
||||
msgid "The required review ID was not provided."
|
||||
msgstr ""
|
||||
|
||||
#: includes/process/form-process.php:412
|
||||
msgid "The required data is missing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/process/form-process.php:433
|
||||
msgid "The review scoring could not be inserted."
|
||||
msgstr ""
|
||||
|
||||
#: includes/queries.php:248 includes/queries.php:401 includes/queries.php:986
|
||||
#: includes/queries.php:1117 includes/queries.php:1335
|
||||
msgid "A product ID is required."
|
||||
msgstr ""
|
||||
|
||||
#: includes/queries.php:581 includes/queries.php:1661
|
||||
msgid "An author ID is required."
|
||||
msgstr ""
|
||||
|
||||
#: includes/queries.php:894 includes/queries.php:1073
|
||||
msgid "A review ID is required."
|
||||
msgstr ""
|
||||
|
||||
#: includes/queries.php:991
|
||||
msgid "An characteristic ID is required."
|
||||
msgstr ""
|
||||
|
||||
#: includes/queries.php:996
|
||||
msgid "An characteristic value is required."
|
||||
msgstr ""
|
||||
|
||||
#: includes/queries.php:1045
|
||||
msgid "Review IDs are required for batch."
|
||||
msgstr ""
|
||||
|
||||
#: includes/queries.php:1454
|
||||
msgid "The required attribute ID is missing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/queries.php:1769
|
||||
msgid "The required characteristic ID is missing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/tables/data-authormeta.php:135 includes/tables/data-content.php:156
|
||||
#: includes/tables/data-ratings.php:117 includes/tables/tax-attributes.php:137
|
||||
#: includes/tables/tax-characteristics.php:115
|
||||
msgid "The data could not be written to the database."
|
||||
msgstr ""
|
||||
|
||||
#: includes/tables/data-authormeta.php:155
|
||||
#: includes/tables/data-authormeta.php:200 includes/tables/data-content.php:176
|
||||
#: includes/tables/data-content.php:221 includes/tables/data-ratings.php:137
|
||||
#: includes/tables/data-ratings.php:182 includes/tables/tax-attributes.php:157
|
||||
#: includes/tables/tax-attributes.php:207
|
||||
#: includes/tables/tax-characteristics.php:135
|
||||
#: includes/tables/tax-characteristics.php:180
|
||||
msgid "The required ID is missing."
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "Better Reviews For WooCommerce"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "https://github.com/liquidweb/woo-better-reviews"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid "Like reviews, only way better."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "Liquid Web"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "https://www.liquidweb.com"
|
||||
msgstr ""
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user