official readme of this plugin.
* Text Domain: wp-phpmyadmin-extension
* Domain Path: /languages
* Version: 5.2.1.13
* WordPress URI: https://wordpress.org/plugins/wp-phpmyadmin-extension/
* Plugin URI: https://puvox.software/software/wordpress-plugins/?plugin=wp-phpmyadmin-extension
* Contributors: puvoxsoftware,ttodua
* Author: Puvox.software
* Author URI: https://puvox.software/
* Donate Link: https://paypal.me/Puvox
* License: GPL-3.0
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
*/
declare(strict_types=1);
namespace WpPhpMyAdminExtension
{
if (!defined('ABSPATH')) exit;
require_once( __DIR__."/library.php" );
require_once( __DIR__."/library_wp.php" );
class PluginClass extends \Puvox\wp_plugin
{
protected $required_version = "7.2.0";
public function declare_settings()
{
$this->initial_static_options =
[
'has_pro_version' => 0,
'show_opts' => true,
'show_rating_message' => true,
'show_donation_footer' => true,
'show_donation_popup' => true,
'menu_pages' => [
'first' =>[
'title' => 'WP-phpMyAdmin',
'default_managed' => 'network', // network | singlesite
'required_role' => 'install_plugins',
'level' => 'mainmenu',
'icon' => $this->helpers->baseURL.'assets/media/menu_icon.png',
'page_title' => 'WP phpMyAdmin Options page',
'tabs' => [],
],
]
];
$this->initial_user_options =
[
'randomCookieName' => "pma_".$this->helpers->random_string(16),
'randomCookieValue' => "pma_".$this->helpers->random_string(16),
'RandomFolderSuffix' => "_".$this->helpers->random_string(23),
'manual_pma_login_url' => '',
'require_ip' => true,
'hide_phma_errors' => false,
'strip_slashes' => true,
'use_https' => false,
'is_localhost' => $this->helpers->is_localhost
];
$this->is_new_php = $this->helpers->above_version($this->required_version);
}
//by default, this will is disabled per requirements. Users can enable only for themselves.
private $allow_work = true;
public function __construct_my()
{
add_action('admin_init', [$this, 'setup_definitions'], 2 );
add_action('admin_init', [$this, 'if_needs_redirect_to_pma'], 3);
add_action('wp_logout', [$this, 'logout_pma_clear'], 33 );
}
// =========================================================================== //
// =========================================================================== //
public function setup_definitions()
{
// Don't save in DB table ! this is for multi-instance installations
try{
$prefix = 'opts['RandomFolderSuffix'];
$this->file_put_contents($a, $prefix . $suffix);
}
}
catch(\Exception $ex){
_e("DIRECTORY SEEMS NOT WRITABLE! WP-PHPMYADMIN PLUGIN WILL NOT WORK. Fix the permissions, or delete the plugin.");
echo $ex->getMessage();
$this->allow_work=false;
return;
}
$this->lib_relpath = '/lib';
$this->lib_absPath = __DIR__ . $this->lib_relpath;
$this->pma_name = "phpMyAdmin". $suffix;
$this->pma_name_real = "phpMyAdmin";
$this->pma_relpath = $this->lib_relpath . '/'. $this->pma_name;
$this->pma_relpath_real = $this->lib_relpath . '/'. $this->pma_name_real;
$this->pma_abspath = __DIR__ . $this->pma_relpath;
$this->pma_abspath_real = __DIR__ . $this->pma_relpath_real;
$this->pma_mainpage_from_plugin= $this->pma_relpath.'/index.php' ;
$this->pma_mainpage_url = $this->helpers->baseURL . substr($this->pma_mainpage_from_plugin,1);
$this->pma_mainpage_path = $this->pma_abspath . '/index.php';
$this->pma_zipPath = $this->lib_absPath . '/phpMyAdmin.zip';
$this->pma_langfiles_zipPath = $this->lib_absPath . '/phpMyAdmin_langs.zip';
$this->pma_sessionfile = $this->pma_abspath . '/_session_temp.php';
$this->pma_sessionAllowfile = $this->pma_abspath . '/_session_temp_allow.php';
$this->pma_sessionDbfile = $this->pma_abspath . '/_session_temp_db_name_'. $this->helpers->array_value($_SERVER,'HTTP_HOST','undefined_server') .'.php';
$this->path_to_pma_config = $this->pma_abspath . '/config.inc.php';
$this->path_to_def_config = __DIR__ . '/default_config.php';
$this->path_to_pma_common = $this->pma_abspath . '/libraries/classes/Common.php';
$this->path_to_def_common = __DIR__ . '/default_common_inc_code.php';
//deleted targets //details: https://goo.gl/tCWdEv
$this->pma_delete_dirs = [ '/js/src', '/vendor/tecnickcom/tcpdf', '/locale', '/themes/original', '/themes/bootstrap', '/themes/metro', '/doc', '/setup', '/examples', '/install', '/js/vendor/openlayers', '/vendor/phpmyadmin/sql-parser/locale']; //
$this->pma_delete_files = ['/ChangeLog', '/composer.lock', '/yarn.lock'];
$this->pma_create_files = ['/vendor/tecnickcom/tcpdf/tcpdf.php'];
$this->conflict_file_1 = $this->pma_abspath . '/vendor/phpmyadmin/motranslator/src/functions.php';
$this->replace_export_pdf_file= $this->pma_abspath . '/libraries/classes/Pdf.php';
}
private function installed() {
return !(is_dir($this->pma_abspath_real) && !is_dir($this->pma_abspath) );
}
private function initialize_unpacked_pma()
{
if (!$this->installed())
{
// avoid simultaneous re-creations caused by WP load from other instances
$this->lockFile=__DIR__."/install_lock.txt";
$this->locker = fopen( $this->lockFile, "w+");
if (flock($this->locker,LOCK_EX))
{
if(!$this->installed()) //check again after LOCK
{
$this->helpers->try_increase_exec_time(120);
//rename files
$dir = $this->pma_abspath_real; // $this->getPMA_FolderName();
// private function getPMA_FolderName(){
// $x = glob($this->lib_absPath.'/phpMyAdmin*', GLOB_ONLYDIR); return (!empty($x) ? $x[0] : "");
// }
if(!empty($dir) && !rename($dir, $this->pma_abspath )) {
exit(__('Failure: can\'t rename '.$dir.' to '.$this->pma_abspath.'. Either do it manually from FTP, or try completely re-install the plugin.', 'wp-phpmyadmin-extension') );
usleep(500000);
}
// delete extra directories
foreach($this->pma_delete_dirs as $eachDir){
$fullPath = $this->helpers->realpath($this->pma_abspath.'/'.$eachDir.'/');
if( is_dir($fullPath) ){
$this->helpers->file->delete_directory($fullPath);
}
}
// delete extra files
foreach($this->pma_delete_files as $eachFile){
$fullPath = $this->pma_abspath.'/'.$eachDir.'/';
if( file_exists($fullPath) ){
unlink($fullPath);
}
}
// strip-out PDF export functionality (because we have removed technikPdf package from vendor-libraroes to save space)
$this->file_put_contents($this->replace_export_pdf_file, 'pma_create_files as $eachFile){
$file = $this->pma_abspath.'/'.$eachFile; $this->helpers->file->create_directory( dirname($file) );
$this->file_put_contents($file,"");
}
// create config
if(is_admin())
{
$force = false;
if( $this->helpers->is_localhost != $this->opts['is_localhost']){
$force = true;
$this->opts['is_localhost']=$this->helpers->is_localhost;
$this->update_opts();
}
// MY NOTE: config.inc.php should alwyas be in pma folder
// include_once( dirname( dirname(dirname( dirname(__DIR__) ) ) ).'/wp_phpmyadmin_config.inc.php' );
if(!file_exists($this->path_to_pma_config) || $force)
{
$content = file_get_contents($this->path_to_def_config);
$content = str_replace('___ALLOWNOPASS___', ($this->helpers->is_localhost ? "true" : "false"), $content);
$content = str_replace('___BLOWFISHSECRET___', '\''. addslashes($this->create_blowfish_secret()).'\'', $content);
$content = str_replace('___LANG___', '\''.$this->static_settings['lang'].'\'', $content);
$content = str_replace('___DBARRAY___', '[file_get_contents(__DIR__."/_session_temp_db_name_".$_SERVER["HTTP_HOST"].".php")]', $content); //DB_NAME //$_COOKIE["pma_DB_NAME"]
$uri_to_index = $this->helpers->slash_normalize_url($this->helpers->remove_domain($this->helpers->baseURL . $this->pma_relpath));
$content = str_replace('___PmaAbsoluteUri___', "'$uri_to_index'", $content);
$content = str_replace('___SignOnUri___', "'".$this->pmaLoginUrl()."'", "$content");
$content = str_replace('___LogoutURL___', "'".$this->pmaLogoutUrl()."'", "$content");
//$content = str_replace( '___RELATIVEPATHTOFOLDER___', '\'/plugins/wp-phpmyadmin/'.$this->pma_dirname.'\'', $content);
//
//$content = str_replace('___RESTRICTORCOOKIENAME___','\''.$this->opts['randomCookieName'].'\'', $content);
//$content = str_replace('___RESTRICTORCOOKIEVALUE___','\''.$this->opts['randomCookieValue'].'\'', $content);
//solution for socket connections too , like : 'localhost:/run/mysqld/mysqld10.sock'
$dbhost = DB_HOST;
$dbport = '';
$connectionType ='tcp';
$socket ='';
// if custom format, i.e. .sock/mysql or 123.123.123.123:xxx
if( stripos($dbhost, ':')!==false )
{
if ( stripos($dbhost, '.sock')!==false || stripos($dbhost, '/mysql')!==false )
{
preg_match('/(.*?):(.*)/', $dbhost, $n);
if (!empty($n[2]))
{
$dbhost = $n[1];
$connectionType = 'socket';
$socket = $n[2];
}
}
else
{
preg_match('/(.*?):(.*)/', $dbhost, $n);
if (!empty($n[2]))
{
$dbhost = $n[1];
$dbport = $n[2];
}
}
}
$content = str_replace('___HOSTADR___', "'$dbhost'", $content);
$content = str_replace('___PORTADR___', "'$dbport'", $content);
$content = str_replace('___CONNECTIONTYPE___', "'$connectionType'", $content);
$content = str_replace('___SOCKET___', "'$socket'", $content);
$this->file_put_contents($this->path_to_pma_config, $content);
}
}
//add content into common.inc
$cont = file_get_contents($this->path_to_pma_common);
$flag = "//_WPMA__REPLACED_\r\n";
if ( stripos($cont,$flag) === false )
{
$addition= $flag . 'require_once(__DIR__."/../../../../'.basename($this->path_to_def_common).'"); WP_PHPMYADMIN_CONFIG_ADDITION(__DIR__);';
if (stripos($cont,$phrase='ServerRequestFactory::createFromGlobals();')!==false) {
$common_inc_content_new = $this->helpers->str_replace_first( $phrase, $phrase."\r\n".$addition, $cont );
}
else
{
wp_die(__("internal issue of WP-phpMyAdmin plugin, as seems PMA changed their internal approach. Please report us by opening a ticket at https://wordpress.org/support/plugin/wp-phpmyadmin-extension/"));
}
$this->file_put_contents( $this->path_to_pma_common, $common_inc_content_new);
}
// rename conflicting function named __( //old method: pastebin_com/raw/v652Ef1A
//$file = $this->pma_abspath .'/vendor/phpmyadmin/motranslator/src/functions.php';
//file_put_contents( $file, str_replace('function __(', 'if (!function_exists("__")) { function __($str) { return __RENAMED(function __RENAMED(', file_get_contents($file) ) );
//$this->disable_dir_browsing_in_htaccess( $this->lib_absPath );
}
flock($this->locker,LOCK_UN);
} //end locker
fclose($this->locker);
if (file_exists($this->lockFile)) @unlink($this->lockFile);
}
}
//from PMA
// same as: public function generateRandom($length)
private function create_blowfish_secret(){
$blowfishSecret = '';
$random_func = (function_exists('openssl_random_pseudo_bytes')) ? 'openssl_random_pseudo_bytes' : 'phpseclib\\Crypt\\Random::string';
while (strlen($blowfishSecret) < 32) {
$byte = $random_func(1);
// We want only ASCII chars
if (ord($byte) > 32 && ord($byte) < 127) {
$blowfishSecret .= $byte;
}
}
return $blowfishSecret;
}
// ======
public function create_session_file($force=false){
$new_content = ''.time().', "name"=>"wp_pma_'.$this->helpers->random_string(14).'", "value"=>"wp_pma_'.$this->helpers->random_string(23).'", "require_ip"=>'.($this->opts['require_ip']? 'true':'false').', "ip"=>"'.$this->helpers->ip.'", "strip_slashes"=>'. ($this->opts['strip_slashes']? 'true':'false') .'];';
$create=false;
if($force || !file_exists($this->pma_sessionfile)){
$create= true;
}
else{
include($this->pma_sessionfile);
//don't reset if login happens in last 30 seconds again.
if( $sess_vars["time"] + 30 < time() ){
$create = true;
}
}
if ($create) $this->file_put_contents($this->pma_sessionfile, $new_content);
}
public function session_pre_pma(){
// Use cookies for session
ini_set('session.use_cookies', 'true');
// Change this to true if using phpMyAdmin over https
$secure_cookie = $this->helpers->is_https;
// Need to have cookie visible from parent directory
session_set_cookie_params(0, '/', '', $secure_cookie, true);
// Create signon session
$session_name = 'SignonSession';
session_name($session_name);
// Uncomment and change the following line to match your $cfg['SessionSavePath']
session_save_path(sys_get_temp_dir());
session_start();
}
public function create_signon($login){
try{
// https://docs.phpmyadmin.net/en/latest/setup.html#signon-authentication-mode '
$this->session_pre_pma();
if ($login)
{
// Store there credentials
$_SESSION['PMA_single_signon_user'] = DB_USER;
$_SESSION['PMA_single_signon_password'] = DB_PASSWORD;
// the below are predefined in config.inc
//$_SESSION['PMA_single_signon_host'] = '127.0.0.1';
//$_SESSION['PMA_single_signon_port'] = 3306;
// Update another field of server configuration
$_SESSION['PMA_single_signon_cfgupdate'] = ['verbose' => 'Signon test'];
$_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(rand()), true));
$id = session_id();
//header('Location: ../index.php');
} else {
unset($_SESSION['PMA_single_signon_user']);
unset($_SESSION['PMA_single_signon_password']);
unset($_SESSION['PMA_single_signon_cfgupdate']);
unset($_SESSION['PMA_single_signon_HMAC_secret']);
}
// Close that session
if (!session_write_close() ){
exit(__("Can not create the session file using 'session_write_close'. Only after fixing that, you will be able to enter PMA"));
}
}
catch (\Exception $e){
exit(__("Error: could not create the session file. " .$e->getMessage()));
}
}
public function create_userip_file(){
$this->file_put_contents($this->pma_sessionAllowfile, $this->helpers->ip);
$this->file_put_contents($this->pma_sessionDbfile, DB_NAME);
include($this->pma_sessionfile);
if(empty($_COOKIE[$sess_vars["name"]]) || $_COOKIE[$sess_vars["name"]] != $sess_vars["value"] ){
$hours = 3*60*60;
$this->helpers->set_cookie($sess_vars["name"], $sess_vars["value"], $hours);
$this->helpers->set_cookie("pma_DB_NAME", DB_NAME, $hours);
}
}
public function replace_in_file($file, $from_pattern, $to){
if(file_exists($file))
{
$cont= file_get_contents($file);
$new_cont= preg_replace($from_pattern, $to, $cont);
$this->file_put_contents($file, $new_cont);
}
}
public function checkShowLastLoginError(){
// just my addition, to
$this->session_pre_pma();
if (isset($_SESSION['PMA_single_signon_error_message'])) {
_e("Go back to plugin's dashboard page. Last PMA login error was:" . $_SESSION['PMA_single_signon_error_message']);
exit;
}
session_write_close();
}
public function logout_pma_clear($user_id){
// clear PMA signon
$this->create_signon(false);
}
public function pmaLoginUrl(){
return trailingslashit(admin_url()).'?rand='.rand(1,99999999).'&goto_wp_phpmyadmin=1';
}
public function pmaLogoutUrl(){
return trailingslashit(admin_url()).'?rand='.rand(1,99999999).'&pma_logout=1';
}
// https://docs.phpmyadmin.net/en/latest/setup.html#signon-authentication-mode
public function if_needs_redirect_to_pma()
{
// for manual logout
if(isset($_GET['pma_logout']))
{
$this->create_signon(false);
wp_die("Logout done!");
}
if( isset($_GET['goto_wp_phpmyadmin']) ){
if( current_user_can('install_plugins') && current_user_can("manage_options") )
{
$this->checkShowLastLoginError();
if (empty($this->opts['ssl_error_shown'])) {
$this->opts['ssl_error_shown']=1; $this->update_opts();
}
if(isset($_GET['hosting_pma'])){
$m_url = sanitize_url($this->opts['manual_pma_login_url']);
if( stripos( $m_url , '/index.php') === false){
$m_url .= ! $this->helpers->ends_with($m_url, '/') ? '/index.php' : 'index.php';
}
$this->chosen_server_url = $m_url;
}
else{
$this->chosen_server_url = $this->pma_mainpage_url;
//$this->helpers->disable_cache(true);
// when chosen our installed pma-url, then we can use protection too
// p.s. SESSIONS DOESNT WORK for some reasons, probably WP resets then in 'shutdown' and start... SO WE USE COOKIES...
$this->create_session_file();
$this->create_userip_file();
$this->create_signon(true);
//debug :: $this->helpers->set_cookie('xxxxxxx', json_encode($_SESSION) );
}
$this->helpers->php_redirect($this->chosen_server_url);
// old methods don't work : https://pastebin_com/ERNBRY56 && https://pastebin_com/5ydiUKsj
exit;
}
else{
wp_die(__("You do not have enough privilegges to open this page."));
}
}
return;
}
public function opts_page_output()
{
$this->settings_page_part("start", "first");
?>
setup_definitions();
if ($this->allow_work) $this->initialize_unpacked_pma();
else _e("WP-PHPMYADMIN can not work on your server. Try to reinstall plugin and note any issues it might show.");
?>
active_tab=="Options")
{
//if form updated
if( $this->checkSubmission() )
{
$this->opts['manual_pma_login_url'] = sanitize_url($_POST[ $this->plugin_slug ]['manual_pma_login_url']);
$this->opts['use_https'] = isset($_POST[ $this->plugin_slug ]['use_https']);
$this->opts['strip_slashes'] = isset($_POST[ $this->plugin_slug ]['strip_slashes']);
$this->opts['require_ip'] = isset($_POST[ $this->plugin_slug ]['require_ip']);
$this->opts['hide_phma_errors'] = isset($_POST[ $this->plugin_slug ]['hide_phma_errors']);
$this->update_opts();
if (isset($_POST[ $this->plugin_slug ]['install_languages'])) {
$this->obtainLanguagePackages();
}
//reflect changes immediately
$this->replace_in_file($this->path_to_pma_config, '/\$cfg\[\WSendErrorReports\W\]\s+=\s+\W(.*?)\W/', '$cfg["SendErrorReports"] = \''. ($this->opts['hide_phma_errors'] ? 'never':'ask') .'\'');
}
$this->ssl_notice_msg = __("This is a one-time message!
Seems that your site doesn\\'t use HTTPS. We strongly recommend to use HTTPS (SSL) with PhpMyAdmin (Automatic login at this moment works only for HTTPS). To use this feature, then you should bypass the SSL warning on the next page, like shown on this screenshot: ", "wp-phpmyadmin-extension") ."
https:// prefix and then try to enter PhpMyAdmin", "wp-phpmyadmin-extension");
$url_to_open = $this->pmaLoginUrl();
?>
settings_page_part("end", "");
}
private function checkNeedLanguageFiles () {
return (!is_dir($this->pma_abspath.'/locale'));
}
private function obtainLanguagePackages () {
$lang_files_zip = 'https://plugins.svn.wordpress.org/wp-phpmyadmin-extension/assets/pma-locales.zip';
wp_remote_get( $url=$lang_files_zip, ['timeout'=>300, 'stream'=>true, 'filename'=>$this->pma_langfiles_zipPath ] );
$this->helpers->unzip($this->pma_langfiles_zipPath, $this->pma_abspath);
usleep(500000);
unlink($this->pma_langfiles_zipPath);
}
public function backend_call($act)
{
// removed : https://pastebin_com/Pi6jCbrf
}
public function file_put_contents($path, $content, $third = null)
{
$dir = dirname($path);
if(!is_dir($dir)) $this->helpers->file->create_directory($dir);
$path = $this->helpers->realpath($path);
$content = is_array($content) || is_object($content) ? json_encode($content) : $content;
if ( is_writable( $dir ) ){
return file_put_contents($path, $content, ($third==null ? LOCK_EX : $third | LOCK_EX) );
}
else{
throw new \Exception("This plugin doesn't have a permission to write file at:". $path);
}
}
} // End Of Class
$GLOBALS[__NAMESPACE__] = new PluginClass();
} // End Of NameSpace
?>