File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/cli.tar
crawler.cls.php 0000644 00000012225 15154021372 0007476 0 ustar 00 <?php
namespace LiteSpeed\CLI;
defined('WPINC') || exit();
use LiteSpeed\Debug2;
use LiteSpeed\Base;
use LiteSpeed\Task;
use LiteSpeed\Crawler as Crawler2;
use WP_CLI;
/**
* Crawler
*/
class Crawler extends Base
{
private $__crawler;
public function __construct()
{
Debug2::debug('CLI_Crawler init');
$this->__crawler = Crawler2::cls();
}
/**
* List all crawler
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # List all crawlers
* $ wp litespeed-crawler l
*
*/
public function l()
{
$this->list();
}
/**
* List all crawler
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # List all crawlers
* $ wp litespeed-crawler list
*
*/
public function list()
{
$crawler_list = $this->__crawler->list_crawlers();
$summary = Crawler2::get_summary();
if ($summary['curr_crawler'] >= count($crawler_list)) {
$summary['curr_crawler'] = 0;
}
$is_running = time() - $summary['is_running'] <= 900;
$CRAWLER_RUN_INTERVAL = defined('LITESPEED_CRAWLER_RUN_INTERVAL') ? LITESPEED_CRAWLER_RUN_INTERVAL : 600; // Specify time in seconds for the time between each run interval
if ($CRAWLER_RUN_INTERVAL > 0) {
$recurrence = '';
$hours = (int) floor($CRAWLER_RUN_INTERVAL / 3600);
if ($hours) {
if ($hours > 1) {
$recurrence .= sprintf(__('%d hours', 'litespeed-cache'), $hours);
} else {
$recurrence .= sprintf(__('%d hour', 'litespeed-cache'), $hours);
}
}
$minutes = (int) floor(($CRAWLER_RUN_INTERVAL % 3600) / 60);
if ($minutes) {
$recurrence .= ' ';
if ($minutes > 1) {
$recurrence .= sprintf(__('%d minutes', 'litespeed-cache'), $minutes);
} else {
$recurrence .= sprintf(__('%d minute', 'litespeed-cache'), $minutes);
}
}
}
$list = array();
foreach ($crawler_list as $i => $v) {
$hit = !empty($summary['crawler_stats'][$i][Crawler2::STATUS_HIT]) ? $summary['crawler_stats'][$i][Crawler2::STATUS_HIT] : 0;
$miss = !empty($summary['crawler_stats'][$i][Crawler2::STATUS_MISS]) ? $summary['crawler_stats'][$i][Crawler2::STATUS_MISS] : 0;
$blacklisted = !empty($summary['crawler_stats'][$i][Crawler2::STATUS_BLACKLIST]) ? $summary['crawler_stats'][$i][Crawler2::STATUS_BLACKLIST] : 0;
$blacklisted += !empty($summary['crawler_stats'][$i][Crawler2::STATUS_NOCACHE]) ? $summary['crawler_stats'][$i][Crawler2::STATUS_NOCACHE] : 0;
if (isset($summary['crawler_stats'][$i][Crawler2::STATUS_WAIT])) {
$waiting = $summary['crawler_stats'][$i][Crawler2::STATUS_WAIT] ?: 0;
} else {
$waiting = $summary['list_size'] - $hit - $miss - $blacklisted;
}
$analytics = 'Waiting: ' . $waiting;
$analytics .= ' Hit: ' . $hit;
$analytics .= ' Miss: ' . $miss;
$analytics .= ' Blocked: ' . $blacklisted;
$running = '';
if ($i == $summary['curr_crawler']) {
$running = 'Pos: ' . ($summary['last_pos'] + 1);
if ($is_running) {
$running .= '(Running)';
}
}
$status = $this->__crawler->is_active($i) ? '✅' : '❌';
$list[] = array(
'ID' => $i + 1,
'Name' => wp_strip_all_tags($v['title']),
'Frequency' => $recurrence,
'Status' => $status,
'Analytics' => $analytics,
'Running' => $running,
);
}
WP_CLI\Utils\format_items('table', $list, array('ID', 'Name', 'Frequency', 'Status', 'Analytics', 'Running'));
}
/**
* Enable one crawler
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Turn on 2nd crawler
* $ wp litespeed-crawler enable 2
*
*/
public function enable($args)
{
$id = $args[0] - 1;
if ($this->__crawler->is_active($id)) {
WP_CLI::error('ID #' . $id . ' had been enabled');
return;
}
$this->__crawler->toggle_activeness($id);
WP_CLI::success('Enabled crawler #' . $id);
}
/**
* Disable one crawler
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Turn off 1st crawler
* $ wp litespeed-crawler disable 1
*
*/
public function disable($args)
{
$id = $args[0] - 1;
if (!$this->__crawler->is_active($id)) {
WP_CLI::error('ID #' . $id . ' has been disabled');
return;
}
$this->__crawler->toggle_activeness($id);
WP_CLI::success('Disabled crawler #' . $id);
}
/**
* Run crawling
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Start crawling
* $ wp litespeed-crawler r
*
*/
public function r()
{
$this->run();
}
/**
* Run crawling
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Start crawling
* $ wp litespeed-crawler run
*
*/
public function run()
{
self::debug('⚠️⚠️⚠️ Forced take over lane (CLI)');
$this->__crawler->Release_lane();
Task::async_call('crawler');
$summary = Crawler2::get_summary();
WP_CLI::success('Start crawling. Current crawler #' . ($summary['curr_crawler'] + 1) . ' [position] ' . $summary['last_pos'] . ' [total] ' . $summary['list_size']);
}
/**
* Reset position
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Reset crawler position
* $ wp litespeed-crawler reset
*
*/
public function reset()
{
$this->__crawler->reset_pos();
$summary = Crawler2::get_summary();
WP_CLI::success('Reset position. Current crawler #' . ($summary['curr_crawler'] + 1) . ' [position] ' . $summary['last_pos'] . ' [total] ' . $summary['list_size']);
}
}
debug.cls.php 0000644 00000001044 15154021372 0007122 0 ustar 00 <?php
namespace LiteSpeed\CLI;
defined('WPINC') || exit();
use LiteSpeed\Debug2;
use LiteSpeed\Report;
use WP_CLI;
/**
* Debug API CLI
*/
class Debug
{
private $__report;
public function __construct()
{
Debug2::debug('CLI_Debug init');
$this->__report = Report::cls();
}
/**
* Send report
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Send env report to LiteSpeed
* $ wp litespeed-debug send
*
*/
public function send()
{
$num = $this->__report->post_env();
WP_CLI::success('Report Number = ' . $num);
}
}
image.cls.php 0000644 00000006454 15154021372 0007130 0 ustar 00 <?php
namespace LiteSpeed\CLI;
defined('WPINC') || exit();
use LiteSpeed\Lang;
use LiteSpeed\Debug2;
use LiteSpeed\Img_Optm;
use LiteSpeed\Utility;
use WP_CLI;
/**
* Image Optm API CLI
*/
class Image
{
private $__img_optm;
public function __construct()
{
Debug2::debug('CLI_Cloud init');
$this->__img_optm = Img_Optm::cls();
}
/**
* Batch toggle optimized images w/ original images
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Switch to original images
* $ wp litespeed-image batch_switch orig
*
* # Switch to optimized images
* $ wp litespeed-image batch_switch optm
*
*/
public function batch_switch($param)
{
$type = $param[0];
$this->__img_optm->batch_switch($type);
}
/**
* Send image optimization request to QUIC.cloud server
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Send image optimization request
* $ wp litespeed-image push
*
*/
public function push()
{
$this->__img_optm->new_req();
}
/**
* Pull optimized images from QUIC.cloud server
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Pull images back from cloud
* $ wp litespeed-image pull
*
*/
public function pull()
{
$this->__img_optm->pull(true);
}
/**
* Show optimization status based on local data
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Show optimization status
* $ wp litespeed-image s
*
*/
public function s()
{
$this->status();
}
/**
* Show optimization status based on local data
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Show optimization status
* $ wp litespeed-image status
*
*/
public function status()
{
$summary = Img_Optm::get_summary();
$img_count = $this->__img_optm->img_count();
foreach (Lang::img_status() as $k => $v) {
if (isset($img_count["img.$k"])) {
$img_count["$v - images"] = $img_count["img.$k"];
unset($img_count["img.$k"]);
}
if (isset($img_count["group.$k"])) {
$img_count["$v - groups"] = $img_count["group.$k"];
unset($img_count["group.$k"]);
}
}
foreach (array('reduced', 'reduced_webp', 'reduced_avif') as $v) {
if (!empty($summary[$v])) {
$summary[$v] = Utility::real_size($summary[$v]);
}
}
if (!empty($summary['last_requested'])) {
$summary['last_requested'] = date('m/d/y H:i:s', $summary['last_requested']);
}
$list = array();
foreach ($summary as $k => $v) {
$list[] = array('key' => $k, 'value' => $v);
}
$list2 = array();
foreach ($img_count as $k => $v) {
if (!$v) {
continue;
}
$list2[] = array('key' => $k, 'value' => $v);
}
WP_CLI\Utils\format_items('table', $list, array('key', 'value'));
WP_CLI::line(WP_CLI::colorize('%CImages in database summary:%n'));
WP_CLI\Utils\format_items('table', $list2, array('key', 'value'));
}
/**
* Clean up unfinished image data from QUIC.cloud server
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Clean up unfinished requests
* $ wp litespeed-image clean
*
*/
public function clean()
{
$this->__img_optm->clean();
WP_CLI::line(WP_CLI::colorize('%CLatest status:%n'));
$this->status();
}
/**
* Remove original image backups
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Remove original image backups
* $ wp litespeed-image rm_bkup
*
*/
public function rm_bkup()
{
$this->__img_optm->rm_bkup();
}
}
online.cls.php 0000644 00000015500 15154021372 0007322 0 ustar 00 <?php
namespace LiteSpeed\CLI;
defined('WPINC') || exit();
use LiteSpeed\Debug2;
use LiteSpeed\Cloud;
use WP_CLI;
/**
* QUIC.cloud API CLI
*/
class Online
{
private $__cloud;
public function __construct()
{
Debug2::debug('CLI_Cloud init');
$this->__cloud = Cloud::cls();
}
/**
* Init domain on QUIC.cloud server (See https://quic.cloud/terms/)
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Activate domain on QUIC.cloud (! Require SERVER IP setting to be set first)
* $ wp litespeed-online init
*
*/
public function init()
{
$resp = $this->__cloud->init_qc_cli();
if (!empty($resp['qc_activated'])) {
$main_domain = !empty($resp['main_domain']) ? $resp['main_domain'] : false;
$this->__cloud->update_qc_activation($resp['qc_activated'], $main_domain);
WP_CLI::success('Init successfully. Activated type: ' . $resp['qc_activated']);
} else {
WP_CLI::error('Init failed!');
}
}
/**
* Init domain CDN service on QUIC.cloud server (See https://quic.cloud/terms/)
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Activate domain CDN on QUIC.cloud (support --format=json)
* $ wp litespeed-online cdn_init --method=cname|ns
* $ wp litespeed-online cdn_init --method=cname|ns --ssl-cert=xxx.pem --ssl-key=xxx
* $ wp litespeed-online cdn_init --method=cfi --cf-token=xxxxxxxx
* $ wp litespeed-online cdn_init --method=cfi --cf-token=xxxxxxxx --ssl-cert=xxx.pem --ssl-key=xxx
*
*/
public function cdn_init($args, $assoc_args)
{
if (empty($assoc_args['method'])) {
WP_CLI::error('Init CDN failed! Missing parameters `--method`.');
return;
}
if ((!empty($assoc_args['ssl-cert']) && empty($assoc_args['ssl-key'])) || (empty($assoc_args['ssl-cert']) && !empty($assoc_args['ssl-key']))) {
WP_CLI::error('Init CDN failed! SSL cert must be present together w/ SSL key.');
return;
}
if ($assoc_args['method'] == 'cfi' && empty($assoc_args['cf-token'])) {
WP_CLI::error('Init CDN failed! CFI must set `--cf-token`.');
return;
}
$cert = !empty($assoc_args['ssl-cert']) ? $assoc_args['ssl-cert'] : '';
$key = !empty($assoc_args['ssl-key']) ? $assoc_args['ssl-key'] : '';
$cf_token = !empty($assoc_args['cf-token']) ? $assoc_args['cf-token'] : '';
$resp = $this->__cloud->init_qc_cdn_cli($assoc_args['method'], $cert, $key, $cf_token);
if (!empty($resp['qc_activated'])) {
$main_domain = !empty($resp['main_domain']) ? $resp['main_domain'] : false;
$this->__cloud->update_qc_activation($resp['qc_activated'], $main_domain, true);
}
if (!empty($assoc_args['format']) && $assoc_args['format'] == 'json') {
WP_CLI::log(json_encode($resp));
return;
}
if (!empty($resp['qc_activated'])) {
WP_CLI::success('Init QC CDN successfully. Activated type: ' . $resp['qc_activated']);
} else {
WP_CLI::error('Init QC CDN failed!');
}
if (!empty($resp['cname'])) {
WP_CLI::success('cname: ' . $resp['cname']);
}
if (!empty($resp['msgs'])) {
WP_CLI::success('msgs: ' . var_export($resp['msgs'], true));
}
}
/**
* Link user account by api key
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Link user account by api key
* $ wp litespeed-online link --email=xxx@example.com --api-key=xxxx
*
*/
public function link($args, $assoc_args)
{
if (empty($assoc_args['email']) || empty($assoc_args['api-key'])) {
WP_CLI::error('Link to QUIC.cloud failed! Missing parameters `--email` or `--api-key`.');
return;
}
$resp = $this->__cloud->link_qc_cli($assoc_args['email'], $assoc_args['api-key']);
if (!empty($resp['qc_activated'])) {
$main_domain = !empty($resp['main_domain']) ? $resp['main_domain'] : false;
$this->__cloud->update_qc_activation($resp['qc_activated'], $main_domain, true);
WP_CLI::success('Link successfully!');
WP_CLI::log(json_encode($resp));
} else {
WP_CLI::error('Link failed!');
}
}
/**
* Sync usage data from QUIC.cloud
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Sync QUIC.cloud service usage info
* $ wp litespeed-online sync
*
*/
public function sync($args, $assoc_args)
{
$json = $this->__cloud->sync_usage();
if (!empty($assoc_args['format'])) {
WP_CLI::print_value($json, $assoc_args);
return;
}
WP_CLI::success('Sync successfully');
$list = array();
foreach (Cloud::$SERVICES as $v) {
$list[] = array(
'key' => $v,
'used' => !empty($json['usage.' . $v]['used']) ? $json['usage.' . $v]['used'] : 0,
'quota' => !empty($json['usage.' . $v]['quota']) ? $json['usage.' . $v]['quota'] : 0,
'PayAsYouGo_Used' => !empty($json['usage.' . $v]['pag_used']) ? $json['usage.' . $v]['pag_used'] : 0,
'PayAsYouGo_Balance' => !empty($json['usage.' . $v]['pag_bal']) ? $json['usage.' . $v]['pag_bal'] : 0,
);
}
WP_CLI\Utils\format_items('table', $list, array('key', 'used', 'quota', 'PayAsYouGo_Used', 'PayAsYouGo_Balance'));
}
/**
* Check QC account status
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Check QC account status
* $ wp litespeed-online cdn_status
*
*/
public function cdn_status($args, $assoc_args)
{
$resp = $this->__cloud->cdn_status_cli();
WP_CLI::log(json_encode($resp));
}
/**
* List all QUIC.cloud services
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # List all services tag
* $ wp litespeed-online services
*
*/
public function services($args, $assoc_args)
{
if (!empty($assoc_args['format'])) {
WP_CLI::print_value(Cloud::$SERVICES, $assoc_args);
return;
}
$list = array();
foreach (Cloud::$SERVICES as $v) {
$list[] = array(
'service' => $v,
);
}
WP_CLI\Utils\format_items('table', $list, array('service'));
}
/**
* List all QUIC.cloud servers in use
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # List all QUIC.cloud servers in use
* $ wp litespeed-online nodes
*
*/
public function nodes($args, $assoc_args)
{
$json = Cloud::get_summary();
$list = array();
$json_output = array();
foreach (Cloud::$SERVICES as $v) {
$server = !empty($json['server.' . $v]) ? $json['server.' . $v] : '';
$list[] = array(
'service' => $v,
'server' => $server,
);
$json_output[] = array($v => $server);
}
if (!empty($assoc_args['format'])) {
WP_CLI::print_value($json_output, $assoc_args);
return;
}
WP_CLI\Utils\format_items('table', $list, array('service', 'server'));
}
/**
* Detect closest node server for current service
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Detect closest node for one service
* $ wp litespeed-online ping img_optm
* $ wp litespeed-online ping img_optm --force
*
*/
public function ping($param, $assoc_args)
{
$svc = $param[0];
$force = !empty($assoc_args['force']);
$json = $this->__cloud->detect_cloud($svc, $force);
if ($json) {
WP_CLI::success('Updated closest server.');
}
WP_CLI::log('svc = ' . $svc);
WP_CLI::log('node = ' . ($json ?: '-'));
}
}
option.cls.php 0000644 00000021155 15154021372 0007351 0 ustar 00 <?php
namespace LiteSpeed\CLI;
defined('WPINC') || exit();
use LiteSpeed\Base;
use LiteSpeed\Admin_Settings;
use LiteSpeed\Utility;
use WP_CLI;
/**
* LiteSpeed Cache option Interface
*/
class Option extends Base
{
/**
* Set an individual LiteSpeed Cache option.
*
* ## OPTIONS
*
* <key>
* : The option key to update.
*
* <newvalue>
* : The new value to set the option to.
*
* ## EXAMPLES
*
* # Set to not cache the login page
* $ wp litespeed-option set cache-priv false
* $ wp litespeed-option set 'cdn-mapping[url][0]' https://cdn.EXAMPLE.com
* $ wp litespeed-option set media-lqip_exc $'line1\nline2'
*
*/
public function set($args, $assoc_args)
{
/**
* Note: If the value is multiple dimensions like cdn-mapping, need to specially handle it both here and in `const.default.json`
*
* For CDN/Crawler mutlti dimension settings, if all children are empty in one line, will delete that line. To delete one line, just set all to empty.
* E.g. to delete cdn-mapping[0], need to run below:
* `set cdn-mapping[url][0] ''`
* `set cdn-mapping[inc_img][0] ''`
* `set cdn-mapping[inc_css][0] ''`
* `set cdn-mapping[inc_js][0] ''`
* `set cdn-mapping[filetype][0] ''`
*/
$key = $args[0];
$val = $args[1];
/**
* For CDN mapping, allow:
* `set 'cdn-mapping[url][0]' https://the1st_cdn_url`
* `set 'cdn-mapping[inc_img][0]' true`
* `set 'cdn-mapping[inc_img][0]' 1`
* @since 2.7.1
*
* For Crawler cookies:
* `set 'crawler-cookies[name][0]' my_currency`
* `set 'crawler-cookies[vals][0]' "USD\nTWD"`
*
* For multi lines setting:
* `set media-lqip_exc $'img1.jpg\nimg2.jpg'`
*/
// Build raw data
$raw_data = array(
Admin_Settings::ENROLL => array($key),
);
// Contains child set
if (strpos($key, '[')) {
parse_str($key . '=' . $val, $key2);
$raw_data = array_merge($raw_data, $key2);
} else {
$raw_data[$key] = $val;
}
$this->cls('Admin_Settings')->save($raw_data);
WP_CLI::line("$key:");
$this->get($args, $assoc_args);
}
/**
* Get the plugin options.
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Get all options
* $ wp litespeed-option all
* $ wp litespeed-option all --json
*
*/
public function all($args, $assoc_args)
{
$options = $this->get_options();
if (!empty($assoc_args['format'])) {
WP_CLI::print_value($options, $assoc_args);
return;
}
$option_out = array();
$buf = WP_CLI::colorize('%CThe list of options:%n');
WP_CLI::line($buf);
foreach ($options as $k => $v) {
if ($k == self::O_CDN_MAPPING || $k == self::O_CRAWLER_COOKIES) {
foreach ($v as $k2 => $v2) {
// $k2 is numeric
if (is_array($v2)) {
foreach ($v2 as $k3 => $v3) {
// $k3 = 'url/inc_img/name/vals'
if (is_array($v3)) {
$option_out[] = array('key' => '', 'value' => '');
foreach ($v3 as $k4 => $v4) {
$option_out[] = array('key' => $k4 == 0 ? "{$k}[$k3][$k2]" : '', 'value' => $v4);
}
$option_out[] = array('key' => '', 'value' => '');
} else {
$option_out[] = array('key' => "{$k}[$k3][$k2]", 'value' => $v3);
}
}
}
}
continue;
} elseif (is_array($v) && $v) {
// $v = implode( PHP_EOL, $v );
$option_out[] = array('key' => '', 'value' => '');
foreach ($v as $k2 => $v2) {
$option_out[] = array('key' => $k2 == 0 ? $k : '', 'value' => $v2);
}
$option_out[] = array('key' => '', 'value' => '');
continue;
}
if (array_key_exists($k, self::$_default_options) && is_bool(self::$_default_options[$k]) && !$v) {
$v = 0;
}
if ($v === '' || $v === array()) {
$v = "''";
}
$option_out[] = array('key' => $k, 'value' => $v);
}
WP_CLI\Utils\format_items('table', $option_out, array('key', 'value'));
}
/**
* Get the plugin options.
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Get one option
* $ wp litespeed-option get cache-priv
* $ wp litespeed-option get 'cdn-mapping[url][0]'
*
*/
public function get($args, $assoc_args)
{
$id = $args[0];
$child = false;
if (strpos($id, '[')) {
parse_str($id, $id2);
Utility::compatibility();
$id = array_key_first($id2);
$child = array_key_first($id2[$id]); // `url`
if (!$child) {
WP_CLI::error('Wrong child key');
return;
}
$numeric = array_key_first($id2[$id][$child]); // `0`
if ($numeric === null) {
WP_CLI::error('Wrong 2nd level numeric key');
return;
}
}
if (!isset(self::$_default_options[$id])) {
WP_CLI::error('ID not exist [id] ' . $id);
return;
}
$v = $this->conf($id);
$default_v = self::$_default_options[$id];
/**
* For CDN_mapping and crawler_cookies
* Examples of option name:
* cdn-mapping[url][0]
* crawler-cookies[name][1]
*/
if ($id == self::O_CDN_MAPPING) {
if (!in_array($child, array(self::CDN_MAPPING_URL, self::CDN_MAPPING_INC_IMG, self::CDN_MAPPING_INC_CSS, self::CDN_MAPPING_INC_JS, self::CDN_MAPPING_FILETYPE))) {
WP_CLI::error('Wrong child key');
return;
}
}
if ($id == self::O_CRAWLER_COOKIES) {
if (!in_array($child, array(self::CRWL_COOKIE_NAME, self::CRWL_COOKIE_VALS))) {
WP_CLI::error('Wrong child key');
return;
}
}
if ($id == self::O_CDN_MAPPING || $id == self::O_CRAWLER_COOKIES) {
if (!empty($v[$numeric][$child])) {
$v = $v[$numeric][$child];
} else {
if ($id == self::O_CDN_MAPPING) {
if (in_array($child, array(self::CDN_MAPPING_INC_IMG, self::CDN_MAPPING_INC_CSS, self::CDN_MAPPING_INC_JS))) {
$v = 0;
} else {
$v = "''";
}
} else {
$v = "''";
}
}
}
if (is_array($v)) {
$v = implode(PHP_EOL, $v);
}
if (!$v && $id != self::O_CDN_MAPPING && $id != self::O_CRAWLER_COOKIES) {
// empty array for CDN/crawler has been handled
if (is_bool($default_v)) {
$v = 0;
} elseif (!is_array($default_v)) {
$v = "''";
}
}
WP_CLI::line($v);
}
/**
* Export plugin options to a file.
*
* ## OPTIONS
*
* [--filename=<path>]
* : The default path used is CURRENTDIR/lscache_wp_options_DATE-TIME.txt.
* To select a different file, use this option.
*
* ## EXAMPLES
*
* # Export options to a file.
* $ wp litespeed-option export
*
*/
public function export($args, $assoc_args)
{
if (isset($assoc_args['filename'])) {
$file = $assoc_args['filename'];
} else {
$file = getcwd() . '/litespeed_options_' . date('d_m_Y-His') . '.data';
}
if (!is_writable(dirname($file))) {
WP_CLI::error('Directory not writable.');
return;
}
$data = $this->cls('Import')->export(true);
if (file_put_contents($file, $data) === false) {
WP_CLI::error('Failed to create file.');
} else {
WP_CLI::success('Created file ' . $file);
}
}
/**
* Import plugin options from a file.
*
* The file must be formatted as such:
* option_key=option_value
* One per line.
* A Semicolon at the beginning of the line indicates a comment and will be skipped.
*
* ## OPTIONS
*
* <file>
* : The file to import options from.
*
* ## EXAMPLES
*
* # Import options from CURRENTDIR/options.txt
* $ wp litespeed-option import options.txt
*
*/
public function import($args, $assoc_args)
{
$file = $args[0];
if (!file_exists($file) || !is_readable($file)) {
WP_CLI::error('File does not exist or is not readable.');
}
$res = $this->cls('Import')->import($file);
if (!$res) {
WP_CLI::error('Failed to parse serialized data from file.');
}
WP_CLI::success('Options imported. [File] ' . $file);
}
/**
* Import plugin options from a remote file.
*
* The file must be formatted as such:
* option_key=option_value
* One per line.
* A Semicolon at the beginning of the line indicates a comment and will be skipped.
*
* ## OPTIONS
*
* <url>
* : The URL to import options from.
*
* ## EXAMPLES
*
* # Import options from https://domain.com/options.txt
* $ wp litespeed-option import_remote https://domain.com/options.txt
*
*/
public function import_remote($args, $assoc_args)
{
$file = $args[0];
$tmp_file = download_url($file);
if (is_wp_error($tmp_file)) {
WP_CLI::error('Failed to download file.');
return;
}
$res = $this->cls('Import')->import($tmp_file);
if (!$res) {
WP_CLI::error('Failed to parse serialized data from file.');
}
WP_CLI::success('Options imported. [File] ' . $file);
}
/**
* Reset all options to default.
*
* ## EXAMPLES
*
* # Reset all options
* $ wp litespeed-option reset
*
*/
public function reset()
{
$this->cls('Import')->reset();
}
}
presets.cls.php 0000644 00000002660 15154021372 0007526 0 ustar 00 <?php
namespace LiteSpeed\CLI;
defined('WPINC') || exit();
use LiteSpeed\Debug2;
use LiteSpeed\Preset;
use WP_CLI;
/**
* Presets CLI
*/
class Presets
{
private $__preset;
public function __construct()
{
Debug2::debug('CLI_Presets init');
$this->__preset = Preset::cls();
}
/**
* Applies a standard preset's settings.
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Apply the preset called "basic"
* $ wp litespeed-presets apply basic
*
*/
public function apply($args)
{
$preset = $args[0];
if (!isset($preset)) {
WP_CLI::error('Please specify a preset to apply.');
return;
}
return $this->__preset->apply($preset);
}
/**
* Returns sorted backup names.
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Get all backups
* $ wp litespeed-presets get_backups
*
*/
public function get_backups()
{
$backups = $this->__preset->get_backups();
foreach ($backups as $backup) {
WP_CLI::line($backup);
}
}
/**
* Restores settings from the backup file with the given timestamp, then deletes the file.
*
* ## OPTIONS
*
* ## EXAMPLES
*
* # Restore the backup with the timestamp 1667485245
* $ wp litespeed-presets restore 1667485245
*
*/
public function restore($args)
{
$timestamp = $args[0];
if (!isset($timestamp)) {
WP_CLI::error('Please specify a timestamp to restore.');
return;
}
return $this->__preset->restore($timestamp);
}
}
purge.cls.php 0000644 00000015244 15154021372 0007165 0 ustar 00 <?php
namespace LiteSpeed\CLI;
defined('WPINC') || exit();
use LiteSpeed\Core;
use LiteSpeed\Router;
use LiteSpeed\Admin_Display;
use WP_CLI;
/**
* LiteSpeed Cache Purge Interface
*/
class Purge
{
/**
* List all site domains and ids on the network.
*
* For use with the blog subcommand.
*
* ## EXAMPLES
*
* # List all the site domains and ids in a table.
* $ wp litespeed-purge network_list
*/
public function network_list($args)
{
if (!is_multisite()) {
WP_CLI::error('This is not a multisite installation!');
return;
}
$buf = WP_CLI::colorize("%CThe list of installs:%n\n");
if (version_compare($GLOBALS['wp_version'], '4.6', '<')) {
$sites = wp_get_sites();
foreach ($sites as $site) {
$buf .= WP_CLI::colorize('%Y' . $site['domain'] . $site['path'] . ':%n ID ' . $site['blog_id']) . "\n";
}
} else {
$sites = get_sites();
foreach ($sites as $site) {
$buf .= WP_CLI::colorize('%Y' . $site->domain . $site->path . ':%n ID ' . $site->blog_id) . "\n";
}
}
WP_CLI::line($buf);
}
/**
* Sends an ajax request to the site. Takes an action and the nonce string to perform.
*
* @since 1.0.14
*/
private function _send_request($action, $extra = array())
{
$data = array(
Router::ACTION => $action,
Router::NONCE => wp_create_nonce($action),
);
if (!empty($extra)) {
$data = array_merge($data, $extra);
}
$url = admin_url('admin-ajax.php');
WP_CLI::debug('URL is ' . $url);
$out = WP_CLI\Utils\http_request('GET', $url, $data);
return $out;
}
/**
* Purges all cache entries for the blog (the entire network if multisite).
*
* ## EXAMPLES
*
* # Purge Everything associated with the WordPress install.
* $ wp litespeed-purge all
*
*/
public function all($args)
{
if (is_multisite()) {
$action = Core::ACTION_QS_PURGE_EMPTYCACHE;
} else {
$action = Core::ACTION_QS_PURGE_ALL;
}
$purge_ret = $this->_send_request($action);
if ($purge_ret->success) {
WP_CLI::success(__('Purged All!', 'litespeed-cache'));
} else {
WP_CLI::error('Something went wrong! Got ' . $purge_ret->status_code);
}
}
/**
* Purges all cache entries for the blog.
*
* ## OPTIONS
*
* <blogid>
* : The blog id to purge
*
* ## EXAMPLES
*
* # In a multisite install, purge only the shop.example.com cache (stored as blog id 2).
* $ wp litespeed-purge blog 2
*
*/
public function blog($args)
{
if (!is_multisite()) {
WP_CLI::error('Not a multisite installation.');
return;
}
$blogid = $args[0];
if (!is_numeric($blogid)) {
$error = WP_CLI::colorize('%RError: invalid blog id entered.%n');
WP_CLI::line($error);
$this->network_list($args);
return;
}
$site = get_blog_details($blogid);
if ($site === false) {
$error = WP_CLI::colorize('%RError: invalid blog id entered.%n');
WP_CLI::line($error);
$this->network_list($args);
return;
}
switch_to_blog($blogid);
$purge_ret = $this->_send_request(Core::ACTION_QS_PURGE_ALL);
if ($purge_ret->success) {
WP_CLI::success(__('Purged the blog!', 'litespeed-cache'));
} else {
WP_CLI::error('Something went wrong! Got ' . $purge_ret->status_code);
}
}
/**
* Purges all cache tags related to a url.
*
* ## OPTIONS
*
* <url>
* : The url to purge.
*
* ## EXAMPLES
*
* # Purge the front page.
* $ wp litespeed-purge url https://mysite.com/
*
*/
public function url($args)
{
$data = array(
Router::ACTION => Core::ACTION_QS_PURGE,
);
$url = $args[0];
$deconstructed = wp_parse_url($url);
if (empty($deconstructed)) {
WP_CLI::error('url passed in is invalid.');
return;
}
if (is_multisite()) {
if (get_blog_id_from_url($deconstructed['host'], '/') === 0) {
WP_CLI::error('Multisite url passed in is invalid.');
return;
}
} else {
$deconstructed_site = wp_parse_url(get_home_url());
if ($deconstructed['host'] !== $deconstructed_site['host']) {
WP_CLI::error('Single site url passed in is invalid.');
return;
}
}
WP_CLI::debug('url is ' . $url);
$purge_ret = WP_CLI\Utils\http_request('GET', $url, $data);
if ($purge_ret->success) {
WP_CLI::success(__('Purged the url!', 'litespeed-cache'));
} else {
WP_CLI::error('Something went wrong! Got ' . $purge_ret->status_code);
}
}
/**
* Helper function for purging by ids.
*
* @access private
* @since 1.0.15
* @param array $args The id list to parse.
* @param string $select The purge by kind
* @param function(int $id) $callback The callback function to check the id.
*/
private function _purgeby($args, $select, $callback)
{
$filtered = array();
foreach ($args as $val) {
if (!ctype_digit($val)) {
WP_CLI::debug('[LSCACHE] Skip val, not a number. ' . $val);
continue;
}
$term = $callback($val);
if (!empty($term)) {
WP_CLI::line($term->name);
$filtered[] = in_array($callback, array('get_tag', 'get_category')) ? $term->name : $val;
} else {
WP_CLI::debug('[LSCACHE] Skip val, not a valid term. ' . $val);
}
}
if (empty($filtered)) {
WP_CLI::error('Arguments must be integer ids.');
return;
}
$str = implode(',', $filtered);
$purge_titles = array(
0 => 'Category',
1 => 'Post ID',
2 => 'Tag',
3 => 'URL',
);
WP_CLI::line('Will purge the following: [' . $purge_titles[$select] . '] ' . $str);
$data = array(
Admin_Display::PURGEBYOPT_SELECT => $select,
Admin_Display::PURGEBYOPT_LIST => $str,
);
$purge_ret = $this->_send_request(Core::ACTION_PURGE_BY, $data);
if ($purge_ret->success) {
WP_CLI::success(__('Purged!', 'litespeed-cache'));
} else {
WP_CLI::error('Something went wrong! Got ' . $purge_ret->status_code);
}
}
/**
* Purges cache tags for a WordPress tag
*
* ## OPTIONS
*
* <ids>...
* : the Term IDs to purge.
*
* ## EXAMPLES
*
* # Purge the tag ids 1, 3, and 5
* $ wp litespeed-purge tag 1 3 5
*
*/
public function tag($args)
{
$this->_purgeby($args, Admin_Display::PURGEBY_TAG, 'get_tag');
}
/**
* Purges cache tags for a WordPress category
*
* ## OPTIONS
*
* <ids>...
* : the Term IDs to purge.
*
* ## EXAMPLES
*
* # Purge the category ids 1, 3, and 5
* $ wp litespeed-purge category 1 3 5
*
*/
public function category($args)
{
$this->_purgeby($args, Admin_Display::PURGEBY_CAT, 'get_category');
}
/**
* Purges cache tags for a WordPress Post/Product
*
* @alias product
*
* ## OPTIONS
*
* <ids>...
* : the Post IDs to purge.
*
* ## EXAMPLES
*
* # Purge the post ids 1, 3, and 5
* $ wp litespeed-purge post_id 1 3 5
*
*/
public function post_id($args)
{
$this->_purgeby($args, Admin_Display::PURGEBY_PID, 'get_post');
}
}
class-wc-cli-com-command.php 0000644 00000014327 15154265270 0011744 0 ustar 00 <?php
/**
* WC_CLI_COM_Command class file.
*
* @package WooCommerce\CLI
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Allows to interact with extensions from WCCOM marketplace via CLI.
*
* @version 6.8
* @package WooCommerce
*/
class WC_CLI_COM_Command {
const APPLICATION_PASSWORD_SECTION_URL = 'https://woocommerce.com/my-account/#application-passwords';
/**
* Registers a commands for managing WooCommerce.com extensions.
*/
public static function register_commands() {
WP_CLI::add_command( 'wc com extension list', array( 'WC_CLI_COM_Command', 'list_extensions' ) );
WP_CLI::add_command( 'wc com disconnect', array( 'WC_CLI_COM_Command', 'disconnect' ) );
WP_CLI::add_command( 'wc com connect', array( 'WC_CLI_COM_Command', 'connect' ) );
}
/**
* List extensions owned by the connected site
*
* [--format]
* : If set, the command will use the specified format. Possible values are table, json, csv and yaml. By default the table format will be used.
*
* [--fields]
* : If set, the command will show only the specified fields instead of showing all the fields in the output.
*
* ## EXAMPLES
*
* # List extensions owned by the connected site in table format with all the fields
* $ wp wc com extension list
*
* # List the product slug of the extension owned by the connected site in csv format
* $ wp wc com extension list --format=csv --fields=product_slug
*
* @param array $args WP-CLI positional arguments.
* @param array $assoc_args WP-CLI associative arguments.
*/
public static function list_extensions( array $args, array $assoc_args ) {
$data = WC_Helper::get_subscriptions();
$data = array_values( $data );
$formatter = new \WP_CLI\Formatter(
$assoc_args,
array(
'product_slug',
'product_name',
'auto_renew',
'expires_on',
'expired',
'sites_max',
'sites_active',
'maxed',
)
);
$data = array_map(
function( $item ) {
$product_slug = '';
$product_url_parts = explode( '/', $item['product_url'] );
if ( count( $product_url_parts ) > 2 ) {
$product_slug = $product_url_parts[ count( $product_url_parts ) - 2 ];
}
return array(
'product_slug' => $product_slug,
'product_name' => htmlspecialchars_decode( $item['product_name'] ),
'auto_renew' => $item['autorenew'] ? 'On' : 'Off',
'expires_on' => gmdate( 'Y-m-d', $item['expires'] ),
'expired' => $item['expired'] ? 'Yes' : 'No',
'sites_max' => $item['sites_max'],
'sites_active' => $item['sites_active'],
'maxed' => $item['maxed'] ? 'Yes' : 'No',
);
},
$data
);
$formatter->display_items( $data );
}
/**
* ## OPTIONS
*
* [--yes]
* : Do not prompt for confirmation.
*
* ## EXAMPLES
*
* # Disconnect from site.
* $ wp wc com disconnect
*
* # Disconnect without prompt for confirmation.
* $ wp wc com disconnect --yes
*
* @param array $args Positional arguments to include when calling the command.
* @param array $assoc_args Associative arguments to include when calling the command.
* @return void
* @throws \WP_CLI\ExitException If WP_CLI::$capture_exit is true.
*/
public static function disconnect( array $args, array $assoc_args ) {
if ( ! WC_Helper::is_site_connected() ) {
WP_CLI::error( __( 'Your store is not connected to WooCommerce.com. Run `wp wc com connect` command.', 'woocommerce' ) );
}
WP_CLI::confirm( __( 'Are you sure you want to disconnect your store from WooCommerce.com?', 'woocommerce' ), $assoc_args );
WC_Helper::disconnect();
WP_CLI::success( __( 'You have successfully disconnected your store from WooCommerce.com', 'woocommerce' ) );
}
/**
* Connects to WooCommerce.com with application-password.
*
* [--password]
* : If set, password won't be prompt.
*
* [--force]
* : If set, site will be disconnected and a new connection will be forced.
*
* ## EXAMPLES
*
* # Connect to WCCOM using password.
* $ wp wc com connect
*
* # force connecting to WCCOM even if site is already connected.
* $ wp wc com connect --force
*
* # Pass password to comman.
* $ wp wc com connect --password=PASSWORD
*
* @param array $args Positional arguments to include when calling the command.
* @param array $assoc_args Associative arguments to include when calling the command.
*
* @return void
* @throws \WP_CLI\ExitException If WP_CLI::$capture_exit is true.
*/
public static function connect( array $args, array $assoc_args ) {
$password = \WP_CLI\Utils\get_flag_value( $assoc_args, 'password' );
$force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force', false );
if ( WC_Helper::is_site_connected() ) {
if ( $force ) {
WC_Helper::disconnect();
} else {
WP_CLI::error( __( 'Your store is already connected.', 'woocommerce' ) );
return;
}
}
if ( empty( $password ) ) {
// translators: %s is the URL for the application-password section in WooCommerce.com.
WP_CLI::log( sprintf( __( 'If you don\'t have an application password (not your account password), generate a password from %s', 'woocommerce' ), esc_url( self::APPLICATION_PASSWORD_SECTION_URL ) ) );
$password = self::ask( __( 'Connection password:', 'woocommerce' ) );
}
$password = sanitize_text_field( $password );
if ( empty( $password ) ) {
// translators: %s is the URL for the application-password section in WooCommerce.com.
WP_CLI::error( sprintf( __( 'Invalid password. Generate a new one from %s.', 'woocommerce' ), esc_url( self::APPLICATION_PASSWORD_SECTION_URL ) ) );
}
$auth = WC_Helper::connect_with_password( $password );
if ( is_wp_error( $auth ) ) {
WP_CLI::error( $auth->get_error_message() );
}
if ( WC_Helper::is_site_connected() ) {
WP_CLI::success( __( 'Store connected successfully.', 'woocommerce' ) );
}
}
/**
* We are asking a question and returning an answer as a string.
*
* @param string $question The question being prompt.
*
* @return string
*/
protected static function ask( $question ) {
// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_read_fwrite
// Adding space to question and showing it.
fwrite( STDOUT, $question . ' ' );
return trim( fgets( STDIN ) );
// phpcs:enable
}
}
class-wc-cli-com-extension-command.php 0000644 00000006317 15154265271 0013757 0 ustar 00 <?php
/**
* WC_CLI_COM_Command class file.
*
* @package WooCommerce\CLI
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Plugin_Command' ) ) {
exit;
}
/**
* Allows to interact with extensions from WCCOM marketplace via CLI.
*
* @version 6.8
* @package WooCommerce
*/
class WC_CLI_COM_Extension_Command extends Plugin_Command {
/**
* Registers a commands for managing WooCommerce.com extensions.
*/
public static function register_commands() {
WP_CLI::add_command( 'wc com extension', 'WC_CLI_COM_Extension_Command' );
}
/**
* Installs one or more plugins from wccom marketplace.
*
* ## OPTIONS
*
* <extension>...
* : One or more plugins to install. Accepts a plugin slug.
*
* [--force]
* : If set, the command will overwrite any installed version of the plugin, without prompting
* for confirmation.
*
* [--activate]
* : If set, the plugin will be activated immediately after install.
*
* [--activate-network]
* : If set, the plugin will be network activated immediately after install
*
* [--insecure]
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
*
* ## EXAMPLES
*
* # Install the latest version from woocommerce.com and activate
* $ wp wc com extension install automatewoo --activate
* Downloading install package from http://s3.amazonaws.com/bucketname/automatewoo.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef......
* Using cached file '/home/vagrant/.wp-cli/cache/plugin/automatewoo.zip'...
* Unpacking the package...
* Installing the plugin...
* Plugin installed successfully.
* Activating 'automatewoo'...
* Plugin 'automatewoo' activated.
* Success: Installed 1 of 1 plugins.
*
* # Forcefully re-install an installed plugin
* $ wp wc com extension install automatewoo --force
* Downloading install package from http://s3.amazonaws.com/bucketname/automatewoo.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef...
* Unpacking the package...
* Installing the plugin...
* Removing the old version of the plugin...
* Plugin updated successfully
* Success: Installed 1 of 1 plugins.
*
* @param array $args WP-CLI positional arguments.
* @param array $assoc_args WP-CLI associative arguments.
*/
public function install( $args, $assoc_args ) {
$subscriptions = WC_Helper_Updater::get_available_extensions_downloads_data();
$extension = reset( $args );
$extension_package_url = null;
// Remove `--version` as we don't support it.
unset( $assoc_args['version'] );
// Filter by slug.
foreach ( $subscriptions as $subscription ) {
if ( $subscription['slug'] === $extension && ! is_null( $subscription['package'] ) ) {
$extension_package_url = $subscription['package'];
break;
}
}
// No package found.
if ( is_null( $extension_package_url ) ) {
WP_CLI::warning( sprintf( 'We couldn\'t find a Subscription for \'%s\'', $extension ) );
WP_CLI\Utils\report_batch_operation_results( $this->item_type, 'install', count( $args ), 0, 1 );
return;
}
parent::install( array( $extension_package_url ), $assoc_args );
}
}
class-wc-cli-rest-command.php 0000644 00000032270 15154265273 0012143 0 ustar 00 <?php
/**
* WP_CLI_Rest_Command class file.
*
* @package WooCommerce\CLI
*/
use Automattic\Jetpack\Constants;
use Automattic\WooCommerce\Utilities\NumberUtil;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Main Command for WooCommerce CLI.
*
* Since a lot of WC operations can be handled via the REST API, we base our CLI
* off of Restful to generate commands for each WooCommerce REST API endpoint
* so most of the logic is shared.
*
* Forked from wp-cli/restful (by Daniel Bachhuber, released under the MIT license https://opensource.org/licenses/MIT).
* https://github.com/wp-cli/restful
*
* @version 3.0.0
* @package WooCommerce
*/
class WC_CLI_REST_Command {
/**
* Endpoints that have a parent ID.
* Ex: Product reviews, which has a product ID and a review ID.
*
* @var array
*/
protected $routes_with_parent_id = array(
'customer_download',
'product_review',
'order_note',
'shop_order_refund',
);
/**
* Name of command/endpoint object.
*
* @var string
*/
private $name;
/**
* Endpoint route.
*
* @var string
*/
private $route;
/**
* Main resource ID.
*
* @var int
*/
private $resource_identifier;
/**
* Schema for command.
*
* @var array
*/
private $schema;
/**
* List of supported IDs and their description (name => desc).
*
* @var array
*/
private $supported_ids = array();
/**
* Sets up REST Command.
*
* @param string $name Name of endpoint object (comes from schema).
* @param string $route Path to route of this endpoint.
* @param array $schema Schema object.
*/
public function __construct( $name, $route, $schema ) {
$this->name = $name;
preg_match_all( '#\([^\)]+\)#', $route, $matches );
$first_match = $matches[0];
$resource_id = ! empty( $matches[0] ) ? array_pop( $matches[0] ) : null;
$this->route = rtrim( $route );
$this->schema = $schema;
$this->resource_identifier = $resource_id;
if ( in_array( $name, $this->routes_with_parent_id, true ) ) {
$is_singular = substr( $this->route, - strlen( $resource_id ) ) === $resource_id;
if ( ! $is_singular ) {
$this->resource_identifier = $first_match[0];
}
}
}
/**
* Passes supported ID arguments (things like product_id, order_id, etc) that we should look for in addition to id.
*
* @param array $supported_ids List of supported IDs.
*/
public function set_supported_ids( $supported_ids = array() ) {
$this->supported_ids = $supported_ids;
}
/**
* Returns an ID of supported ID arguments (things like product_id, order_id, etc) that we should look for in addition to id.
*
* @return array
*/
public function get_supported_ids() {
return $this->supported_ids;
}
/**
* Create a new item.
*
* @subcommand create
*
* @param array $args WP-CLI positional arguments.
* @param array $assoc_args WP-CLI associative arguments.
*/
public function create_item( $args, $assoc_args ) {
$assoc_args = self::decode_json( $assoc_args );
list( $status, $body ) = $this->do_request( 'POST', $this->get_filled_route( $args ), $assoc_args );
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {
WP_CLI::line( $body['id'] );
} else {
WP_CLI::success( "Created {$this->name} {$body['id']}." );
}
}
/**
* Delete an existing item.
*
* @subcommand delete
*
* @param array $args WP-CLI positional arguments.
* @param array $assoc_args WP-CLI associative arguments.
*/
public function delete_item( $args, $assoc_args ) {
list( $status, $body ) = $this->do_request( 'DELETE', $this->get_filled_route( $args ), $assoc_args );
$object_id = isset( $body['id'] ) ? $body['id'] : '';
if ( ! $object_id && isset( $body['slug'] ) ) {
$object_id = $body['slug'];
}
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {
WP_CLI::line( $object_id );
} else {
if ( empty( $assoc_args['force'] ) ) {
WP_CLI::success( __( 'Trashed', 'woocommerce' ) . " {$this->name} {$object_id}" );
} else {
WP_CLI::success( __( 'Deleted', 'woocommerce' ) . " {$this->name} {$object_id}." );
}
}
}
/**
* Get a single item.
*
* @subcommand get
*
* @param array $args WP-CLI positional arguments.
* @param array $assoc_args WP-CLI associative arguments.
*/
public function get_item( $args, $assoc_args ) {
$route = $this->get_filled_route( $args );
list( $status, $body, $headers ) = $this->do_request( 'GET', $route, $assoc_args );
if ( ! empty( $assoc_args['fields'] ) ) {
$body = self::limit_item_to_fields( $body, $assoc_args['fields'] );
}
if ( empty( $assoc_args['format'] ) ) {
$assoc_args['format'] = 'table';
}
if ( 'headers' === $assoc_args['format'] ) {
echo wp_json_encode( $headers );
} elseif ( 'body' === $assoc_args['format'] ) {
echo wp_json_encode( $body );
} elseif ( 'envelope' === $assoc_args['format'] ) {
echo wp_json_encode(
array(
'body' => $body,
'headers' => $headers,
'status' => $status,
)
);
} else {
$formatter = $this->get_formatter( $assoc_args );
$formatter->display_item( $body );
}
}
/**
* List all items.
*
* @subcommand list
*
* @param array $args WP-CLI positional arguments.
* @param array $assoc_args WP-CLI associative arguments.
*/
public function list_items( $args, $assoc_args ) {
if ( ! empty( $assoc_args['format'] ) && 'count' === $assoc_args['format'] ) {
$method = 'HEAD';
} else {
$method = 'GET';
}
if ( ! isset( $assoc_args['per_page'] ) || empty( $assoc_args['per_page'] ) ) {
$assoc_args['per_page'] = '100';
}
list( $status, $body, $headers ) = $this->do_request( $method, $this->get_filled_route( $args ), $assoc_args );
if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) {
$items = array_column( $body, 'id' );
} else {
$items = $body;
}
if ( ! empty( $assoc_args['fields'] ) ) {
foreach ( $items as $key => $item ) {
$items[ $key ] = self::limit_item_to_fields( $item, $assoc_args['fields'] );
}
}
if ( empty( $assoc_args['format'] ) ) {
$assoc_args['format'] = 'table';
}
if ( ! empty( $assoc_args['format'] ) && 'count' === $assoc_args['format'] ) {
echo (int) $headers['X-WP-Total'];
} elseif ( 'headers' === $assoc_args['format'] ) {
echo wp_json_encode( $headers );
} elseif ( 'body' === $assoc_args['format'] ) {
echo wp_json_encode( $body );
} elseif ( 'envelope' === $assoc_args['format'] ) {
echo wp_json_encode(
array(
'body' => $body,
'headers' => $headers,
'status' => $status,
'api_url' => $this->api_url,
)
);
} else {
$formatter = $this->get_formatter( $assoc_args );
$formatter->display_items( $items );
}
}
/**
* Update an existing item.
*
* @subcommand update
*
* @param array $args WP-CLI positional arguments.
* @param array $assoc_args WP-CLI associative arguments.
*/
public function update_item( $args, $assoc_args ) {
$assoc_args = self::decode_json( $assoc_args );
list( $status, $body ) = $this->do_request( 'POST', $this->get_filled_route( $args ), $assoc_args );
if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {
WP_CLI::line( $body['id'] );
} else {
WP_CLI::success( __( 'Updated', 'woocommerce' ) . " {$this->name} {$body['id']}." );
}
}
/**
* Do a REST Request
*
* @param string $method Request method. Examples: 'POST', 'PUT', 'DELETE' or 'GET'.
* @param string $route Resource route.
* @param array $assoc_args Associative arguments passed to the originating WP-CLI command.
*
* @return array
*/
private function do_request( $method, $route, $assoc_args ) {
wc_maybe_define_constant( 'REST_REQUEST', true );
$request = new WP_REST_Request( $method, $route );
if ( in_array( $method, array( 'POST', 'PUT' ), true ) ) {
$request->set_body_params( $assoc_args );
} else {
foreach ( $assoc_args as $key => $value ) {
$request->set_param( $key, $value );
}
}
if ( Constants::is_true( 'SAVEQUERIES' ) ) {
$original_queries = is_array( $GLOBALS['wpdb']->queries ) ? array_keys( $GLOBALS['wpdb']->queries ) : array();
}
$response = rest_do_request( $request );
if ( Constants::is_true( 'SAVEQUERIES' ) ) {
$performed_queries = array();
foreach ( (array) $GLOBALS['wpdb']->queries as $key => $query ) {
if ( in_array( $key, $original_queries, true ) ) {
continue;
}
$performed_queries[] = $query;
}
usort(
$performed_queries,
function( $a, $b ) {
if ( $a[1] === $b[1] ) {
return 0;
}
return ( $a[1] > $b[1] ) ? -1 : 1;
}
);
$query_count = count( $performed_queries );
$query_total_time = 0;
foreach ( $performed_queries as $query ) {
$query_total_time += $query[1];
}
$slow_query_message = '';
if ( $performed_queries && 'wc' === WP_CLI::get_config( 'debug' ) ) {
$slow_query_message .= '. Ordered by slowness, the queries are:' . PHP_EOL;
foreach ( $performed_queries as $i => $query ) {
$i++;
$bits = explode( ', ', $query[2] );
$backtrace = implode( ', ', array_slice( $bits, 13 ) );
$seconds = NumberUtil::round( $query[1], 6 );
$slow_query_message .= <<<EOT
{$i}:
- {$seconds} seconds
- {$backtrace}
- {$query[0]}
EOT;
$slow_query_message .= PHP_EOL;
}
} elseif ( 'wc' !== WP_CLI::get_config( 'debug' ) ) {
$slow_query_message = '. Use --debug=wc to see all queries.';
}
$query_total_time = NumberUtil::round( $query_total_time, 6 );
WP_CLI::debug( "wc command executed {$query_count} queries in {$query_total_time} seconds{$slow_query_message}", 'wc' );
}
$error = $response->as_error();
if ( $error ) {
// For authentication errors (status 401), include a reminder to set the --user flag.
// WP_CLI::error will only return the first message from WP_Error, so we will pass a string containing both instead.
if ( 401 === $response->get_status() ) {
$errors = $error->get_error_messages();
$errors[] = __( 'Make sure to include the --user flag with an account that has permissions for this action.', 'woocommerce' ) . ' {"status":401}';
$error = implode( "\n", $errors );
}
WP_CLI::error( $error );
}
return array( $response->get_status(), $response->get_data(), $response->get_headers() );
}
/**
* Get Formatter object based on supplied parameters.
*
* @param array $assoc_args Parameters passed to command. Determines formatting.
* @return \WP_CLI\Formatter
*/
protected function get_formatter( &$assoc_args ) {
if ( ! empty( $assoc_args['fields'] ) ) {
if ( is_string( $assoc_args['fields'] ) ) {
$fields = explode( ',', $assoc_args['fields'] );
} else {
$fields = $assoc_args['fields'];
}
} else {
if ( ! empty( $assoc_args['context'] ) ) {
$fields = $this->get_context_fields( $assoc_args['context'] );
} else {
$fields = $this->get_context_fields( 'view' );
}
}
return new \WP_CLI\Formatter( $assoc_args, $fields );
}
/**
* Get a list of fields present in a given context
*
* @param string $context Scope under which the request is made. Determines fields present in response.
* @return array
*/
private function get_context_fields( $context ) {
$fields = array();
foreach ( $this->schema['properties'] as $key => $args ) {
if ( empty( $args['context'] ) || in_array( $context, $args['context'], true ) ) {
$fields[] = $key;
}
}
return $fields;
}
/**
* Get the route for this resource
*
* @param array $args Positional arguments passed to the originating WP-CLI command.
* @return string
*/
private function get_filled_route( $args = array() ) {
$supported_id_matched = false;
$route = $this->route;
foreach ( $this->get_supported_ids() as $id_name => $id_desc ) {
if ( 'id' !== $id_name && strpos( $route, '<' . $id_name . '>' ) !== false && ! empty( $args ) ) {
$route = str_replace( array( '(?P<' . $id_name . '>[\d]+)', '(?P<' . $id_name . '>\w[\w\s\-]*)' ), $args[0], $route );
$supported_id_matched = true;
}
}
if ( ! empty( $args ) ) {
$id_replacement = $supported_id_matched && ! empty( $args[1] ) ? $args[1] : $args[0];
$route = str_replace( array( '(?P<id>[\d]+)', '(?P<id>[\w-]+)' ), $id_replacement, $route );
}
return rtrim( $route );
}
/**
* Reduce an item to specific fields.
*
* @param array $item Item to reduce.
* @param array $fields Fields to keep.
* @return array
*/
private static function limit_item_to_fields( $item, $fields ) {
if ( empty( $fields ) ) {
return $item;
}
if ( is_string( $fields ) ) {
$fields = explode( ',', $fields );
}
foreach ( $item as $i => $field ) {
if ( ! in_array( $i, $fields, true ) ) {
unset( $item[ $i ] );
}
}
return $item;
}
/**
* JSON can be passed in some more complicated objects, like the payment gateway settings array.
* This function decodes the json (if present) and tries to get it's value.
*
* @param array $arr Array that will be scanned for JSON encoded values.
*
* @return array
*/
protected function decode_json( $arr ) {
foreach ( $arr as $key => $value ) {
if ( '[' === substr( $value, 0, 1 ) || '{' === substr( $value, 0, 1 ) ) {
$arr[ $key ] = json_decode( $value, true );
} else {
continue;
}
}
return $arr;
}
}
class-wc-cli-runner.php 0000644 00000020362 15154265274 0011063 0 ustar 00 <?php
/**
* WP_CLI_Runner class file.
*
* @package WooCommerce\CLI
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC API to WC CLI Bridge.
*
* Hooks into the REST API, figures out which endpoints come from WC,
* and registers them as CLI commands.
*
* Forked from wp-cli/restful (by Daniel Bachhuber, released under the MIT license https://opensource.org/licenses/MIT).
* https://github.com/wp-cli/restful
*
* @version 3.0.0
* @package WooCommerce
*/
class WC_CLI_Runner {
/**
* Endpoints to disable (meaning they will not be available as CLI commands).
* Some of these can either be done via WP already, or are offered with
* some other changes (like tools).
*
* @var array
*/
private static $disabled_endpoints = array(
'settings',
'settings/(?P<group_id>[\w-]+)',
'settings/(?P<group_id>[\w-]+)/batch',
'settings/(?P<group_id>[\w-]+)/(?P<id>[\w-]+)',
'system_status',
'system_status/tools',
'system_status/tools/(?P<id>[\w-]+)',
'reports',
'reports/sales',
'reports/top_sellers',
);
/**
* The version of the REST API we should target to
* generate commands.
*
* @var string
*/
private static $target_rest_version = 'v2';
/**
* Register's all endpoints as commands once WP and WC have all loaded.
*/
public static function after_wp_load() {
global $wp_rest_server;
$wp_rest_server = new WP_REST_Server();
do_action( 'rest_api_init', $wp_rest_server );
$request = new WP_REST_Request( 'GET', '/' );
$request->set_param( 'context', 'help' );
$response = $wp_rest_server->dispatch( $request );
$response_data = $response->get_data();
if ( empty( $response_data ) ) {
return;
}
// Loop through all of our endpoints and register any valid WC endpoints.
foreach ( $response_data['routes'] as $route => $route_data ) {
// Only register endpoints for WC and our target version.
if ( substr( $route, 0, 4 + strlen( self::$target_rest_version ) ) !== '/wc/' . self::$target_rest_version ) {
continue;
}
// Only register endpoints with schemas.
if ( empty( $route_data['schema']['title'] ) ) {
/* translators: %s: Route to a given WC-API endpoint */
WP_CLI::debug( sprintf( __( 'No schema title found for %s, skipping REST command registration.', 'woocommerce' ), $route ), 'wc' );
continue;
}
// Ignore batch endpoints.
if ( 'batch' === $route_data['schema']['title'] ) {
continue;
}
// Disable specific endpoints.
$route_pieces = explode( '/', $route );
$endpoint_piece = str_replace( '/wc/' . $route_pieces[2] . '/', '', $route );
if ( in_array( $endpoint_piece, self::$disabled_endpoints, true ) ) {
continue;
}
self::register_route_commands( new WC_CLI_REST_Command( $route_data['schema']['title'], $route, $route_data['schema'] ), $route, $route_data );
}
}
/**
* Generates command information and tells WP CLI about all
* commands available from a route.
*
* @param string $rest_command WC-API command.
* @param string $route Path to route endpoint.
* @param array $route_data Command data.
* @param array $command_args WP-CLI command arguments.
*/
private static function register_route_commands( $rest_command, $route, $route_data, $command_args = array() ) {
// Define IDs that we are looking for in the routes (in addition to id)
// so that we can pass it to the rest command, and use it here to generate documentation.
$supported_ids = array(
'product_id' => __( 'Product ID.', 'woocommerce' ),
'customer_id' => __( 'Customer ID.', 'woocommerce' ),
'order_id' => __( 'Order ID.', 'woocommerce' ),
'refund_id' => __( 'Refund ID.', 'woocommerce' ),
'attribute_id' => __( 'Attribute ID.', 'woocommerce' ),
'zone_id' => __( 'Zone ID.', 'woocommerce' ),
'instance_id' => __( 'Instance ID.', 'woocommerce' ),
'id' => __( 'The ID for the resource.', 'woocommerce' ),
'slug' => __( 'The slug for the resource.', 'woocommerce' ),
);
$rest_command->set_supported_ids( $supported_ids );
$positional_args = array_keys( $supported_ids );
$parent = "wc {$route_data['schema']['title']}";
$supported_commands = array();
// Get a list of supported commands for each route.
foreach ( $route_data['endpoints'] as $endpoint ) {
preg_match_all( '#\([^\)]+\)#', $route, $matches );
$resource_id = ! empty( $matches[0] ) ? array_pop( $matches[0] ) : null;
$trimmed_route = rtrim( $route );
$is_singular = substr( $trimmed_route, - strlen( $resource_id ?? '' ) ) === $resource_id;
// List a collection.
if ( array( 'GET' ) === $endpoint['methods'] && ! $is_singular ) {
$supported_commands['list'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array();
}
// Create a specific resource.
if ( array( 'POST' ) === $endpoint['methods'] && ! $is_singular ) {
$supported_commands['create'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array();
}
// Get a specific resource.
if ( array( 'GET' ) === $endpoint['methods'] && $is_singular ) {
$supported_commands['get'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array();
}
// Update a specific resource.
if ( in_array( 'POST', $endpoint['methods'], true ) && $is_singular ) {
$supported_commands['update'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array();
}
// Delete a specific resource.
if ( array( 'DELETE' ) === $endpoint['methods'] && $is_singular ) {
$supported_commands['delete'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array();
}
}
foreach ( $supported_commands as $command => $endpoint_args ) {
$synopsis = array();
$arg_regs = array();
$ids = array();
foreach ( $supported_ids as $id_name => $id_desc ) {
if ( strpos( $route, '<' . $id_name . '>' ) !== false ) {
$synopsis[] = array(
'name' => $id_name,
'type' => 'positional',
'description' => $id_desc,
'optional' => false,
);
$ids[] = $id_name;
}
}
foreach ( $endpoint_args as $name => $args ) {
if ( ! in_array( $name, $positional_args, true ) || strpos( $route, '<' . $id_name . '>' ) === false ) {
$arg_regs[] = array(
'name' => $name,
'type' => 'assoc',
'description' => ! empty( $args['description'] ) ? $args['description'] : '',
'optional' => empty( $args['required'] ),
);
}
}
foreach ( $arg_regs as $arg_reg ) {
$synopsis[] = $arg_reg;
}
if ( in_array( $command, array( 'list', 'get' ), true ) ) {
$synopsis[] = array(
'name' => 'fields',
'type' => 'assoc',
'description' => __( 'Limit response to specific fields. Defaults to all fields.', 'woocommerce' ),
'optional' => true,
);
$synopsis[] = array(
'name' => 'field',
'type' => 'assoc',
'description' => __( 'Get the value of an individual field.', 'woocommerce' ),
'optional' => true,
);
$synopsis[] = array(
'name' => 'format',
'type' => 'assoc',
'description' => __( 'Render response in a particular format.', 'woocommerce' ),
'optional' => true,
'default' => 'table',
'options' => array(
'table',
'json',
'csv',
'ids',
'yaml',
'count',
'headers',
'body',
'envelope',
),
);
}
if ( in_array( $command, array( 'create', 'update', 'delete' ), true ) ) {
$synopsis[] = array(
'name' => 'porcelain',
'type' => 'flag',
'description' => __( 'Output just the id when the operation is successful.', 'woocommerce' ),
'optional' => true,
);
}
$methods = array(
'list' => 'list_items',
'create' => 'create_item',
'delete' => 'delete_item',
'get' => 'get_item',
'update' => 'update_item',
);
$before_invoke = null;
if ( empty( $command_args['when'] ) && \WP_CLI::get_config( 'debug' ) ) {
$before_invoke = function() {
wc_maybe_define_constant( 'SAVEQUERIES', true );
};
}
WP_CLI::add_command(
"{$parent} {$command}",
array( $rest_command, $methods[ $command ] ),
array(
'synopsis' => $synopsis,
'when' => ! empty( $command_args['when'] ) ? $command_args['when'] : '',
'before_invoke' => $before_invoke,
)
);
}
}
}
class-wc-cli-tool-command.php 0000644 00000005546 15154265274 0012152 0 ustar 00 <?php
/**
* WC_CLI_Tool_Command class file.
*
* @package WooCommerce\CLI
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Hooks up our system status tools to the CLI.
*
* Forked from wp-cli/restful (by Daniel Bachhuber, released under the MIT license https://opensource.org/licenses/MIT).
* https://github.com/wp-cli/restful
*
* @version 3.0.0
* @package WooCommerce
*/
class WC_CLI_Tool_Command {
/**
* Registers just a 'list' and 'run' command to the WC CLI
* since we only want to enable certain actions on the system status
* tools endpoints.
*/
public static function register_commands() {
global $wp_rest_server;
$request = new WP_REST_Request( 'OPTIONS', '/wc/v2/system_status/tools' );
$response = $wp_rest_server->dispatch( $request );
$response_data = $response->get_data();
if ( empty( $response_data ) ) {
return;
}
$parent = 'wc tool';
$supported_commands = array( 'list', 'run' );
foreach ( $supported_commands as $command ) {
$synopsis = array();
if ( 'run' === $command ) {
$synopsis[] = array(
'name' => 'id',
'type' => 'positional',
'description' => __( 'The id for the resource.', 'woocommerce' ),
'optional' => false,
);
$method = 'update_item';
$route = '/wc/v2/system_status/tools/(?P<id>[\w-]+)';
} elseif ( 'list' === $command ) {
$synopsis[] = array(
'name' => 'fields',
'type' => 'assoc',
'description' => __( 'Limit response to specific fields. Defaults to all fields.', 'woocommerce' ),
'optional' => true,
);
$synopsis[] = array(
'name' => 'field',
'type' => 'assoc',
'description' => __( 'Get the value of an individual field.', 'woocommerce' ),
'optional' => true,
);
$synopsis[] = array(
'name' => 'format',
'type' => 'assoc',
'description' => __( 'Render response in a particular format.', 'woocommerce' ),
'optional' => true,
'default' => 'table',
'options' => array(
'table',
'json',
'csv',
'ids',
'yaml',
'count',
'headers',
'body',
'envelope',
),
);
$method = 'list_items';
$route = '/wc/v2/system_status/tools';
}
$before_invoke = null;
if ( empty( $command_args['when'] ) && WP_CLI::get_config( 'debug' ) ) {
$before_invoke = function() {
wc_maybe_define_constant( 'SAVEQUERIES', true );
};
}
$rest_command = new WC_CLI_REST_Command( 'system_status_tool', $route, $response_data['schema'] );
WP_CLI::add_command(
"{$parent} {$command}",
array( $rest_command, $method ),
array(
'synopsis' => $synopsis,
'when' => ! empty( $command_args['when'] ) ? $command_args['when'] : '',
'before_invoke' => $before_invoke,
)
);
}
}
}
class-wc-cli-tracker-command.php 0000644 00000002353 15154265275 0012622 0 ustar 00 <?php
/**
* WC_CLI_Tracker_Command class file.
*
* @package WooCommerce\CLI
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Allows access to tracker snapshot for transparency and debugging.
*
* @since 5.5.0
* @package WooCommerce
*/
class WC_CLI_Tracker_Command {
/**
* Registers a command for showing WooCommerce Tracker snapshot data.
*/
public static function register_commands() {
WP_CLI::add_command( 'wc tracker snapshot', array( 'WC_CLI_Tracker_Command', 'show_tracker_snapshot' ) );
}
/**
* Dump tracker snapshot data to screen.
*
* ## EXAMPLES
*
* wp wc tracker snapshot --format=yaml
* wp wc tracker snapshot --format=json
*
* ## OPTIONS
*
* [--format=<format>]
* : Render output in a particular format, see WP_CLI\Formatter for details.
*
* @see \WP_CLI\Formatter
* @see WC_Tracker::get_tracking_data()
* @param array $args WP-CLI positional arguments.
* @param array $assoc_args WP-CLI associative arguments.
*/
public static function show_tracker_snapshot( $args, $assoc_args ) {
$snapshot_data = WC_Tracker::get_tracking_data();
$formatter = new \WP_CLI\Formatter(
$assoc_args,
array_keys( $snapshot_data )
);
$formatter->display_items( array( $snapshot_data ) );
}
}
class-wc-cli-update-command.php 0000644 00000005102 15154265276 0012445 0 ustar 00 <?php
/**
* WC_CLI_Update_Command class file.
*
* @package WooCommerce\CLI
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Allows updates via CLI.
*
* @version 3.0.0
* @package WooCommerce
*/
class WC_CLI_Update_Command {
/**
* Registers the update command.
*/
public static function register_commands() {
WC()->call_static( WP_CLI::class, 'add_command', 'wc update', array( 'WC_CLI_Update_Command', 'update' ) );
}
/**
* Runs all pending WooCommerce database updates.
*/
public static function update() {
global $wpdb;
$wpdb->hide_errors();
include_once WC_ABSPATH . 'includes/class-wc-install.php';
include_once WC_ABSPATH . 'includes/wc-update-functions.php';
$current_db_version = get_option( 'woocommerce_db_version' );
$update_count = 0;
$callbacks = WC_Install::get_db_update_callbacks();
$callbacks_to_run = array();
foreach ( $callbacks as $version => $update_callbacks ) {
if ( version_compare( $current_db_version, $version, '<' ) ) {
foreach ( $update_callbacks as $update_callback ) {
$callbacks_to_run[] = $update_callback;
}
}
}
if ( empty( $callbacks_to_run ) ) {
// Ensure DB version is set to the current WC version to match WP-Admin update routine.
WC_Install::update_db_version();
WC()->call_static(
WP_CLI::class,
'success',
/* translators: %s Database version number */
sprintf( __( 'No updates required. Database version is %s', 'woocommerce' ), get_option( 'woocommerce_db_version' ) )
);
return;
}
WC()->call_static(
WP_CLI::class,
'log',
/* translators: 1: Number of database updates 2: List of update callbacks */
sprintf( __( 'Found %1$d updates (%2$s)', 'woocommerce' ), count( $callbacks_to_run ), implode( ', ', $callbacks_to_run ) )
);
$progress = WC()->call_function(
'WP_CLI\Utils\make_progress_bar',
__( 'Updating database', 'woocommerce' ),
count( $callbacks_to_run ) // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
);
foreach ( $callbacks_to_run as $update_callback ) {
call_user_func( $update_callback );
$update_count ++;
$progress->tick();
}
WC_Install::update_db_version();
$progress->finish();
WC_Admin_Notices::remove_notice( 'update', true );
WC()->call_static(
WP_CLI::class,
'success',
/* translators: 1: Number of database updates performed 2: Database version number */
sprintf( __( '%1$d update functions completed. Database version is %2$s', 'woocommerce' ), absint( $update_count ), get_option( 'woocommerce_db_version' ) )
);
}
}