From 5106760db7af0097770295c38b5771e679b56656 Mon Sep 17 00:00:00 2001 From: Thang Hoang Van Date: Wed, 19 Mar 2014 23:58:52 +0700 Subject: [PATCH] First commit --- class/MainWPBackup.class.php | 640 ++++ class/MainWPChild.class.php | 3092 ++++++++++++++++++ class/MainWPChildDB.class.php | 119 + class/MainWPChildServerInformation.class.php | 450 +++ class/MainWPClone.class.php | 1174 +++++++ class/MainWPCloneInstall.class.php | 776 +++++ class/MainWPHeatmapTracker.class.php | 399 +++ class/MainWPHelper.class.php | 536 +++ class/MainWPKeywordLinks.class.php | 775 +++++ class/MainWPSecurity.class.php | 375 +++ class/index.html | 0 index.html | 0 js/heatmap.js | 362 ++ js/heatmapinit.js | 41 + js/index.html | 0 js/keywordlinks.js | 22 + js/tracker.js | 62 + languages/mainwp-child-bs_BA.mo | Bin 0 -> 8334 bytes languages/mainwp-child-bs_BA.po | 411 +++ languages/mainwp-child-de_DE.mo | Bin 0 -> 9288 bytes languages/mainwp-child-de_DE.po | 735 +++++ languages/mainwp-child-hr_HR.mo | Bin 0 -> 8378 bytes languages/mainwp-child-hr_HR.po | 411 +++ languages/mainwp-child-sr_CS.mo | Bin 0 -> 8334 bytes languages/mainwp-child-sr_CS.po | 411 +++ languages/mainwp-child-sr_RS.mo | Bin 0 -> 8334 bytes languages/mainwp-child-sr_RS.po | 411 +++ mainwp-child.php | 35 + readme.txt | 157 + 29 files changed, 11394 insertions(+) create mode 100644 class/MainWPBackup.class.php create mode 100644 class/MainWPChild.class.php create mode 100644 class/MainWPChildDB.class.php create mode 100644 class/MainWPChildServerInformation.class.php create mode 100644 class/MainWPClone.class.php create mode 100644 class/MainWPCloneInstall.class.php create mode 100644 class/MainWPHeatmapTracker.class.php create mode 100644 class/MainWPHelper.class.php create mode 100644 class/MainWPKeywordLinks.class.php create mode 100644 class/MainWPSecurity.class.php create mode 100644 class/index.html create mode 100644 index.html create mode 100644 js/heatmap.js create mode 100644 js/heatmapinit.js create mode 100644 js/index.html create mode 100644 js/keywordlinks.js create mode 100644 js/tracker.js create mode 100644 languages/mainwp-child-bs_BA.mo create mode 100644 languages/mainwp-child-bs_BA.po create mode 100644 languages/mainwp-child-de_DE.mo create mode 100644 languages/mainwp-child-de_DE.po create mode 100644 languages/mainwp-child-hr_HR.mo create mode 100644 languages/mainwp-child-hr_HR.po create mode 100644 languages/mainwp-child-sr_CS.mo create mode 100644 languages/mainwp-child-sr_CS.po create mode 100644 languages/mainwp-child-sr_RS.mo create mode 100644 languages/mainwp-child-sr_RS.po create mode 100644 mainwp-child.php create mode 100644 readme.txt diff --git a/class/MainWPBackup.class.php b/class/MainWPBackup.class.php new file mode 100644 index 00000000..0f552aa2 --- /dev/null +++ b/class/MainWPBackup.class.php @@ -0,0 +1,640 @@ +file_descriptors = $file_descriptors; + + $dirs = MainWPHelper::getMainWPDir('backup'); + $backupdir = $dirs[0]; + if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR', $backupdir); + + $timestamp = time(); + if ($filePrefix != '') $filePrefix .= '-'; + $filepath = $backupdir . 'backup-' . $filePrefix . $timestamp . '.zip'; + $fileurl = $dirs[1] . 'backup-' . $filePrefix . $timestamp . '.zip'; + + if ($dh = opendir($backupdir)) + { + while (($file = readdir($dh)) !== false) + { + if ($file != '.' && $file != '..' && preg_match('/^backup-(.*).zip/', $file)) + { + @unlink($backupdir . $file); + } + } + closedir($dh); + } + + if (!$addConfig) + { + if (!in_array(str_replace(ABSPATH, '', WP_CONTENT_DIR), $excludes) && !in_array('wp-admin', $excludes) && !in_array(WPINC, $excludes)) + { + $addConfig = true; + $includeCoreFiles = true; + } + } + + $time = 300; /*300 seconds = 5 minutes*/ + $mem = '512M'; + @ini_set('memory_limit', $mem); + @ini_set('max_execution_time', $time); + + $success = false; + if ($this->checkZipSupport() && $this->createZipFullBackup($filepath, $excludes, $addConfig, $includeCoreFiles)) + { + $success = true; + } + else if ($this->checkZipConsole() && $this->createZipConsoleFullBackup($filepath, $excludes, $addConfig, $includeCoreFiles)) + { + $success = true; + } + else if ($this->createZipPclFullBackup2($filepath, $excludes, $addConfig, $includeCoreFiles)) + { + $success = true; + } + + return ($success) ? array( + 'timestamp' => $timestamp, + 'file' => $fileurl, + 'filesize' => filesize($filepath) + ) : false; + } + + /** + * Check for default PHP zip support + * + * @return bool + */ + public function checkZipSupport() + { + return class_exists('ZipArchive'); + } + + /** + * Check if we could run zip on console + * + * @return bool + */ + public function checkZipConsole() + { + return false; +// return function_exists('system'); + } + + /** + * Create full backup using default PHP zip library + * + * @param string $filepath File path to create + * @return bool + */ + public function createZipFullBackup($filepath, $excludes, $addConfig = false, $includeCoreFiles = false) + { + $this->zip = new ZipArchive(); + $this->zipArchiveFileCount = 0; + $this->zipArchiveSizeCount = 0; + $this->zipArchiveFileName = $filepath; + $zipRes = $this->zip->open($filepath, ZipArchive::CREATE); + if ($zipRes) + { + $nodes = glob(ABSPATH . '*'); + if (!$includeCoreFiles) + { + $coreFiles = array('favicon.ico', 'index.php', 'license.txt', 'readme.html', 'wp-activate.php', 'wp-app.php', 'wp-blog-header.php', 'wp-comments-post.php', 'wp-config.php', 'wp-config-sample.php', 'wp-cron.php', 'wp-links-opml.php', 'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-pass.php', 'wp-register.php', 'wp-settings.php', 'wp-signup.php', 'wp-trackback.php', 'xmlrpc.php'); + foreach ($nodes as $key => $node) + { + if (MainWPHelper::startsWith($node, ABSPATH . WPINC)) + { + unset($nodes[$key]); + } + else if (MainWPHelper::startsWith($node, ABSPATH . basename(admin_url('')))) + { + unset($nodes[$key]); + } + else + { + foreach ($coreFiles as $coreFile) + { + if ($node == ABSPATH . $coreFile) unset($nodes[$key]); + } + } + } + unset($coreFiles); + } + + $this->createBackupDB(dirname($filepath) . DIRECTORY_SEPARATOR . 'dbBackup.sql'); + $this->addFileToZip(dirname($filepath) . DIRECTORY_SEPARATOR . 'dbBackup.sql', basename(WP_CONTENT_DIR) . '/' . 'dbBackup.sql'); + if (file_exists(ABSPATH . '.htaccess')) $this->addFileToZip(ABSPATH . '.htaccess', 'mainwp-htaccess'); + foreach ($nodes as $node) + { + if ($excludes == null || !in_array(str_replace(ABSPATH, '', $node), $excludes)) + { + if (is_dir($node)) + { + $this->zipAddDir($node, $excludes); + } + else if (is_file($node)) + { + $this->addFileToZip($node, str_replace(ABSPATH, '', $node)); + } + } + } + + if ($addConfig) + { + global $wpdb; + $plugins = array(); + $dir = WP_CONTENT_DIR . '/plugins/'; + $fh = @opendir($dir); + while ($entry = @readdir($fh)) + { + if (!@is_dir($dir . $entry)) continue; + if (($entry == '.') || ($entry == '..')) continue; + $plugins[] = $entry; + } + @closedir($fh); + + $themes = array(); + $dir = WP_CONTENT_DIR . '/themes/'; + $fh = @opendir($dir); + while ($entry = @readdir($fh)) + { + if (!@is_dir($dir . $entry)) continue; + if (($entry == '.') || ($entry == '..')) continue; + $themes[] = $entry; + } + @closedir($fh); + + $string = base64_encode(serialize(array('siteurl' => get_option('siteurl'), + 'home' => get_option('home'), + 'abspath' => ABSPATH, + 'prefix' => $wpdb->prefix, + 'lang' => WPLANG, + 'plugins' => $plugins, + 'themes' => $themes))); + + $this->addFileFromStringToZip('clone/config.txt', $string); + } + + $return = $this->zip->close(); + @unlink(dirname($filepath) . DIRECTORY_SEPARATOR . 'dbBackup.sql'); + + return $return; + } + return false; + } + + /** + * Create full backup using pclZip library + * + * @param string $filepath File path to create + * @return bool + */ + public function createZipPclFullBackup($filepath, $excludes, $addConfig, $includeCoreFiles) + { + require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php'); + $this->zip = new PclZip($filepath); + $nodes = glob(ABSPATH . '*'); + if (!$includeCoreFiles) + { + $coreFiles = array('favicon.ico', 'index.php', 'license.txt', 'readme.html', 'wp-activate.php', 'wp-app.php', 'wp-blog-header.php', 'wp-comments-post.php', 'wp-config.php', 'wp-config-sample.php', 'wp-cron.php', 'wp-links-opml.php', 'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-pass.php', 'wp-register.php', 'wp-settings.php', 'wp-signup.php', 'wp-trackback.php', 'xmlrpc.php'); + foreach ($nodes as $key => $node) + { + if (MainWPHelper::startsWith($node, ABSPATH . WPINC)) + { + unset($nodes[$key]); + } + else if (MainWPHelper::startsWith($node, ABSPATH . basename(admin_url('')))) + { + unset($nodes[$key]); + } + else + { + foreach ($coreFiles as $coreFile) + { + if ($node == ABSPATH . $coreFile) unset($nodes[$key]); + } + } + } + unset($coreFiles); + } + + $this->createBackupDB(dirname($filepath) . DIRECTORY_SEPARATOR . 'dbBackup.sql'); + $error = false; + if (($rslt = $this->zip->add(dirname($filepath) . DIRECTORY_SEPARATOR . 'dbBackup.sql', PCLZIP_OPT_REMOVE_PATH, dirname($filepath), PCLZIP_OPT_ADD_PATH, basename(WP_CONTENT_DIR))) == 0) $error = true; + + @unlink(dirname($filepath) . DIRECTORY_SEPARATOR . 'dbBackup.sql'); + if (!$error) + { + foreach ($nodes as $node) + { + if ($excludes == null || !in_array(str_replace(ABSPATH, '', $node), $excludes)) + { + if (is_dir($node)) + { + if (!$this->pclZipAddDir($node, $excludes)) + { + $error = true; + break; + } + } + else if (is_file($node)) + { + if (($rslt = $this->zip->add($node, PCLZIP_OPT_REMOVE_PATH, ABSPATH)) == 0) + { + $error = true; + break; + } + } + } + } + } + + if ($addConfig) + { + global $wpdb; + $string = base64_encode(serialize(array('siteurl' => get_option('siteurl'), + 'home' => get_option('home'), 'abspath' => ABSPATH, 'prefix' => $wpdb->prefix, 'lang' => WPLANG))); + + $this->addFileFromStringToPCLZip('clone/config.txt', $string, $filepath); + } + + if ($error) + { + @unlink($filepath); + return false; + } + return true; + } + + function copy_dir( $nodes, $excludes, $backupfolder ) { + if (!is_array($nodes)) return; + + foreach ($nodes as $node) + { + if ($excludes == null || !in_array(str_replace(ABSPATH, '', $node), $excludes)) + { + if (is_dir($node)) + { + if( !file_exists( str_replace(ABSPATH, $backupfolder, $node) ) ) + @mkdir ( str_replace(ABSPATH, $backupfolder, $node) ); + + $newnodes = glob($node . DIRECTORY_SEPARATOR . '*'); + $this->copy_dir($newnodes, $excludes, $backupfolder); + unset($newnodes); + } + else if (is_file($node)) + { + @copy($node, str_replace(ABSPATH, $backupfolder, $node)); + } + } + } + } + + public function createZipPclFullBackup2($filepath, $excludes, $addConfig, $includeCoreFiles) + { + global $classDir; + //Create backup folder + $backupFolder = dirname($filepath) . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR; + @mkdir($backupFolder); + + //Create DB backup + $this->createBackupDB($backupFolder . 'dbBackup.sql'); + + //Copy installation to backup folder + $nodes = glob(ABSPATH . '*'); + if (!$includeCoreFiles) + { + $coreFiles = array('favicon.ico', 'index.php', 'license.txt', 'readme.html', 'wp-activate.php', 'wp-app.php', 'wp-blog-header.php', 'wp-comments-post.php', 'wp-config.php', 'wp-config-sample.php', 'wp-cron.php', 'wp-links-opml.php', 'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-pass.php', 'wp-register.php', 'wp-settings.php', 'wp-signup.php', 'wp-trackback.php', 'xmlrpc.php'); + foreach ($nodes as $key => $node) + { + if (MainWPHelper::startsWith($node, ABSPATH . WPINC)) + { + unset($nodes[$key]); + } + else if (MainWPHelper::startsWith($node, ABSPATH . basename(admin_url('')))) + { + unset($nodes[$key]); + } + else + { + foreach ($coreFiles as $coreFile) + { + if ($node == ABSPATH . $coreFile) unset($nodes[$key]); + } + } + } + unset($coreFiles); + } + $this->copy_dir($nodes, $excludes, $backupFolder); + unset($nodes); + + //Zip this backup folder.. + require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php'); + $this->zip = new PclZip($filepath); + $this->zip->create($backupFolder, PCLZIP_OPT_REMOVE_PATH, $backupFolder); + if ($addConfig) + { + global $wpdb; + $string = base64_encode(serialize(array('siteurl' => get_option('siteurl'), + 'home' => get_option('home'), 'abspath' => ABSPATH, 'prefix' => $wpdb->prefix, 'lang' => WPLANG))); + + $this->addFileFromStringToPCLZip('clone/config.txt', $string, $filepath); + } + //Remove backup folder + MainWPHelper::delete_dir($backupFolder); + return true; + } + + /** + * Recursive add directory for default PHP zip library + */ + public function zipAddDir($path, $excludes) + { + $this->zip->addEmptyDir(str_replace(ABSPATH, '', $path)); + + if (file_exists(rtrim($path, '/') . '/.htaccess')) $this->addFileToZip(rtrim($path, '/') . '/.htaccess', rtrim(str_replace(ABSPATH, '', $path), '/') . '/mainwp-htaccess'); + + $nodes = glob(rtrim($path, '/') . '/*'); + if (empty($nodes)) return true; + + foreach ($nodes as $node) + { + if ($excludes == null || !in_array(str_replace(ABSPATH, '', $node), $excludes)) + { + if (is_dir($node)) + { + $this->zipAddDir($node, $excludes); + } + else if (is_file($node)) + { + $this->addFileToZip($node, str_replace(ABSPATH, '', $node)); + } + } + } + } + + public function pclZipAddDir($path, $excludes) + { + $error = false; + $nodes = glob(rtrim($path, '/') . '/*'); + if (empty($nodes)) return true; + + foreach ($nodes as $node) + { + if ($excludes == null || !in_array(str_replace(ABSPATH, '', $node), $excludes)) + { + if (is_dir($node)) + { + if (!$this->pclZipAddDir($node, $excludes)) + { + $error = true; + break; + } + } + else if (is_file($node)) + { + if (($rslt = $this->zip->add($node, PCLZIP_OPT_REMOVE_PATH, ABSPATH)) == 0) + { + $error = true; + break; + } + } + } + } + return !$error; + } + + function addFileFromStringToZip($file, $string) + { + return $this->zip->addFromString($file, $string); + } + + public function addFileFromStringToPCLZip($file, $string, $filepath) + { + $file = preg_replace("/(?:\.|\/)*(.*)/", "$1", $file); + $localpath = dirname($file); + $tmpfilename = dirname($filepath). '/' . basename($file); + if (false !== file_put_contents($tmpfilename, $string)) { + $this->zip->delete(PCLZIP_OPT_BY_NAME, $file); + $add = $this->zip->add($tmpfilename, + PCLZIP_OPT_REMOVE_PATH, dirname($filepath), + PCLZIP_OPT_ADD_PATH, $localpath); + unlink($tmpfilename); + if (!empty($add)) { + return true; + } + } + return false; + } + + function addFileToZip($path, $zipEntryName) + { + // this would fail with status ZIPARCHIVE::ER_OPEN + // after certain number of files is added since + // ZipArchive internally stores the file descriptors of all the + // added files and only on close writes the contents to the ZIP file + // see: http://bugs.php.net/bug.php?id=40494 + // and: http://pecl.php.net/bugs/bug.php?id=9443 + // return $zip->addFile( $path, $zipEntryName ); + + $this->zipArchiveFileCount++; + $this->zipArchiveSizeCount += filesize($path); + + $added = $this->zip->addFile($path, $zipEntryName); +// if (true || filesize($path) > 10485760) +// { +// echo 'addFile ' . $path . ' : ' . $added . '
'; +// } +// else +// { +// $contents = file_get_contents($path); +// if ($contents === false) +// { +// return false; +// } +// $added = $this->zip->addFromString($zipEntryName, $contents); +// } + + //Over limits? 30 files or 30MB of files added +// if (($this->zipArchiveFileCount >= 254) || ($this->zipArchiveSizeCount >= 31457280)) + if ((($this->file_descriptors > 0) && ($this->zipArchiveFileCount > $this->file_descriptors)) || $this->zipArchiveSizeCount >= (31457280 * 2)) + { + $this->zip->close(); + $this->zip->open($this->zipArchiveFileName); + $this->zipArchiveFileCount = 0; + $this->zipArchiveSizeCount = 0; + } + + return $added; + } + + /** + * Create full backup using zip on console + * + * @param string $filepath File path to create + * @return bool + */ + public function createZipConsoleFullBackup($filepath, $excludes, $addConfig) + { + // @TODO to work with 'zip' from system if PHP Zip library not available + //system('zip'); + return false; + } + + /** + * Create full SQL backup + * + * @return string The SQL string + */ + public function createBackupDB($filepath) + { + $fh = fopen($filepath, 'w'); //or error; + + global $wpdb; + + //Get all the tables + $tables_db = $wpdb->get_results('SHOW TABLES FROM `' . DB_NAME . '`', ARRAY_N); + foreach ($tables_db as $curr_table) + { + $table = $curr_table[0]; + + fwrite($fh, "\n\n" . 'DROP TABLE IF EXISTS ' . $table . ';'); + $table_create = $wpdb->get_row('SHOW CREATE TABLE ' . $table, ARRAY_N); + fwrite($fh, "\n" . $table_create[1] . ";\n\n"); + + $rows = @MainWPChildDB::_query('SELECT * FROM ' . $table, $wpdb->dbh); + if ($rows) + { + $table_insert = 'INSERT INTO `' . $table . '` VALUES ('; + + while ($row = @MainWPChildDB::fetch_array($rows)) + { + $query = $table_insert; + foreach ($row as $value) + { + $query.= '"'.MainWPChildDB::real_escape_string($value).'", ' ; + } + $query = trim($query, ', ') . ");"; + + fwrite($fh, "\n" . $query); + } + } + } + + fclose($fh); + return true; + } + + public function createBackupDB_legacy($filepath) + { + $fh = fopen($filepath, 'w'); //or error; + + global $wpdb; + $maxchars = 50000; + + //Get all the tables + $tables_db = $wpdb->get_results('SHOW TABLES FROM `' . DB_NAME . '`', ARRAY_N); + foreach ($tables_db as $curr_table) + { + $table = $curr_table[0]; + + fwrite($fh, "\n" . 'DROP TABLE IF EXISTS ' . $table . ';'); + $table_create = $wpdb->get_row('SHOW CREATE TABLE ' . $table, ARRAY_N); + fwrite($fh, "\n" . $table_create[1] . ';'); + + //$rows = $wpdb->get_results('SELECT * FROM ' . $table, ARRAY_N); + $rows = @MainWPChildDB::_query('SELECT * FROM ' . $table, $wpdb->dbh); + if ($rows) + { + $table_columns = $wpdb->get_results('SHOW COLUMNS FROM ' . $table); + $table_columns_insert = ''; + foreach ($table_columns as $table_column) + { + if ($table_columns_insert != '') + $table_columns_insert .= ', '; + $table_columns_insert .= '`' . $table_column->Field . '`'; + } + $table_insert = 'INSERT INTO `' . $table . '` ('; + $table_insert .= $table_columns_insert; + $table_insert .= ') VALUES ' . "\n"; + + + $current_insert = $table_insert; + + $inserted = false; + $add_insert = ''; + while ($row = @MainWPChildDB::fetch_array($rows)) + { + //Create new insert! + $add_insert = '('; + $add_insert_each = ''; + foreach ($row as $value) + { + //$add_insert_each .= "'" . str_replace(array("\n", "\r", "'"), array('\n', '\r', "\'"), $value) . "',"; + + $value = addslashes($value); + $value = str_replace("\n","\\n",$value); + $value = str_replace("\r","\\r",$value); + $add_insert_each.= '"'.$value.'",' ; + } + $add_insert .= trim($add_insert_each, ',') . ')'; + + //If we already inserted something & the total is too long - commit previous! + if ($inserted && strlen($add_insert) + strlen($current_insert) >= $maxchars) + { + fwrite($fh, "\n" . $current_insert . ';'); + $current_insert = $table_insert; + $current_insert .= $add_insert; + $inserted = false; + } + else + { + if ($inserted) + { + $current_insert .= ', ' . "\n"; + } + $current_insert .= $add_insert; + } + $inserted = true; + } + if ($inserted) + { + fwrite($fh, "\n" . $current_insert . ';'); + } + } + } + + fclose($fh); + return true; + } + +} + +?> diff --git a/class/MainWPChild.class.php b/class/MainWPChild.class.php new file mode 100644 index 00000000..7f4a8881 --- /dev/null +++ b/class/MainWPChild.class.php @@ -0,0 +1,3092 @@ + 'getSiteStats', + 'upgrade' => 'upgradeWP', + 'newpost' => 'newPost', + 'deactivate' => 'deactivate', + 'newuser' => 'newUser', + 'newadminpassword' => 'newAdminPassword', + 'installplugintheme' => 'installPluginTheme', + 'upgradeplugintheme' => 'upgradePluginTheme', + 'backup' => 'backup', + 'cloneinfo' => 'cloneinfo', + 'security' => 'getSecurityStats', + 'securityFix' => 'doSecurityFix', + 'securityUnFix' => 'doSecurityUnFix', + 'post_action' => 'post_action', + 'get_all_posts' => 'get_all_posts', + 'comment_action' => 'comment_action', + 'comment_bulk_action' => 'comment_bulk_action', + 'get_all_comments' => 'get_all_comments', + 'get_all_themes' => 'get_all_themes', + 'theme_action' => 'theme_action', + 'get_all_plugins' => 'get_all_plugins', + 'plugin_action' => 'plugin_action', + 'get_all_pages' => 'get_all_pages', + 'get_all_users' => 'get_all_users', + 'user_action' => 'user_action', + 'search_users' => 'search_users', + 'get_terms' => 'get_terms', + 'set_terms' => 'set_terms', + 'insert_comment' => 'insert_comment', + 'get_post_meta' => 'get_post_meta', + 'get_total_ezine_post' => 'get_total_ezine_post', + 'get_next_time_to_post' => 'get_next_time_to_post', + 'cancel_scheduled_post' => 'cancel_scheduled_post', + // 'get_next_time_of_post_to_post' => 'get_next_time_of_post_to_post', + // 'get_next_time_of_page_to_post' => 'get_next_time_of_page_to_post', + 'serverInformation' => 'serverInformation', + 'maintenance_site' => 'maintenance_site', + 'keyword_links_action' => 'keyword_links_action' + ); + + private $FTP_ERROR = 'Failed, please add FTP details for automatic upgrades.'; + + private $callableFunctionsNoAuth = array( + 'stats' => 'getSiteStatsNoAuth' + ); + + private $posts_where_suffix; + private $comments_and_clauses; + private $plugin_slug; + private $plugin_dir; + private $slug; + private $maxHistory = 5; + + private $filterFunction = null; + + public function __construct($plugin_file) + { + $this->filterFunction = create_function( '$a', 'if ($a == null) { return false; } return $a;' ); + $this->plugin_dir = dirname($plugin_file); + $this->plugin_slug = plugin_basename($plugin_file); + list ($t1, $t2) = explode('/', $this->plugin_slug); + $this->slug = str_replace('.php', '', $t2); + + $this->posts_where_suffix = ''; + $this->comments_and_clauses = ''; + add_action('init', array(&$this, 'parse_init')); + add_action('admin_menu', array(&$this, 'admin_menu')); + add_action('init', array(&$this, 'localization')); + $this->checkOtherAuth(); + + MainWPClone::init(); + + //Clean legacy... + if (get_option('mainwp_child_legacy') === false) + { + $upload_dir = wp_upload_dir(); + $dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'sicknetwork' . DIRECTORY_SEPARATOR; + + MainWPHelper::delete_dir($dir); + + update_option('mainwp_child_legacy', true); + } + + add_action( 'admin_notices', array(&$this, 'admin_notice')); + } + + public function admin_notice() + { + //Admin Notice... + if (is_plugin_active('mainwp-child/mainwp-child.php')) { + if (!get_option('mainwp_child_pubkey')) { + echo '

Attention!

+

Please add this site to your MainWP Dashboard now or deactivate the MainWP Child plugin until you are ready to do so to avoid security issues.

'; + } + } + } + + public function localization() + { + load_plugin_textdomain('mainwp-child', false, dirname(dirname(plugin_basename(__FILE__))) . '/languages/'); + } + + function checkOtherAuth() + { + $auths = get_option('mainwp_child_auth'); + + if (!$auths) + { + $auths = array(); + } + + if (!isset($auths['last']) || $auths['last'] < mktime(0, 0, 0, date("m"), date("d"), date("Y"))) + { + //Generate code for today.. + for ($i = 0; $i < $this->maxHistory; $i++) + { + if (!isset($auths[$i + 1])) continue; + + $auths[$i] = $auths[$i + 1]; + } + $newI = $this->maxHistory + 1; + while (isset($auths[$newI])) unset($auths[$newI++]); + $auths[$this->maxHistory] = md5(MainWPHelper::randString(14)); + $auths['last'] = time(); + update_option('mainwp_child_auth', $auths); + } + } + + function isValidAuth($key) + { + $auths = get_option('mainwp_child_auth'); + if (!$auths) return false; + for ($i = 0; $i <= $this->maxHistory; $i++) + { + if (isset($auths[$i]) && ($auths[$i] == $key)) return true; + } + + return false; + } + + function admin_menu() + { + add_options_page('MainWPSettings', __('MainWP Settings','mainwp-child'), 'manage_options', 'MainWPSettings', array(&$this, 'settings')); + + $restorePage = add_submenu_page('tools.php', 'MainWP Restore', '', 'read', 'mainwp-child-restore', array('MainWPClone', 'renderRestore')); + add_action('admin_print_scripts-'.$restorePage, array('MainWPClone', 'print_scripts')); + + $sitesToClone = get_option('mainwp_child_clone_sites'); + if ($sitesToClone != '0') + { + MainWPClone::init_menu(); + } + else + { + MainWPClone::init_restore_menu(); + } + } + + function settings() + { + if (isset($_POST['submit'])) + { + if (isset($_POST['requireUniqueSecurityId'])) + { + update_option('mainwp_child_uniqueId', MainWPHelper::randString(8)); + } + else + { + update_option('mainwp_child_uniqueId', ''); + } + } + ?> +

+
+
+ +

+ + + + + + + + + + +
/> '.__('Your Unique Security ID is:','mainwp-child') . ' ' . get_option('mainwp_child_uniqueId') . ''; + } ?>
Main Dashboard. The Unique Security ID will need to match when being added to
the Main Dashboard. This is additional security and should not be needed in most situations.','mainwp-child'); ?>
+
+

+ \n"; + $rules .= "RewriteEngine On\n"; + $rules .= "RewriteBase $home_root\n"; + + //add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all) + foreach ($pRules as $match => $query) + { + // Apache 1.3 does not support the reluctant (non-greedy) modifier. + $match = str_replace('.+?', '.+', $match); + + $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; + } + + $rules .= "\n"; + + return $rules; + } + + function update_htaccess($hard = false) + { + if ((get_option('mainwp_child_pluginDir') == 'hidden') && ($hard || (get_option('mainwp_child_htaccess_set') != 'yes'))) + { + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + + $snPluginDir = basename($this->plugin_dir); + + $rules = null; + if (get_option('heatMapEnabled') !== '0') + { + //Heatmap enabled + //Make the plugin invisible, except heatmap + $rules = $this->mod_rewrite_rules(array('wp-content/plugins/' . $snPluginDir . '/([^js\/]*)$' => 'wp-content/plugins/THIS_PLUGIN_DOES_NOT_EXIST')); + } + else + { + //Make the plugin invisible + $rules = $this->mod_rewrite_rules(array('wp-content/plugins/' . $snPluginDir . '/(.*)$' => 'wp-content/plugins/THIS_PLUGIN_DOES_NOT_EXIST')); + } + + $home_path = ABSPATH; + $htaccess_file = $home_path . '.htaccess'; + if (function_exists('save_mod_rewrite_rules')) + { + $rules = explode("\n", $rules); + insert_with_markers($htaccess_file, 'MainWP', $rules); + + if (get_option('mainwp_child_onetime_htaccess') === false) + { +// insert_with_markers($htaccess_file, 'SickNetwork', array()); + update_option('mainwp_child_onetime_htaccess', true); + } + } + update_option('mainwp_child_htaccess_set', 'yes'); + } + else if ($hard) + { + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + + $home_path = ABSPATH; + $htaccess_file = $home_path . '.htaccess'; + if (function_exists('save_mod_rewrite_rules')) + { + $rules = explode("\n", ''); + insert_with_markers($htaccess_file, 'MainWP', $rules); + + if (get_option('mainwp_child_onetime_htaccess') === false) + { +// insert_with_markers($htaccess_file, 'SickNetwork', array()); + update_option('mainwp_child_onetime_htaccess', true); + } + } + } + } + + function parse_init() + { + if (isset($_POST['cloneFunc'])) + { + if (!isset($_POST['key'])) return; + if (!isset($_POST['file']) || ($_POST['file'] == '')) return; + if (!$this->isValidAuth($_POST['key'])) return; + + if ($_POST['cloneFunc'] == 'deleteCloneBackup') + { + $dirs = MainWPHelper::getMainWPDir('backup'); + $backupdir = $dirs[0]; + $result = glob($backupdir . $_POST['file']); + if (count($result) == 0) return; + + @unlink($result[0]); + MainWPHelper::write(array('result' => 'ok')); + } + else if ($_POST['cloneFunc'] == 'createCloneBackupPoll') + { + $dirs = MainWPHelper::getMainWPDir('backup'); + $backupdir = $dirs[0]; + $result = glob($backupdir . 'backup-'.$_POST['file'].'-*.zip'); + if (count($result) == 0) return; + + MainWPHelper::write(array('size' => filesize($result[0]))); + } + else if ($_POST['cloneFunc'] == 'createCloneBackup') + { + MainWPHelper::endSession(); + if (file_exists(WP_CONTENT_DIR . '/dbBackup.sql')) @unlink(WP_CONTENT_DIR . '/dbBackup.sql'); + if (file_exists(ABSPATH . 'clone/config.txt')) @unlink(ABSPATH . 'clone/config.txt'); + if (MainWPHelper::is_dir_empty(ABSPATH . 'clone')) @rmdir(ABSPATH . 'clone'); + + $wpversion = $_POST['wpversion']; + global $wp_version; + $includeCoreFiles = ($wpversion != $wp_version); + $excludes = (isset($_POST['exclude']) ? explode(',', $_POST['exclude']) : array()); + $excludes[] = str_replace(ABSPATH, '', WP_CONTENT_DIR) . '/uploads/mainwp'; + $excludes[] = str_replace(ABSPATH, '', WP_CONTENT_DIR) . '/object-cache.php'; + if (!ini_get('safe_mode')) set_time_limit(600); + + $newExcludes = array(); + foreach ($excludes as $exclude) + { + $newExcludes[] = rtrim($exclude, '/'); + } + + $res = MainWPBackup::get()->createFullBackup($newExcludes, $_POST['file'], true, $includeCoreFiles); + if (!$res) + { + $information['backup'] = false; + } + else + { + $information['backup'] = $res['file']; + $information['size'] = $res['filesize']; + } + + //todo: RS: Remove this when the .18 is out + $plugins = array(); + $dir = WP_CONTENT_DIR . '/plugins/'; + $fh = @opendir($dir); + while ($entry = @readdir($fh)) + { + if (!is_dir($dir . $entry)) continue; + if (($entry == '.') || ($entry == '..')) continue; + $plugins[] = $entry; + } + @closedir($fh); + $information['plugins'] = $plugins; + + $themes = array(); + $dir = WP_CONTENT_DIR . '/themes/'; + $fh = @opendir($dir); + while ($entry = @readdir($fh)) + { + if (!is_dir($dir . $entry)) continue; + if (($entry == '.') || ($entry == '..')) continue; + $themes[] = $entry; + } + @closedir($fh); + $information['themes'] = $themes; + + MainWPHelper::write($information); + } + } + + global $wp_rewrite; + $snPluginDir = basename($this->plugin_dir); + if (isset($wp_rewrite->non_wp_rules['wp-content/plugins/' . $snPluginDir . '/([^js\/]*)$'])) + { + unset($wp_rewrite->non_wp_rules['wp-content/plugins/' . $snPluginDir . '/([^js\/]*)$']); + } + + if (isset($wp_rewrite->non_wp_rules['wp-content/plugins/' . $snPluginDir . '/(.*)$'])) + { + unset($wp_rewrite->non_wp_rules['wp-content/plugins/' . $snPluginDir . '/(.*)$']); + } + + if (get_option('mainwp_child_fix_htaccess') === false) + { + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + + $wp_rewrite->flush_rules(); + update_option('mainwp_child_fix_htaccess', 'yes'); + } + + $this->update_htaccess(); + + global $current_user; //wp variable + + //Login the user + if (isset($_REQUEST['login_required']) && ($_REQUEST['login_required'] == 1) && isset($_REQUEST['user'])) + { + if (!is_user_logged_in() || $_REQUEST['user'] != $current_user->user_login) + { + $signature = rawurldecode(isset($_REQUEST['mainwpsignature']) ? $_REQUEST['mainwpsignature'] : ''); +// $signature = str_replace(' ', '+', $signature); + $auth = $this->auth($signature, rawurldecode((isset($_REQUEST['where']) ? $_REQUEST['where'] : (isset($_REQUEST['file']) ? $_REQUEST['file'] : ''))), isset($_REQUEST['nonce']) ? $_REQUEST['nonce'] : '', isset($_REQUEST['nossl']) ? $_REQUEST['nossl'] : 0); + if (!$auth) return; + if (!$this->login($_REQUEST['user'])) + { + return; + } + } + + $where = isset($_REQUEST['where']) ? $_REQUEST['where'] : ''; + if (isset($_POST['file'])) + { + $where = 'tools.php?page=mainwp-child-restore'; + if (session_id() == '') session_start(); + $_SESSION['file'] = $_POST['file']; + $_SESSION['size'] = $_POST['size']; + } + + add_filter('the_content', array(MainWPKeywordLinks::Instance(), 'filter_content'), 100, 2); + wp_redirect(admin_url($where)); + exit(); + } + + + remove_action('admin_init', 'send_frame_options_header'); + remove_action('login_init', 'send_frame_options_header'); + + // Call Heatmap + if (get_option('heatMapEnabled') !== '0') new MainWPHeatmapTracker(); + + /** + * Security + */ + MainWPSecurity::fixAll(); + + if (isset($_GET['test'])) + { + error_reporting(E_ALL); + ini_set('display_errors', TRUE); + ini_set('display_startup_errors', TRUE); + echo '
';
+            $excludes = (isset($_POST['exclude']) ? explode(',', $_POST['exclude']) : array());
+            $excludes[] = str_replace(ABSPATH, '', WP_CONTENT_DIR) . '/uploads/mainwp';
+            $excludes[] = str_replace(ABSPATH, '', WP_CONTENT_DIR) . '/object-cache.php';
+            if (!ini_get('safe_mode')) set_time_limit(600);
+
+            $file_descriptors = 0;
+
+            $newExcludes = array();
+            foreach ($excludes as $exclude)
+            {
+                $newExcludes[] = rtrim($exclude, '/');
+            }
+
+            $res = MainWPBackup::get()->createFullBackup($newExcludes, '', false, false, $file_descriptors);
+            print_r($res);
+            die('
'); + } + + //Register does not require auth, so we register here.. + if (isset($_POST['function']) && $_POST['function'] == 'register') + { + $this->registerSite(); + } + + $auth = $this->auth(isset($_POST['mainwpsignature']) ? $_POST['mainwpsignature'] : '', isset($_POST['function']) ? $_POST['function'] : '', isset($_POST['nonce']) ? $_POST['nonce'] : '', isset($_POST['nossl']) ? $_POST['nossl'] : 0); + + if (!$auth && isset($_POST['mainwpsignature'])) + { + MainWPHelper::error(__('Authentication failed. Reinstall MainWP plugin please','mainwp-child')); + } + + //Check if the user exists & is an administrator + if (isset($_POST['function']) && isset($_POST['user'])) + { + $user = get_user_by('login', $_POST['user']); + if (!$user) + { + MainWPHelper::error(__('No such user','mainwp-child')); + } + + if ($user->wp_user_level != 10 && (!isset($user->user_level) || $user->user_level != 10) && !current_user_can('level_10')) + { + MainWPHelper::error(__('User is not an administrator','mainwp-child')); + } + } + + if (isset($_POST['function']) && $_POST['function'] == 'visitPermalink') + { + if ($auth) + { + if ($this->login($_POST['user'], true)) + { + return; + } + else + { + exit(); + } + } + } + + //Redirect to the admin part if needed + if ($auth && isset($_POST['admin']) && $_POST['admin'] == 1) + { + wp_redirect(get_option('siteurl') . '/wp-admin/'); + die(); + } + + //Call the function required + if (isset($_POST['function']) && isset($this->callableFunctions[$_POST['function']])) + { + call_user_func(array($this, ($auth ? $this->callableFunctions[$_POST['function']] + : $this->callableFunctionsNoAuth[$_POST['function']]))); + } + if (get_option('mainwpKeywordLinks') == 1) { + new MainWPKeywordLinks(); + if (!is_admin()) { + add_filter('the_content', array(MainWPKeywordLinks::Instance(), 'filter_content'), 100); + } + MainWPKeywordLinks::Instance()->update_htaccess(); // if needed + MainWPKeywordLinks::Instance()->redirect_cloak(); + } + else if (get_option('mainwp_keyword_links_htaccess_set') == 'yes') + { + MainWPKeywordLinks::clear_htaccess(); // force clear + } + } + + function default_option_active_plugins($default) + { + if (!is_array($default)) $default = array(); + if (!in_array('managewp/init.php', $default)) $default[] = 'managewp/init.php'; + + return $default; + } + + function auth($signature, $func, $nonce, $pNossl) + { + if (!isset($signature) || !isset($func) || (!get_option('mainwp_child_pubkey') && !get_option('mainwp_child_nossl_key'))) + { + $auth = false; + } + else + { + $nossl = get_option('mainwp_child_nossl'); + $serverNoSsl = (isset($pNossl) && $pNossl == 1); + + if (($nossl == 1) || $serverNoSsl) + { + $auth = (md5($func . $nonce . get_option('mainwp_child_nossl_key')) == base64_decode($signature)); + } + else + { + $auth = openssl_verify($func . $nonce, base64_decode($signature), base64_decode(get_option('mainwp_child_pubkey'))); + } + } + + return $auth; + } + + //Login.. + function login($username, $doAction = false) + { + global $current_user; + + //Logout if required + if (isset($current_user->user_login)) + do_action('wp_logout'); + + $user = get_user_by('login', $username); + if ($user) + { //If user exists, login + wp_set_current_user($user->ID, $user->user_login); + wp_set_auth_cookie($user->ID); + + wp_set_current_user($user->ID); + wp_set_auth_cookie($user->ID); + if ($doAction) do_action('wp_login', $user->user_login); + return (is_user_logged_in() && $current_user->user_login == $username); + } + return false; + } + + /** + * Functions to support core functionality + */ + function installPluginTheme() + { + $wp_filesystem = $this->getWPFilesystem(); + + if (!isset($_POST['type']) || !isset($_POST['url']) || ($_POST['type'] != 'plugin' && $_POST['type'] != 'theme') || $_POST['url'] == '') + { + MainWPHelper::error(__('Bad request.','mainwp-child')); + } + if (file_exists(ABSPATH . '/wp-admin/includes/screen.php')) include_once(ABSPATH . '/wp-admin/includes/screen.php'); + include_once(ABSPATH . '/wp-admin/includes/template.php'); + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + include_once(ABSPATH . '/wp-admin/includes/class-wp-upgrader.php'); + include_once(ABSPATH . '/wp-admin/includes/plugin.php'); + + $urlgot = json_decode(stripslashes($_POST['url'])); + + $urls = array(); + if (!is_array($urlgot)) + { + $urls[] = $urlgot; + } + else + { + $urls = $urlgot; + } + + $result = array(); + foreach ($urls as $url) + { + $installer = new WP_Upgrader(); + //@see wp-admin/includes/class-wp-upgrader.php + $result = $installer->run(array( + 'package' => $url, + 'destination' => ($_POST['type'] == 'plugin' ? WP_PLUGIN_DIR + : WP_CONTENT_DIR . '/themes'), + 'clear_destination' => (isset($_POST['overwrite']) && $_POST['overwrite'] == true), //overwrite files? + 'clear_working' => true, + 'hook_extra' => array() + )); + if (is_wp_error($result)) + { + $error = $result->get_error_codes(); + if (is_array($error)) + { + MainWPHelper::error(implode(', ', $error)); + } + else + { + MainWPHelper::error($error); + } + } + if ($_POST['type'] == 'plugin' && isset($_POST['activatePlugin']) && $_POST['activatePlugin'] == 'yes') + { + $path = $result['destination']; + foreach ($result['source_files'] as $srcFile) + { + $thePlugin = get_plugin_data($path . $srcFile); + if ($thePlugin != null && $thePlugin != '' && $thePlugin['Name'] != '') + { + activate_plugin($path . $srcFile, '', false, true); + break; + } + } + } + } + $information['installation'] = 'SUCCESS'; + $information['destination_name'] = $result['destination_name']; + MainWPHelper::write($information); + } + + //This will upgrade WP + function upgradeWP() + { + global $wp_version; + $wp_filesystem = $this->getWPFilesystem(); + + $information = array(); + + include_once(ABSPATH . '/wp-admin/includes/update.php'); + include_once(ABSPATH . '/wp-admin/includes/class-wp-upgrader.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/screen.php')) include_once(ABSPATH . '/wp-admin/includes/screen.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/template.php')) include_once(ABSPATH . '/wp-admin/includes/template.php'); + include_once(ABSPATH . '/wp-admin/includes/file.php'); + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + + + if ($this->filterFunction != null) add_filter( 'pre_site_transient_update_core', $this->filterFunction, 99 ); + if ($this->filterFunction != null) add_filter( 'pre_transient_update_core', $this->filterFunction, 99 ); + + //Check for new versions + @wp_version_check(); + + $core_updates = get_core_updates(); + if (count($core_updates) > 0) + { + foreach ($core_updates as $core_update) + { + if ($core_update->response == 'latest') + { + $information['upgrade'] = 'SUCCESS'; + } + else if ($core_update->response == 'upgrade' && $core_update->locale == get_locale() && version_compare($wp_version, $core_update->current, '<=')) + { + //Upgrade! + $upgrade = false; + if (class_exists('Core_Upgrader')) + { + $core = new Core_Upgrader(); + $upgrade = $core->upgrade($core_update); + } + //If this does not work - add code from /wp-admin/includes/class-wp-upgrader.php in the newer versions + //So users can upgrade older versions too. + //3rd option: 'wp_update_core' + + if (!is_wp_error($upgrade)) + { + $information['upgrade'] = 'SUCCESS'; + } + else + { + $information['upgrade'] = 'WPERROR'; + } + break; + } + } + + if (!isset($information['upgrade'])) + { + foreach ($core_updates as $core_update) + { + if ($core_update->response == 'upgrade' && version_compare($wp_version, $core_update->current, '<=')) + { + //Upgrade! + $upgrade = false; + if (class_exists('Core_Upgrader')) + { + $core = new Core_Upgrader(); + $upgrade = $core->upgrade($core_update); + } + //If this does not work - add code from /wp-admin/includes/class-wp-upgrader.php in the newer versions + //So users can upgrade older versions too. + //3rd option: 'wp_update_core' + + if (!is_wp_error($upgrade)) + { + $information['upgrade'] = 'SUCCESS'; + } + else + { + $information['upgrade'] = 'WPERROR'; + } + break; + } + } + } + } + else + { + $information['upgrade'] = 'NORESPONSE'; + } + if ($this->filterFunction != null) remove_filter( 'pre_site_transient_update_core', $this->filterFunction, 99 ); + if ($this->filterFunction != null) remove_filter( 'pre_transient_update_core', $this->filterFunction, 99 ); + + MainWPHelper::write($information); + } + + /** + * Expects $_POST['type'] == plugin/theme + * $_POST['list'] == 'theme1,theme2' or 'plugin1,plugin2' + */ + function upgradePluginTheme() + { + $wp_filesystem = $this->getWPFilesystem(); + + include_once(ABSPATH . '/wp-admin/includes/class-wp-upgrader.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/screen.php')) include_once(ABSPATH . '/wp-admin/includes/screen.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/template.php')) include_once(ABSPATH . '/wp-admin/includes/template.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/misc.php')) include_once(ABSPATH . '/wp-admin/includes/misc.php'); + include_once(ABSPATH . '/wp-admin/includes/file.php'); + include_once(ABSPATH . '/wp-admin/includes/plugin.php'); + $information = array(); + $information['upgrades'] = array(); + $mwp_premium_updates_todo = array(); + $mwp_premium_updates_todo_slugs = array(); + if (isset($_POST['type']) && $_POST['type'] == 'plugin') + { + include_once(ABSPATH . '/wp-admin/includes/update.php'); + if ($this->filterFunction != null) add_filter( 'pre_site_transient_update_plugins', $this->filterFunction , 99); + + @wp_update_plugins(); + $information['plugin_updates'] = get_plugin_updates(); + + $plugins = explode(',', urldecode($_POST['list'])); + $premiumPlugins = array(); + $premiumUpdates = get_option('mainwp_premium_updates'); + if (is_array($premiumUpdates)) + { + $newPlugins = array(); + foreach ($plugins as $plugin) + { + if (in_array($plugin, $premiumUpdates)) + { + $premiumPlugins[] = $plugin; + } + else + { + $newPlugins[] = $plugin; + } + } + $plugins = $newPlugins; + } + if (count($plugins) > 0) + { + //@see wp-admin/update.php + $upgrader = new Plugin_Upgrader(new Bulk_Plugin_Upgrader_Skin(compact('nonce', 'url'))); + $result = $upgrader->bulk_upgrade($plugins); + if (!empty($result)) + { + foreach ($result as $plugin => $info) + { + if (empty($info)) + { + $information['upgrades'][$plugin] = false; + } + else + { + $information['upgrades'][$plugin] = true; + } + } + } + else + { + MainWPHelper::error(__('Bad request','mainwp-child')); + } + } + if (count($premiumPlugins) > 0) + { + $mwp_premium_updates = apply_filters('mwp_premium_perform_update', array()); + foreach ($premiumPlugins as $premiumPlugin) + { + foreach ($mwp_premium_updates as $key => $update) + { + $slug = (isset($update['slug']) ? $update['slug'] : $update['Name']); + if (strcmp($slug, $premiumPlugin) == 0) + { + $mwp_premium_updates_todo[$key] = $update; + $mwp_premium_updates_todo_slugs[] = $slug; + } + } + } + unset($mwp_premium_updates); + + $premiumUpgrader = new Plugin_Upgrader(new Bulk_Plugin_Upgrader_Skin(compact('nonce', 'url'))); + } + + if (count($plugins) <= 0 && count($premiumPlugins) <= 0) + { + MainWPHelper::error(__('Bad request','mainwp-child')); + } + + if ($this->filterFunction != null) remove_filter( 'pre_site_transient_update_plugins', $this->filterFunction , 99); + } + else if (isset($_POST['type']) && $_POST['type'] == 'theme') + { + include_once(ABSPATH . '/wp-admin/includes/update.php'); + if ($this->filterFunction != null) add_filter( 'pre_site_transient_update_themes', $this->filterFunction , 99); + @wp_update_themes(); + include_once(ABSPATH . '/wp-admin/includes/theme.php'); + $information['theme_updates'] = $this->upgrade_get_theme_updates(); + $themes = explode(',', $_POST['list']); + $premiumThemes = array(); + $premiumUpdates = get_option('mainwp_premium_updates'); + if (is_array($premiumUpdates)) + { + $newThemes = array(); + foreach ($themes as $theme) + { + if (in_array($theme, $premiumUpdates)) + { + $premiumThemes[] = $theme; + } + else + { + $newThemes[] = $theme; + } + } + $themes = $newThemes; + } + + if (count($themes) > 0) + { + //@see wp-admin/update.php + $upgrader = new Theme_Upgrader(new Bulk_Theme_Upgrader_Skin(compact('nonce', 'url'))); + $result = $upgrader->bulk_upgrade($themes); + if (!empty($result)) + { + foreach ($result as $theme => $info) + { + if (empty($info)) + { + $information['upgrades'][$theme] = false; + } + else + { + $information['upgrades'][$theme] = true; + } + } + } + else + { + MainWPHelper::error(__('Bad request','mainwp-child')); + } + } + if (count($premiumThemes) > 0) + { + $mwp_premium_updates = apply_filters('mwp_premium_perform_update', array()); + $mwp_premium_updates_todo = array(); + $mwp_premium_updates_todo_slugs = array(); + foreach ($premiumThemes as $premiumTheme) + { + foreach ($mwp_premium_updates as $key => $update) + { + $slug = (isset($update['slug']) ? $update['slug'] : $update['Name']); + if (strcmp($slug, $premiumTheme) == 0) + { + $mwp_premium_updates_todo[$key] = $update; + $mwp_premium_updates_todo_slugs[] = $slug; + } + } + } + unset($mwp_premium_updates); + + $premiumUpgrader = new Theme_Upgrader(new Bulk_Theme_Upgrader_Skin(compact('nonce', 'url'))); + } + if (count($themes) <= 0 && count($premiumThemes) <= 0) + { + MainWPHelper::error(__('Bad request','mainwp-child')); + } + + if ($this->filterFunction != null) remove_filter( 'pre_site_transient_update_themes', $this->filterFunction , 99); + } + else + { + MainWPHelper::error(__('Bad request','mainwp-child')); + } + + if (count($mwp_premium_updates_todo) > 0) + { + //Upgrade via WP + //@see wp-admin/update.php + $result = $premiumUpgrader->bulk_upgrade($mwp_premium_updates_todo_slugs); + if (!empty($result)) + { + foreach ($result as $plugin => $info) + { + if (!empty($info)) + { + $information['upgrades'][$plugin] = true; + + foreach ($mwp_premium_updates_todo as $key => $update) + { + $slug = (isset($update['slug']) ? $update['slug'] : $update['Name']); + if (strcmp($slug, $plugin) == 0) + { + //unset($mwp_premium_updates_todo[$key]); + } + } + } + } + } + + //Upgrade via callback + foreach ($mwp_premium_updates_todo as $update) + { + $slug = (isset($update['slug']) ? $update['slug'] : $update['Name']); + + if (isset($update['url'])) + { + $installer = new WP_Upgrader(); + //@see wp-admin/includes/class-wp-upgrader.php + $result = $installer->run(array( + 'package' => $update['url'], + 'destination' => ($update['type'] == 'plugin' ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/themes'), + 'clear_destination' => true, + 'clear_working' => true, + 'hook_extra' => array() + )); + $information['upgrades'][$slug] = (!is_wp_error($result) && !empty($result)); + } + else if (isset($update['callback'])) + { + if (is_array($update['callback']) && isset($update['callback'][0]) && isset($update['callback'][1])) + { + $update_result = @call_user_func(array($update['callback'][0], $update['callback'][1] )); + $information['upgrades'][$slug] = $update_result && true; + } + else if (is_string($update['callback'])) + { + $update_result = @call_user_func($update['callback']); + $information['upgrades'][$slug] = $update_result && true; + } + else + { + $information['upgrades'][$slug] = false; + } + } + else + { + $information['upgrades'][$slug] = false; + } + } + } + $information['sync'] = $this->getSiteStats(array(), false); + MainWPHelper::write($information); + } + + //This will register the current wp - thus generating the public key etc.. + function registerSite() + { + global $current_user; + + $information = array(); + //Check if the user is valid & login + if (!isset($_POST['user']) || !isset($_POST['pubkey'])) + { + MainWPHelper::error(__('Invalid request','mainwp-child')); + } + + //Already added - can't readd. Deactivate plugin.. + if (get_option('mainwp_child_pubkey')) + { + MainWPHelper::error(__('Public key already set, reset the MainWP plugin on your site and try again.','mainwp-child')); + } + + if (get_option('mainwp_child_uniqueId') != '') + { + if (!isset($_POST['uniqueId']) || ($_POST['uniqueId'] == '')) + { + MainWPHelper::error(__('This Child Site is set to require a Unique Security ID - Please Enter It before connection can be established.','mainwp-child')); + } + else if (get_option('mainwp_child_uniqueId') != $_POST['uniqueId']) + { + MainWPHelper::error(__('The Unique Security ID you have entered does not match Child Security ID - Please Correct It before connection can be established.','mainwp-child')); + } + } + + //Login + if (isset($_POST['user'])) + { + if (!$this->login($_POST['user'])) + { + MainWPHelper::error(__('No such user','mainwp-child')); + } + if ($current_user->wp_user_level != 10 && (!isset($current_user->user_level) || $current_user->user_level != 10) && !current_user_can('level_10')) + { + MainWPHelper::error(__('User is not an administrator','mainwp-child')); + } + } + + update_option('mainwp_child_pubkey', base64_encode($_POST['pubkey'])); //Save the public key + update_option('mainwp_child_server', $_POST['server']); //Save the public key + update_option('mainwp_child_nonce', 0); //Save the nonce + + update_option('mainwp_child_nossl', ($_POST['pubkey'] == '-1' || !function_exists('openssl_verify') ? 1 : 0)); + $information['nossl'] = ($_POST['pubkey'] == '-1' || !function_exists('openssl_verify') ? 1 : 0); + $nossl_key = uniqid('', true); + update_option('mainwp_child_nossl_key', $nossl_key); + $information['nosslkey'] = $nossl_key; + + $information['register'] = 'OK'; + $information['user'] = $_POST['user']; + $this->getSiteStats($information); + } + + function newPost() + { + //Read form data + $new_post = unserialize(base64_decode($_POST['new_post'])); + $post_custom = unserialize(base64_decode($_POST['post_custom'])); + $post_category = (isset($_POST['post_category']) ? base64_decode($_POST['post_category']) : null); + $post_tags = (isset($new_post['post_tags']) ? $new_post['post_tags'] : null); + $post_featured_image = base64_decode($_POST['post_featured_image']); + $upload_dir = unserialize(base64_decode($_POST['mainwp_upload_dir'])); + $new_post['_ezin_post_category'] = unserialize(base64_decode($_POST['_ezin_post_category'])); + + $res = MainWPHelper::createPost($new_post, $post_custom, $post_category, $post_featured_image, $upload_dir, $post_tags); + $created = $res['success']; + if ($created != true) + { + MainWPHelper::error($created); + } + + $information['added'] = true; + $information['added_id'] = $res['added_id']; + $information['link'] = $res['link']; + + MainWPHelper::write($information); + } + + function post_action() + { + //Read form data + $action = $_POST['action']; + $postId = $_POST['id']; + + if ($action == 'publish') + { + wp_publish_post($postId); + } + else if ($action == 'update') + { + $postData = $_POST['post_data']; + $my_post = is_array($postData) ? $postData : array(); + wp_update_post($my_post); + } + else if ($action == 'unpublish') + { + $my_post = array(); + $my_post['ID'] = $postId; + $my_post['post_status'] = 'draft'; + wp_update_post($my_post); + } + else if ($action == 'trash') + { + wp_trash_post($postId); + } + else if ($action == 'delete') + { + wp_delete_post($postId, true); + } + else if ($action == 'restore') + { + wp_untrash_post($postId); + } + else if ($action == 'update_meta') + { + $values = unserialize(base64_decode($_POST['values'])); + $meta_key = $values['meta_key']; + $meta_value = $values['meta_value']; + $check_prev = $values['check_prev']; + + foreach ($meta_key as $i => $key) + { + if (intval($check_prev[$i]) == 1) + update_post_meta($postId, $key, get_post_meta($postId, $key, true) ? get_post_meta($postId, $key, true) : $meta_value[$i]); + else + update_post_meta($postId, $key, $meta_value[$i]); + } + } + else + { + $information['status'] = 'FAIL'; + } + + if (!isset($information['status'])) $information['status'] = 'SUCCESS'; + $information['my_post'] = $my_post; + MainWPHelper::write($information); + } + + function user_action() + { + //Read form data + $action = $_POST['action']; + $extra = $_POST['extra']; + $userId = $_POST['id']; + $user_pass = $_POST['user_pass']; + + if ($action == 'delete') + { + include_once(ABSPATH . '/wp-admin/includes/user.php'); + wp_delete_user($userId); + } + else if ($action == 'changeRole') + { + $my_user = array(); + $my_user['ID'] = $userId; + $my_user['role'] = $extra; + wp_update_user($my_user); + } + else if ($action == 'update_password') + { + $my_user = array(); + $my_user['ID'] = $userId; + $my_user['user_pass'] = $user_pass; + wp_update_user($my_user); + } + else + { + $information['status'] = 'FAIL'; + } + + if (!isset($information['status'])) $information['status'] = 'SUCCESS'; + MainWPHelper::write($information); + } + + //todo: backwards compatible: wp_set_comment_status ? + function comment_action() + { + //Read form data + $action = $_POST['action']; + $commentId = $_POST['id']; + + if ($action == 'approve') + { + wp_set_comment_status($commentId, 'approve'); + } + else if ($action == 'unapprove') + { + wp_set_comment_status($commentId, 'hold'); + } + else if ($action == 'spam') + { + wp_spam_comment($commentId); + } + else if ($action == 'unspam') + { + wp_unspam_comment($commentId); + } + else if ($action == 'trash') + { + wp_trash_comment($commentId); + } + else if ($action == 'restore') + { + wp_untrash_comment($commentId); + } + else if ($action == 'delete') + { + wp_delete_comment($commentId, true); + } + else + { + $information['status'] = 'FAIL'; + } + + if (!isset($information['status'])) $information['status'] = 'SUCCESS'; + MainWPHelper::write($information); + } + + //todo: backwards compatible: wp_set_comment_status ? + function comment_bulk_action() + { + //Read form data + $action = $_POST['action']; + $commentIds = explode(',', $_POST['ids']); + $information['success'] = 0; + foreach ($commentIds as $commentId) + { + if ($commentId) + { + $information['success']++; + if ($action == 'approve') + { + wp_set_comment_status($commentId, 'approve'); + } + else if ($action == 'unapprove') + { + wp_set_comment_status($commentId, 'hold'); + } + else if ($action == 'spam') + { + wp_spam_comment($commentId); + } + else if ($action == 'unspam') + { + wp_unspam_comment($commentId); + } + else if ($action == 'trash') + { + wp_trash_comment($commentId); + } + else if ($action == 'restore') + { + wp_untrash_comment($commentId); + } + else if ($action == 'delete') + { + wp_delete_comment($commentId, true); + } + else + { + $information['success']--; + } + + + } + } + MainWPHelper::write($information); + } + + + function newAdminPassword() + { + //Read form data + $new_password = unserialize(base64_decode($_POST['new_password'])); + $user = get_user_by('login', $_POST['user']); + require_once(ABSPATH . WPINC . '/registration.php'); + + $id = wp_update_user(array('ID' => $user->ID, 'user_pass' => $new_password['user_pass'])); + if ($id != $user->ID) + { + if (is_wp_error($id)) + { + MainWPHelper::error($id->get_error_message()); + } + else + { + MainWPHelper::error(__('Could not change the admin password.','mainwp-child')); + } + } + + $information['added'] = true; + MainWPHelper::write($information); + } + + function newUser() + { + //Read form data + $new_user = unserialize(base64_decode($_POST['new_user'])); + $send_password = $_POST['send_password']; + + $new_user_id = wp_insert_user($new_user); + + if (is_wp_error($new_user_id)) + { + MainWPHelper::error($new_user_id->get_error_message()); + } + if ($new_user_id == 0) + { + MainWPHelper::error(__('Undefined error','mainwp-child')); + } + + if ($send_password) + { + $user = new WP_User($new_user_id); + + $user_login = stripslashes($user->user_login); + $user_email = stripslashes($user->user_email); + + // The blogname option is escaped with esc_html on the way into the database in sanitize_option + // we want to reverse this for the plain text arena of emails. + $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + + $message = sprintf(__('Username: %s'), $user_login) . "\r\n"; + $message .= sprintf(__('Password: %s'), $new_user['user_pass']) . "\r\n"; + $message .= wp_login_url() . "\r\n"; + + wp_mail($user_email, sprintf(__('[%s] Your username and password'), $blogname), $message); + } + $information['added'] = true; + MainWPHelper::write($information); + } + + function cloneinfo() + { + global $table_prefix; + $information['dbCharset'] = DB_CHARSET; + $information['dbCollate'] = DB_COLLATE; + $information['table_prefix'] = $table_prefix; + $information['site_url'] = get_option('site_url'); + $information['home'] = get_option('home'); + + MainWPHelper::write($information); + } + + function backup() + { + if ($_POST['type'] == 'full') + { + $excludes = (isset($_POST['exclude']) ? explode(',', $_POST['exclude']) : array()); + $excludes[] = str_replace(ABSPATH, '', WP_CONTENT_DIR) . '/uploads/mainwp'; + $excludes[] = str_replace(ABSPATH, '', WP_CONTENT_DIR) . '/object-cache.php'; + if (!ini_get('safe_mode')) set_time_limit(600); + + $file_descriptors = (isset($_POST['file_descriptors']) ? $_POST['file_descriptors'] : 0); + + $newExcludes = array(); + foreach ($excludes as $exclude) + { + $newExcludes[] = rtrim($exclude, '/'); + } + + $res = MainWPBackup::get()->createFullBackup($newExcludes, '', false, false, $file_descriptors); + if (!$res) + { + $information['full'] = false; + } + else + { + $information['full'] = $res['file']; + $information['size'] = $res['filesize']; + } + $information['db'] = false; + } + else if ($_POST['type'] == 'db') + { + $res = $this->backupDB(); + if (!$res) + { + $information['db'] = false; + } + else + { + $information['db'] = $res['file']; + $information['size'] = $res['filesize']; + } + $information['full'] = false; + } + else + { + $information['full'] = false; + $information['db'] = false; + } + MainWPHelper::write($information); + } + + protected function backupDB() + { + $dirs = MainWPHelper::getMainWPDir('backup'); + $dir = $dirs[0]; + $timestamp = time(); + $filepath = $dir . 'dbBackup-' . $timestamp . '.sql'; + + if ($dh = opendir($dir)) + { + while (($file = readdir($dh)) !== false) + { + if ($file != '.' && $file != '..' && preg_match('/dbBackup-(.*).sql$/', $file)) + { + @unlink($dir . $file); + } + } + closedir($dh); + } + + if (file_exists($filepath)) + { + @unlink($filepath); + } + + + $success = MainWPBackup::get()->createBackupDB($filepath); + + return ($success) ? array( + 'timestamp' => $timestamp, + 'file' => $dirs[1] . basename($filepath), + 'filesize' => filesize($filepath) + ) : false; + } + + function doSecurityFix() + { + $sync = false; + if ($_POST['feature'] == 'all') + { + //fix all + $sync = true; + } + + $information = array(); + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'listing') + { + MainWPSecurity::prevent_listing(); + $information['listing'] = (!MainWPSecurity::prevent_listing_ok() ? 'N' : 'Y'); + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'wp_version') + { + update_option('mainwp_child_remove_wp_version', 'T'); + MainWPSecurity::remove_wp_version(); + $information['wp_version'] = (!MainWPSecurity::remove_wp_version_ok() ? 'N' : 'Y'); + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'rsd') + { + update_option('mainwp_child_remove_rsd', 'T'); + MainWPSecurity::remove_rsd(); + $information['rsd'] = (!MainWPSecurity::remove_rsd_ok() ? 'N' : 'Y'); + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'wlw') + { + update_option('mainwp_child_remove_wlw', 'T'); + MainWPSecurity::remove_wlw(); + $information['wlw'] = (!MainWPSecurity::remove_wlw_ok() ? 'N' : 'Y'); + } + +// if ($_POST['feature'] == 'all' || $_POST['feature'] == 'core_updates') +// { +// update_option('mainwp_child_remove_core_updates', 'T'); +// MainWPSecurity::remove_core_update(); +// $information['core_updates'] = (!MainWPSecurity::remove_core_update_ok() ? 'N' : 'Y'); +// } + +// if ($_POST['feature'] == 'all' || $_POST['feature'] == 'plugin_updates') +// { +// update_option('mainwp_child_remove_plugin_updates', 'T'); +// MainWPSecurity::remove_plugin_update(); +// $information['plugin_updates'] = (!MainWPSecurity::remove_plugin_update_ok() ? 'N' : 'Y'); +// } + +// if ($_POST['feature'] == 'all' || $_POST['feature'] == 'theme_updates') +// { +// update_option('mainwp_child_remove_theme_updates', 'T'); +// MainWPSecurity::remove_theme_update(); +// $information['theme_updates'] = (!MainWPSecurity::remove_theme_update_ok() ? 'N' : 'Y'); +// } + +// if ($_POST['feature'] == 'all' || $_POST['feature'] == 'file_perms') +// { +// MainWPSecurity::fix_file_permissions(); +// $information['file_perms'] = (!MainWPSecurity::fix_file_permissions_ok() ? 'N' : 'Y'); +// if ($information['file_perms'] == 'N') +// { +// $information['file_perms'] = 'Could not change all the file permissions'; +// } +// } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'db_reporting') + { + MainWPSecurity::remove_database_reporting(); + $information['db_reporting'] = (!MainWPSecurity::remove_database_reporting_ok() ? 'N' : 'Y'); + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'php_reporting') + { + update_option('mainwp_child_remove_php_reporting', 'T'); + MainWPSecurity::remove_php_reporting(); + $information['php_reporting'] = (!MainWPSecurity::remove_php_reporting_ok() ? 'N' : 'Y'); + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'versions') + { + update_option('mainwp_child_remove_scripts_version', 'T'); + update_option('mainwp_child_remove_styles_version', 'T'); + MainWPSecurity::remove_scripts_version(); + MainWPSecurity::remove_styles_version(); + $information['versions'] = (!MainWPSecurity::remove_scripts_version_ok() || !MainWPSecurity::remove_styles_version_ok() + ? 'N' : 'Y'); + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'admin') + { + $information['admin'] = (!MainWPSecurity::admin_user_ok() ? 'N' : 'Y'); + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'readme') + { + update_option('mainwp_child_remove_readme', 'T'); + MainWPSecurity::remove_readme(); + $information['readme'] = (MainWPSecurity::remove_readme_ok() ? 'Y' : 'N'); + } + + if ($sync) + { + $information['sync'] = $this->getSiteStats(array(), false); + } + MainWPHelper::write($information); + } + + function doSecurityUnFix() + { + $information = array(); + + $sync = false; + if ($_POST['feature'] == 'all') + { + $sync = true; + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'wp_version') + { + update_option('mainwp_child_remove_wp_version', 'F'); + $information['wp_version'] = 'N'; + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'rsd') + { + update_option('mainwp_child_remove_rsd', 'F'); + $information['rsd'] = 'N'; + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'wlw') + { + update_option('mainwp_child_remove_wlw', 'F'); + $information['wlw'] = 'N'; + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'php_reporting') + { + update_option('mainwp_child_remove_php_reporting', 'F'); + $information['php_reporting'] = 'N'; + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'versions') + { + update_option('mainwp_child_remove_scripts_version', 'F'); + update_option('mainwp_child_remove_styles_version', 'F'); + $information['versions'] = 'N'; + } + + if ($_POST['feature'] == 'all' || $_POST['feature'] == 'readme') + { + update_option('mainwp_child_remove_readme', 'F'); + $information['readme'] = MainWPSecurity::remove_readme_ok(); + } + + if ($sync) + { + $information['sync'] = $this->getSiteStats(array(), false); + } + + MainWPHelper::write($information); + } + + function getSecurityStats() + { + $information = array(); + + $information['listing'] = (!MainWPSecurity::prevent_listing_ok() ? 'N' : 'Y'); + $information['wp_version'] = (!MainWPSecurity::remove_wp_version_ok() ? 'N' : 'Y'); + $information['rsd'] = (!MainWPSecurity::remove_rsd_ok() ? 'N' : 'Y'); + $information['wlw'] = (!MainWPSecurity::remove_wlw_ok() ? 'N' : 'Y'); +// $information['core_updates'] = (!MainWPSecurity::remove_core_update_ok() ? 'N' : 'Y'); +// $information['plugin_updates'] = (!MainWPSecurity::remove_plugin_update_ok() ? 'N' : 'Y'); +// $information['theme_updates'] = (!MainWPSecurity::remove_theme_update_ok() ? 'N' : 'Y'); +// $information['file_perms'] = (!MainWPSecurity::fix_file_permissions_ok() ? 'N' : 'Y'); + $information['db_reporting'] = (!MainWPSecurity::remove_database_reporting_ok() ? 'N' : 'Y'); + $information['php_reporting'] = (!MainWPSecurity::remove_php_reporting_ok() ? 'N' : 'Y'); + $information['versions'] = (!MainWPSecurity::remove_scripts_version_ok() || !MainWPSecurity::remove_styles_version_ok() + ? 'N' : 'Y'); + $information['admin'] = (!MainWPSecurity::admin_user_ok() ? 'N' : 'Y'); + $information['readme'] = (MainWPSecurity::remove_readme_ok() ? 'Y' : 'N'); + + MainWPHelper::write($information); + } + + function updateExternalSettings() + { + $update_htaccess = false; + + if (get_option('mainwp_child_onetime_htaccess') === false) + { + $update_htaccess = true; + } + + if (isset($_POST['heatMap'])) + { + if ($_POST['heatMap'] == '1') + { + if (get_option('heatMapEnabled') != '1') $update_htaccess = true; + update_option('heatMapEnabled', '1'); + } + else + { + if (get_option('heatMapEnabled') != '0') $update_htaccess = true; + update_option('heatMapEnabled', '0'); + } + } + + if (isset($_POST['cloneSites'])) + { + if ($_POST['cloneSites'] != '0') + { + $arr = @json_decode(urldecode($_POST['cloneSites']), 1); + update_option('mainwp_child_clone_sites', (!is_array($arr) ? array() : $arr)); + } + else + { + update_option('mainwp_child_clone_sites', '0'); + } + } + + if (isset($_POST['pluginDir'])) + { + if (get_option('mainwp_child_pluginDir') != $_POST['pluginDir']) + { + update_option('mainwp_child_pluginDir', $_POST['pluginDir']); + $update_htaccess = true; + } + } + else if (get_option('mainwp_child_pluginDir') != false) + { + delete_option('mainwp_child_pluginDir'); + $update_htaccess = true; + } + + if ($update_htaccess) + { + $this->update_htaccess(true); + } + } + + //Show stats + function getSiteStats($information = array(), $exit = true) + { + global $wp_version; + + $this->updateExternalSettings(); + + $information['wpversion'] = $wp_version; + $information['siteurl'] = get_option('siteurl'); + $information['nossl'] = (get_option('mainwp_child_nossl') == 1 ? 1 : 0); + + include_once(ABSPATH . '/wp-admin/includes/update.php'); + + //Check for new versions + if ($this->filterFunction != null) add_filter( 'pre_site_transient_update_core', $this->filterFunction, 99 ); + if ($this->filterFunction != null) add_filter( 'pre_transient_update_core', $this->filterFunction, 99 ); + @wp_version_check(); + $core_updates = get_core_updates(); + if (count($core_updates) > 0) + { + foreach ($core_updates as $core_update) + { + if ($core_update->response == 'latest') + { + break; + } + if ($core_update->response == 'upgrade' && version_compare($wp_version, $core_update->current, '<=')) + { + $information['wp_updates'] = $core_update->current; + } + } + } + if (!isset($information['wp_updates'])) + { + $information['wp_updates'] = null; + } + if ($this->filterFunction != null) remove_filter( 'pre_site_transient_update_core', $this->filterFunction, 99 ); + if ($this->filterFunction != null) remove_filter( 'pre_transient_update_core', $this->filterFunction, 99 ); + + add_filter('default_option_active_plugins', array(&$this, 'default_option_active_plugins')); + add_filter('option_active_plugins', array(&$this, 'default_option_active_plugins')); + + //First check for new premium updates + $update_check = apply_filters('mwp_premium_update_check', array()); + if (!empty($update_check)) + { + foreach ($update_check as $updateFeedback) + { + if (is_array($updateFeedback['callback']) && isset($updateFeedback['callback'][0]) && isset($updateFeedback['callback'][1])) + { + @call_user_func(array($updateFeedback['callback'][0], $updateFeedback['callback'][1])); + } + else if (is_string($updateFeedback['callback'])) + { + @call_user_func($updateFeedback['callback']); + } + } + } + + $informationPremiumUpdates = apply_filters('mwp_premium_update_notification', array()); + $premiumPlugins = array(); + $premiumThemes = array(); + if (is_array($informationPremiumUpdates)) + { + $premiumUpdates = array(); + $information['premium_updates'] = array(); + for ($i = 0; $i < count($informationPremiumUpdates); $i++) + { + if (!isset($informationPremiumUpdates[$i]['new_version'])) + { + continue; + } + $slug = (isset($informationPremiumUpdates[$i]['slug']) ? $informationPremiumUpdates[$i]['slug'] : $informationPremiumUpdates[$i]['Name']); + + if ($informationPremiumUpdates[$i]['type'] == 'plugin') + { + $premiumPlugins[] = $slug; + } + else if ($informationPremiumUpdates[$i]['type'] == 'theme') + { + $premiumThemes[] = $slug; + } + + $new_version = $informationPremiumUpdates[$i]['new_version']; + + unset($informationPremiumUpdates[$i]['old_version']); + unset($informationPremiumUpdates[$i]['new_version']); + + $information['premium_updates'][$slug] = $informationPremiumUpdates[$i]; + $information['premium_updates'][$slug]['update'] = (object)array('new_version' => $new_version, 'premium' => true, 'slug' => $slug); + if (!in_array($slug, $premiumUpdates)) $premiumUpdates[] = $slug; + } + update_option('mainwp_premium_updates', $premiumUpdates); + } + + remove_filter('default_option_active_plugins', array(&$this, 'default_option_active_plugins')); + remove_filter('option_active_plugins', array(&$this, 'default_option_active_plugins')); + + if ($this->filterFunction != null) add_filter( 'pre_site_transient_update_plugins', $this->filterFunction , 99); + @wp_update_plugins(); + include_once(ABSPATH . '/wp-admin/includes/plugin.php'); + $plugin_updates = get_plugin_updates(); + if (is_array($plugin_updates)) + { + $information['plugin_updates'] = array(); + + foreach ($plugin_updates as $slug => $plugin_update) + { + if (in_array($plugin_update->Name, $premiumPlugins)) continue; + + $information['plugin_updates'][$slug] = $plugin_update; + } + } + if ($this->filterFunction != null) remove_filter( 'pre_site_transient_update_plugins', $this->filterFunction , 99); + if ($this->filterFunction != null) add_filter( 'pre_site_transient_update_themes', $this->filterFunction, 99); + @wp_update_themes(); + include_once(ABSPATH . '/wp-admin/includes/theme.php'); + $theme_updates = $this->upgrade_get_theme_updates(); + if (is_array($theme_updates)) + { + $information['theme_updates'] = array(); + + foreach ($theme_updates as $slug => $theme_update) + { + if (in_array($theme_update->Name, $premiumThemes)) continue; + + $information['theme_updates'][$slug] = $theme_update; + } + } + if ($this->filterFunction != null) remove_filter( 'pre_site_transient_update_themes', $this->filterFunction, 99); + $information['recent_comments'] = $this->get_recent_comments(array('approve', 'hold'), 5); + $information['recent_posts'] = $this->get_recent_posts(array('publish', 'draft', 'pending', 'trash'), 5); + $information['recent_pages'] = $this->get_recent_posts(array('publish', 'draft', 'pending', 'trash'), 5, 'page'); + + $securityIssuess = 0; + if (!MainWPSecurity::prevent_listing_ok()) $securityIssuess++; + if (!MainWPSecurity::remove_wp_version_ok()) $securityIssuess++; + if (!MainWPSecurity::remove_rsd_ok()) $securityIssuess++; + if (!MainWPSecurity::remove_wlw_ok()) $securityIssuess++; +// if (!MainWPSecurity::remove_core_update_ok()) $securityIssuess++; +// if (!MainWPSecurity::remove_plugin_update_ok()) $securityIssuess++; +// if (!MainWPSecurity::remove_theme_update_ok()) $securityIssuess++; +// if (!MainWPSecurity::fix_file_permissions_ok()) $securityIssuess++; + if (!MainWPSecurity::remove_database_reporting_ok()) $securityIssuess++; + if (!MainWPSecurity::remove_php_reporting_ok()) $securityIssuess++; + if (!MainWPSecurity::remove_scripts_version_ok() || !MainWPSecurity::remove_styles_version_ok()) $securityIssuess++; + if (!MainWPSecurity::admin_user_ok()) $securityIssuess++; + if (!MainWPSecurity::remove_readme_ok()) $securityIssuess++; + + $information['securityIssues'] = $securityIssuess; + + //Directory listings! + $information['directories'] = $this->scanDir(ABSPATH, 3); + $cats = get_categories(array('hide_empty' => 0, 'name' => 'select_name', 'hierarchical' => true)); + $categories = array(); + foreach ($cats as $cat) + { + $categories[] = $cat->name; + } + $information['categories'] = $categories; + $information['totalsize'] = $this->getTotalFileSize(); + $auths = get_option('mainwp_child_auth'); + $information['extauth'] = ($auths && isset($auths[$this->maxHistory]) ? $auths[$this->maxHistory] : null); + + $plugins = false; + $themes = false; + if (isset($_POST['optimize']) && ($_POST['optimize'] == 1)) + { + $plugins = $this->get_all_plugins_int(false); + $information['plugins'] = $plugins; + $themes = $this->get_all_themes_int(false); + $information['themes'] = $themes; + $information['users'] = $this->get_all_users_int(); + } + + if (isset($_POST['pluginConflicts']) && ($_POST['pluginConflicts'] != false)) + { + $pluginConflicts = json_decode(stripslashes($_POST['pluginConflicts']), true); + $conflicts = array(); + if (count($pluginConflicts) > 0) + { + if ($plugins == false) $plugins = $this->get_all_plugins_int(false); + foreach ($plugins as $plugin) + { + foreach ($pluginConflicts as $pluginConflict) + { + if (($plugin['active'] == 1) && (($plugin['name'] == $pluginConflict) || ($plugin['slug'] == $pluginConflict))) + { + $conflicts[] = $plugin['name']; + } + } + } + } + if (count($conflicts) > 0) $information['pluginConflicts'] = $conflicts; + } + + if (isset($_POST['themeConflicts']) && ($_POST['themeConflicts'] != false)) + { + $themeConflicts = json_decode(stripslashes($_POST['themeConflicts']), true); + $conflicts = array(); + if (count($themeConflicts) > 0) + { + $theme = wp_get_theme()->get('Name'); + foreach ($themeConflicts as $themeConflict) + { + if ($theme == $themeConflict) + { + $conflicts[] = $theme; + } + } + } + if (count($conflicts) > 0) $information['themeConflicts'] = $conflicts; + } + + $last_post = wp_get_recent_posts(array( 'numberposts' => absint('1'))); + if (isset($last_post[0])) $last_post = $last_post[0]; + if (isset($last_post)) $information['last_post_gmt'] = strtotime($last_post['post_modified_gmt']); + $information['mainwpdir'] = (MainWPHelper::validateMainWPDir() ? 1 : -1); + + if ($exit) MainWPHelper::write($information); + + return $information; + } + + function scanDir($pDir, $pLvl) + { + $output = array(); + if (file_exists($pDir) && is_dir($pDir)) + { + if ($pLvl == 0) return $output; + + if ($files = @scandir($pDir)) + { + foreach ($files as $file) + { + if (($file == '.') || ($file == '..')) continue; + $newDir = $pDir . $file . DIRECTORY_SEPARATOR; + if (@is_dir($newDir)) + { + $output[$file] = $this->scanDir($newDir, $pLvl - 1); + } + } + } + } + return $output; + } + + function upgrade_get_theme_updates() + { + $themeUpdates = get_theme_updates(); + $newThemeUpdates = array(); + if (is_array($themeUpdates)) + { + foreach ($themeUpdates as $slug => $themeUpdate) + { + $newThemeUpdate = array(); + $newThemeUpdate['update'] = $themeUpdate->update; + $newThemeUpdate['Name'] = MainWPHelper::search($themeUpdate, 'Name'); + $newThemeUpdate['Version'] = MainWPHelper::search($themeUpdate, 'Version'); + $newThemeUpdates[$slug] = $newThemeUpdate; + } + } + + return $newThemeUpdates; + } + + function get_recent_posts($pAllowedStatuses, $pCount, $type = 'post') + { + $allPosts = array(); + if ($pAllowedStatuses != null) + { + foreach ($pAllowedStatuses as $status) + { + $this->get_recent_posts_int($status, $pCount, $type, $allPosts); + } + } + else + { + $this->get_recent_posts_int('any', $pCount, $type, $allPosts); + } + return $allPosts; + } + + function get_recent_posts_int($status, $pCount, $type = 'post', &$allPosts) + { + $args = array('post_status' => $status, + 'suppress_filters' => false, + 'post_type' => $type); + + if ($pCount != 0) $args['numberposts'] = $pCount; + + $posts = get_posts($args); + if (is_array($posts)) + { + foreach ($posts as $post) + { + $outPost = array(); + $outPost['id'] = $post->ID; + $outPost['status'] = $post->post_status; + $outPost['title'] = $post->post_title; + $outPost['content'] = $post->post_content; + $outPost['comment_count'] = $post->comment_count; + $outPost['dts'] = strtotime($post->post_modified_gmt); + $usr = get_user_by('id', $post->post_author); + $outPost['author'] = $usr->user_nicename; + $categoryObjects = get_the_category($post->ID); + $categories = ""; + foreach ($categoryObjects as $cat) + { + if ($categories != "") $categories .= ", "; + $categories .= $cat->name; + } + $outPost['categories'] = $categories; + + $tagObjects = get_the_tags($post->ID); + $tags = ""; + if (is_array($tagObjects)) + { + foreach ($tagObjects as $tag) + { + if ($tags != "") $tags .= ", "; + $tags .= $tag->name; + } + } + $outPost['tags'] = $tags; + $allPosts[] = $outPost; + } + } + } + + function posts_where($where) + { + if ($this->posts_where_suffix) $where .= ' ' . $this->posts_where_suffix; + return $where; + } + + function get_all_posts() + { + $this->get_all_posts_by_type('post'); + } + + function get_terms() + { + $taxonomy = base64_decode($_POST['taxonomy']); + $rslt = get_terms(taxonomy_exists($taxonomy) ? $taxonomy : 'category', 'hide_empty=0'); + MainWPHelper::write($rslt); + } + + function set_terms() + { + $id = base64_decode($_POST['id']); + $terms = base64_decode($_POST['terms']); + $taxonomy = base64_decode($_POST['taxonomy']); + + if (trim($terms) != '') + { + $terms = explode(',', $terms); + if (count($terms) > 0) + { + wp_set_object_terms($id, array_map('intval', $terms), taxonomy_exists($taxonomy) ? $taxonomy : 'category'); + } + } + } + + function insert_comment() + { + $postId = $_POST['id']; + $comments = unserialize(base64_decode($_POST['comments'])); + $ids = array(); + foreach ($comments as $comment) + { + $ids[] = wp_insert_comment(array( + 'comment_post_ID' => $postId, + 'comment_author' => $comment['author'], + 'comment_content' => $comment['content'], + 'comment_date' => $comment['date'] + )); + } + MainWPHelper::write($ids); + } + + function get_post_meta() + { + /** @var $wpdb wpdb */ + global $wpdb; + $postId = $_POST['id']; + $keys = base64_decode(unserialize($_POST['keys'])); + $meta_value = $_POST['value']; + + $where = ''; + if (!empty($postId)) + $where .= " AND `post_id` = $postId "; + if (!empty($keys)) + { + $str_keys = '\'' . implode('\',\'', $keys) . '\''; + $where .= " AND `meta_key` IN = $str_keys "; + } + if (!empty($meta_value)) + $where .= " AND `meta_value` = $meta_value "; + + + $results = $wpdb->get_results(sprintf("SELECT * FROM %s WHERE 1 = 1 $where ", $wpdb->postmeta)); + MainWPHelper::write($results); + } + + function get_total_ezine_post() + { + /** @var $wpdb wpdb */ + global $wpdb; + $start_date = base64_decode($_POST['start_date']); + $end_date = base64_decode($_POST['end_date']); + $keyword_meta = base64_decode($_POST['keyword_meta']); + $where = " WHERE "; + if (!empty($start_date) && !empty($end_date)) + $where .= " p.post_date>='$start_date' AND p.post_date<='$end_date' AND "; + else if (!empty($start_date) && empty($end_date)) + { + $where .= " p.post_date='$start_date' AND "; + } + $where .= " ( p.post_status='publish' OR p.post_status='future' OR p.post_status='draft' ) + AND (pm.meta_key='_ezine_keyword' AND pm.meta_value='$keyword_meta')"; + $total = $wpdb->get_var("SELECT COUNT(*) + FROM $wpdb->posts p JOIN $wpdb->postmeta pm ON p.ID=pm.post_id + $where "); + MainWPHelper::write($total); + } + + function cancel_scheduled_post() { + global $wpdb; + $postId = $_POST['post_id']; + $cancel_all = $_POST['cancel_all']; + $result = false; + $information = array(); + if ($postId > 0) { + if (get_post_meta($postId, '_is_auto_generate_content', true) == 'yes') { + $post = $wpdb->get_row('SELECT * FROM ' . $wpdb->posts . + ' WHERE ID = ' . $postId . + ' AND post_status = \'future\''); + if ($post) + $result = wp_trash_post($postId); + else + $result = true; + } + if ($result !== false) + $information['status'] = 'SUCCESS'; + } else if ($cancel_all == true) { + $post_type = $_POST['post_type']; + $where = " WHERE p.post_status='future' AND p.post_type = '" . $post_type . "' AND pm.meta_key = '_is_auto_generate_content' AND pm.meta_value = 'yes' "; + $posts = $wpdb->get_results("SELECT p.ID FROM $wpdb->posts p JOIN $wpdb->postmeta pm ON p.ID=pm.post_id $where "); + $count = 0; + if (is_array($posts)) { + foreach($posts as $post) { + if ($post) { + if (false !== wp_trash_post($post->ID)) { + $count++; + + } + } + } + } else { + $posts = array(); + } + + $information['status'] = "SUCCESS"; + $information['count'] = $count; + } + + MainWPHelper::write($information); + } + + function get_next_time_to_post() + { + $post_type = $_POST['post_type']; + if ($post_type != 'post' && $post_type != 'page') { + MainWPHelper::write(array('error' => 'Data error.')); + return; + } + $information = array(); + try + { + global $wpdb; + $ct = current_time('mysql'); + $next_post = $wpdb->get_row(" + SELECT * + FROM " . $wpdb->posts . " p JOIN " . $wpdb->postmeta . " pm ON p.ID=pm.post_id + WHERE + pm.meta_key='_is_auto_generate_content' AND + pm.meta_value='yes' AND + p.post_status='future' AND + p.post_type= '" . $post_type. "' AND + p.post_date > NOW() + ORDER BY p.post_date + LIMIT 1"); + + if (!$next_post) + { + $information['error'] = "Thera are not auto scheduled post"; + } + else + { + $timestamp = strtotime($next_post->post_date); + $timestamp_gmt = $timestamp - get_option('gmt_offset') * 60 * 60; + $information['next_post_date_timestamp_gmt'] = $timestamp_gmt; + $information['next_post_id'] = $next_post->ID; + } + + MainWPHelper::write($information); + } + catch (Exception $e) + { + $information['error'] = $e->getMessage(); + MainWPHelper::write($information); + } + } + + // function get_next_time_of_post_to_post() + // { + // /** @var $wpdb wpdb */ + // global $wpdb; + // try + // { + // $ct = current_time('mysql'); + // $next_post = $wpdb->get_row(" + // SELECT * + // FROM $wpdb->posts p JOIN $wpdb->postmeta pm ON p.ID=pm.post_id + // WHERE + // pm.meta_key='_ezine_keyword' AND + // p.post_status='future' AND + // p.post_type='post' AND + // p.post_date>'$ct' + // ORDER BY p.post_date + // LIMIT 1"); + + // if (!$next_post) + // { + // $information['error'] = "Can not get next schedule post"; + // } + // else + // { + // $information['next_post_date'] = $next_post->post_date; + // $information['next_post_id'] = $next_post->ID; + + // $next_posts = $wpdb->get_results(" + // SELECT DISTINCT `ID` + // FROM $wpdb->posts p + // JOIN $wpdb->postmeta pm ON p.ID = pm.post_id + // WHERE pm.meta_key = '_ezine_keyword' + // AND p.post_status = 'future' + // AND p.post_date > NOW( ) + // ORDER BY p.post_date + // "); + + // if (!$next_posts) + // $information['error'] = "Can not get all next schedule post"; + // else + // $information['next_posts'] = $next_posts; + + // } + + // MainWPHelper::write($information); + // } + // catch (Exception $e) + // { + // $information['error'] = $e->getMessage(); + // MainWPHelper::write($information); + // } + // } + + // function get_next_time_of_page_to_post() + // { + // /** @var $wpdb wpdb */ + // global $wpdb; + // try + // { + + // $ct = current_time('mysql'); + // $next_post = $wpdb->get_row(" + // SELECT * + // FROM $wpdb->posts p JOIN $wpdb->postmeta pm ON p.ID=pm.post_id + // WHERE + // pm.meta_key='_ezine_keyword' AND + // p.post_status='future' AND + // p.post_type='page' AND + // p.post_date>'$ct' + // ORDER BY p.post_date + // LIMIT 1"); + + // if (!$next_post) + // { + // $information['error'] = "Can not get next schedule post"; + // } + // else + // { + + // $information['next_post_date'] = $next_post->post_date; + // $information['next_post_id'] = $next_post->ID; + + // $next_posts = $wpdb->get_results(" + // SELECT DISTINCT `ID` + // FROM $wpdb->posts p + // JOIN $wpdb->postmeta pm ON p.ID = pm.post_id + // WHERE pm.meta_key = '_ezine_keyword' + // AND p.post_status = 'future' + // AND p.post_date > NOW( ) + // ORDER BY p.post_date + // "); + + // if (!$next_posts) + // $information['error'] = "Can not get all next schedule post"; + // else + // $information['next_posts'] = $next_posts; + + // } + + // MainWPHelper::write($information); + // } + // catch (Exception $e) + // { + // $information['error'] = $e->getMessage(); + // MainWPHelper::write($information); + // } + + // } + + function get_all_pages() + { + $this->get_all_posts_by_type('page'); + } + + function get_all_pages_int() + { + $rslt = $this->get_recent_posts(null, -1, 'page'); + return $rslt; + } + + function get_all_posts_by_type($type) + { + global $wpdb; + + add_filter('posts_where', array(&$this, 'posts_where')); + + if (isset($_POST['postId'])) + { + $this->posts_where_suffix .= " AND $wpdb->posts.ID = " . $_POST['postId']; + } + else if (isset($_POST['userId'])) + { + $this->posts_where_suffix .= " AND $wpdb->posts.post_author = " . $_POST['userId']; + } + else + { + if (isset($_POST['keyword'])) + { + $this->posts_where_suffix .= " AND $wpdb->posts.post_content LIKE '%" . $_POST['keyword'] . "%'"; + } + if (isset($_POST['dtsstart']) && $_POST['dtsstart'] != '') + { + $this->posts_where_suffix .= " AND $wpdb->posts.post_modified > '" . $_POST['dtsstart'] . "'"; + } + if (isset($_POST['dtsstop']) && $_POST['dtsstop'] != '') + { + $this->posts_where_suffix .= " AND $wpdb->posts.post_modified < '" . $_POST['dtsstop'] . "'"; + } + } + + $maxPages = MAINWP_CHILD_NR_OF_PAGES; + if (isset($_POST['maxRecords'])) + { + $maxPages = $_POST['maxRecords']; + } + if ($maxPages == 0) + { + $maxPages = 99999; + } + + $rslt = $this->get_recent_posts(explode(',', $_POST['status']), $maxPages, $type); + $this->posts_where_suffix = ''; + + MainWPHelper::write($rslt); + } + + function comments_clauses($clauses) + { + if ($this->comments_and_clauses) $clauses['where'] .= ' ' . $this->comments_and_clauses; + return $clauses; + } + + function get_all_comments() + { + global $wpdb; + + add_filter('comments_clauses', array(&$this, 'comments_clauses')); + + if (isset($_POST['postId'])) + { + $this->comments_and_clauses .= " AND $wpdb->comments.comment_post_ID = " . $_POST['postId']; + } + else + { + if (isset($_POST['keyword'])) + { + $this->comments_and_clauses .= " AND $wpdb->comments.comment_content LIKE '%" . $_POST['keyword'] . "%'"; + } + if (isset($_POST['dtsstart']) && $_POST['dtsstart'] != '') + { + $this->comments_and_clauses .= " AND $wpdb->comments.comment_date > '" . $_POST['dtsstart'] . "'"; + } + if (isset($_POST['dtsstop']) && $_POST['dtsstop'] != '') + { + $this->comments_and_clauses .= " AND $wpdb->comments.comment_date < '" . $_POST['dtsstop'] . "'"; + } + } + + $maxComments = MAINWP_CHILD_NR_OF_COMMENTS; + if (isset($_POST['maxRecords'])) + { + $maxComments = $_POST['maxRecords']; + } + + if ($maxComments == 0) + { + $maxComments = 99999; + } + + $rslt = $this->get_recent_comments(explode(',', $_POST['status']), $maxComments); + $this->comments_and_clauses = ''; + + MainWPHelper::write($rslt); + } + + function get_recent_comments($pAllowedStatuses, $pCount) + { + if (!function_exists('get_comment_author_url')) include_once(WPINC . '/comment-template.php'); + $allComments = array(); + + foreach ($pAllowedStatuses as $status) + { + $params = array('status' => $status); + if ($pCount != 0) $params['number'] = $pCount; + $comments = get_comments($params); + if (is_array($comments)) + { + foreach ($comments as $comment) + { + $post = get_post($comment->comment_post_ID); + $outComment = array(); + $outComment['id'] = $comment->comment_ID; + $outComment['status'] = wp_get_comment_status($comment->comment_ID); + $outComment['author'] = $comment->comment_author; + $outComment['author_url'] = get_comment_author_url($comment->comment_ID); + $outComment['author_ip'] = get_comment_author_IP($comment->comment_ID); + $outComment['author_email'] = $email = apply_filters( 'comment_email', $comment->comment_author_email ); + if ((!empty($outComment['author_email'])) && ($outComment['author_email'] != '@')) { + $outComment['author_email'] = ''.$outComment['author_email'].''; + } + $outComment['postId'] = $comment->comment_post_ID; + $outComment['postName'] = $post->post_title; + $outComment['comment_count'] = $post->comment_count; + $outComment['content'] = $comment->comment_content; + $outComment['dts'] = strtotime($comment->comment_date_gmt); + $allComments[] = $outComment; + } + } + } + return $allComments; + } + + function theme_action() + { + //Read form data + $action = $_POST['action']; + $theme = $_POST['theme']; + + if ($action == 'activate') + { + include_once(ABSPATH . '/wp-admin/includes/theme.php'); + $theTheme = get_theme($theme); + if ($theTheme != null && $theTheme != '') switch_theme($theTheme['Template'], $theTheme['Stylesheet']); + } + else if ($action == 'delete') + { + include_once(ABSPATH . '/wp-admin/includes/theme.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/screen.php')) include_once(ABSPATH . '/wp-admin/includes/screen.php'); + include_once(ABSPATH . '/wp-admin/includes/file.php'); + include_once(ABSPATH . '/wp-admin/includes/template.php'); + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + include_once(ABSPATH . '/wp-admin/includes/class-wp-upgrader.php'); + include_once(ABSPATH . '/wp-admin/includes/class-wp-filesystem-base.php'); + include_once(ABSPATH . '/wp-admin/includes/class-wp-filesystem-direct.php'); + + $wp_filesystem = $this->getWPFilesystem(); + if (empty($wp_filesystem)) $wp_filesystem = new WP_Filesystem_Direct(null); + $themeUpgrader = new Theme_Upgrader(); + + $theme_name = wp_get_theme()->get('Name'); + $themes = explode('||', $theme); + + foreach ($themes as $idx => $themeToDelete) + { + if ($themeToDelete != $theme_name) + { + $theTheme = get_theme($themeToDelete); + if ($theTheme != null && $theTheme != '') + { + $tmp['theme'] = $theTheme['Template']; + $themeUpgrader->delete_old_theme(null, null, null, $tmp); + } + } + } + } + else + { + $information['status'] = 'FAIL'; + } + + if (!isset($information['status'])) $information['status'] = 'SUCCESS'; + $information['sync'] = $this->getSiteStats(array(), false); + MainWPHelper::write($information); + } + + function get_all_themes() + { + $keyword = $_POST['keyword']; + $status = $_POST['status']; + $rslt = $this->get_all_themes_int(true, $keyword, $status); + + MainWPHelper::write($rslt); + } + + function get_all_themes_int($filter, $keyword = '', $status = '') + { + $rslt = array(); + $themes = get_themes(); //todo: deprecated, use wp_get_themes + if (is_array($themes)) + { + $theme_name = wp_get_theme()->get('Name'); + + foreach ($themes as $theme) + { + $out = array(); + $out['name'] = $theme['Name']; + $out['title'] = $theme['Title']; + $out['description'] = $theme['Description']; + $out['version'] = $theme['Version']; + $out['active'] = ($theme['Name'] == $theme_name) ? 1 : 0; + $out['slug'] = $theme['Stylesheet']; + if (!$filter) + { + $rslt[] = $out; + } + else if ($out['active'] == (($status == 'active') ? 1 : 0)) + { + if ($keyword == '' || stristr($out['title'], $keyword)) $rslt[] = $out; + } + } + } + + return $rslt; + } + + function plugin_action() + { + //Read form data + $action = $_POST['action']; + $plugins = explode('||', $_POST['plugin']); + + if ($action == 'activate') + { + include_once(ABSPATH . '/wp-admin/includes/plugin.php'); + + foreach ($plugins as $idx => $plugin) + { + if ($plugin != $this->plugin_slug) + { + $thePlugin = get_plugin_data($plugin); + if ($thePlugin != null && $thePlugin != '') activate_plugin($plugin); + } + } + } + else if ($action == 'deactivate') + { + include_once(ABSPATH . '/wp-admin/includes/plugin.php'); + + foreach ($plugins as $idx => $plugin) + { + if ($plugin != $this->plugin_slug) + { + $thePlugin = get_plugin_data($plugin); + if ($thePlugin != null && $thePlugin != '') deactivate_plugins($plugin); + } + } + } + else if ($action == 'delete') + { + include_once(ABSPATH . '/wp-admin/includes/plugin.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/screen.php')) include_once(ABSPATH . '/wp-admin/includes/screen.php'); + include_once(ABSPATH . '/wp-admin/includes/file.php'); + include_once(ABSPATH . '/wp-admin/includes/template.php'); + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + include_once(ABSPATH . '/wp-admin/includes/class-wp-upgrader.php'); + include_once(ABSPATH . '/wp-admin/includes/class-wp-filesystem-base.php'); + include_once(ABSPATH . '/wp-admin/includes/class-wp-filesystem-direct.php'); + + $wp_filesystem = $this->getWPFilesystem(); + if ($wp_filesystem == null) $wp_filesystem = new WP_Filesystem_Direct(null); + $pluginUpgrader = new Plugin_Upgrader(); + + foreach ($plugins as $idx => $plugin) + { + if ($plugin != $this->plugin_slug) + { + $thePlugin = get_plugin_data($plugin); + if ($thePlugin != null && $thePlugin != '') + { + $tmp['plugin'] = $plugin; + $pluginUpgrader->delete_old_plugin(null, null, null, $tmp); + } + } + } + } + else + { + $information['status'] = 'FAIL'; + } + + if (!isset($information['status'])) $information['status'] = 'SUCCESS'; + $information['sync'] = $this->getSiteStats(array(), false); + MainWPHelper::write($information); + } + + function get_all_plugins() + { + $keyword = $_POST['keyword']; + $status = $_POST['status']; + $rslt = $this->get_all_plugins_int(true, $keyword, $status); + + MainWPHelper::write($rslt); + } + + function get_all_plugins_int($filter, $keyword = '', $status = '') + { + if (!function_exists('get_plugins')) + { + include_once(ABSPATH . 'wp-admin/includes/plugin.php'); + } + $rslt = array(); + $plugins = get_plugins(); //todo: deprecated, use wp_get_plugins + if (is_array($plugins)) + { + $active_plugins = get_option('active_plugins'); + + foreach ($plugins as $pluginslug => $plugin) + { + if ($pluginslug == $this->plugin_slug) continue; + + $out = array(); + $out['name'] = $plugin['Name']; + $out['slug'] = $pluginslug; + $out['description'] = $plugin['Description']; + $out['version'] = $plugin['Version']; + $out['active'] = (is_array($active_plugins) && in_array($pluginslug, $active_plugins)) ? 1 : 0; + if (!$filter) + { + $rslt[] = $out; + } + else if ($out['active'] == (($status == 'active') ? 1 : 0)) + { + if ($keyword == '' || stristr($out['name'], $keyword)) $rslt[] = $out; + } + } + } + + return $rslt; + } + + function get_all_users() + { + $roles = explode(',', $_POST['role']); + $allusers = array(); + if (is_array($roles)) + { + foreach ($roles as $role) + { + $new_users = get_users('role=' . $role); + // $allusers[$role] = array(); + foreach ($new_users as $new_user) + { + $usr = array(); + $usr['id'] = $new_user->ID; + $usr['login'] = $new_user->user_login; + $usr['nicename'] = $new_user->user_nicename; + $usr['email'] = $new_user->user_email; + $usr['registered'] = $new_user->user_registered; + $usr['status'] = $new_user->user_status; + $usr['display_name'] = $new_user->display_name; + $usr['role'] = $role; + $usr['post_count'] = count_user_posts($new_user->ID); + $usr['avatar'] = get_avatar($new_user->ID, 32); + $allusers[] = $usr; + } + } + } + + MainWPHelper::write($allusers); + } + + function get_all_users_int() + { + $allusers = array(); + + $new_users = get_users(); + if (is_array($new_users)) + { + foreach ($new_users as $new_user) + { + $usr = array(); + $usr['id'] = $new_user->ID; + $usr['login'] = $new_user->user_login; + $usr['nicename'] = $new_user->user_nicename; + $usr['email'] = $new_user->user_email; + $usr['registered'] = $new_user->user_registered; + $usr['status'] = $new_user->user_status; + $usr['display_name'] = $new_user->display_name; + $userdata = get_userdata($new_user->ID); + $user_roles = $userdata->roles; + $user_role = array_shift($user_roles); + $usr['role'] = $user_role; + $usr['post_count'] = count_user_posts($new_user->ID); + $allusers[] = $usr; + } + } + + return $allusers; + } + + + function search_users() + { + $columns = explode(',', $_POST['search_columns']); + $allusers = array(); + $exclude = array(); + + foreach ($columns as $col) + { + if (empty($col)) + continue; + + $user_query = new WP_User_Query(array('search' => $_POST['search'], + 'fields' => 'all_with_meta', + 'search_columns' => array($col), + 'query_orderby' => array($col), + 'exclude' => $exclude)); + if (!empty($user_query->results)) + { + foreach ($user_query->results as $new_user) + { + $exclude[] = $new_user->ID; + $usr = array(); + $usr['id'] = $new_user->ID; + $usr['login'] = $new_user->user_login; + $usr['nicename'] = $new_user->user_nicename; + $usr['email'] = $new_user->user_email; + $usr['registered'] = $new_user->user_registered; + $usr['status'] = $new_user->user_status; + $usr['display_name'] = $new_user->display_name; + $userdata = get_userdata($new_user->ID); + $user_roles = $userdata->roles; + $user_role = array_shift($user_roles); + $usr['role'] = $user_role; + $usr['post_count'] = count_user_posts($new_user->ID); + $usr['avatar'] = get_avatar($new_user->ID, 32); + $allusers[] = $usr; + } + } + } + + MainWPHelper::write($allusers); + } + +//Show stats without login - only allowed while no account is added yet + function getSiteStatsNoAuth($information = array()) + { + if (get_option('mainwp_child_pubkey')) + { + MainWPHelper::error(__('This site already contains a link - please disable and enable the MainWP plugin.','mainwp-child')); + } + + global $wp_version; + $information['wpversion'] = $wp_version; + MainWPHelper::write($information); + } + + //Deactivating the plugin + function deactivate() + { + include_once(ABSPATH . 'wp-admin/includes/plugin.php'); + deactivate_plugins($this->plugin_slug, true); + $information = array(); + if (is_plugin_active($this->plugin_slug)) + { + MainWPHelper::error('Plugin still active'); + } + $information['deactivated'] = true; + MainWPHelper::write($information); + } + + function activation() + { + if (get_option('_sicknetwork_pubkey') !== false && get_option('mainwp_child_activated_once') === false) + { + $options = array('sicknetwork_auth' => 'mainwp_child_auth', + 'sicknetwork_clone_sites' => 'mainwp_child_clone_sites', + '_sicknetwork_uniqueId' => 'mainwp_child_uniqueId', + '_sicknetwork_pluginDir' => 'mainwp_child_pluginDir', + '_sicknetwork_htaccess_set' => 'mainwp_child_htaccess_set', + '_sicknetwork_fix_htaccess' => 'mainwp_child_fix_htaccess', + '_sicknetwork_pubkey' => 'mainwp_child_pubkey', + '_sicknetwork_server' => 'mainwp_child_server', + '_sicknetwork_nonce' => 'mainwp_child_nonce', + '_sicknetwork_nossl' => 'mainwp_child_nossl', + '_sicknetwork_nossl_key' => 'mainwp_child_nossl_key', + '_sicknetwork_remove_wp_version' => 'mainwp_child_remove_wp_version', + '_sicknetwork_remove_rsd' => 'mainwp_child_remove_rsd', + '_sicknetwork_remove_wlw' => 'mainwp_child_remove_wlw', + '_sicknetwork_remove_core_updates' => 'mainwp_child_remove_core_updates', + '_sicknetwork_remove_plugin_updates' => 'mainwp_child_remove_plugin_updates', + '_sicknetwork_remove_theme_updates' => 'mainwp_child_remove_theme_updates', + '_sicknetwork_remove_php_reporting' => 'mainwp_child_remove_php_reporting', + '_sicknetwork_remove_scripts_version' => 'mainwp_child_remove_scripts_version', + '_sicknetwork_remove_styles_version' => 'mainwp_child_remove_styles_version', + '_sicknetwork_clone_permalink' => 'mainwp_child_clone_permalink', + '_sicknetwork_click_data' => 'mainwp_child_click_data'); + + foreach ($options as $old => $new) + { + if (get_option($old) !== false) + { + update_option($new, get_option($old)); + } + } + } + else + { + $to_delete = array('mainwp_child_pubkey', 'mainwp_child_nonce', 'mainwp_child_nossl', 'mainwp_child_nossl_key', 'mainwp_child_uniqueId'); + foreach ($to_delete as $delete) + { + if (get_option($delete)) + { + delete_option($delete); + } + } + } + + update_option('mainwp_child_activated_once', true); + } + + function deactivation() + { + $to_delete = array('mainwp_child_pubkey', 'mainwp_child_nonce', 'mainwp_child_nossl', 'mainwp_child_nossl_key', 'mainwp_child_remove_styles_version', 'mainwp_child_remove_scripts_version', 'mainwp_child_remove_php_reporting', 'mainwp_child_remove_theme_updates', 'mainwp_child_remove_plugin_updates', 'mainwp_child_remove_core_updates', 'mainwp_child_remove_wlw', 'mainwp_child_remove_rsd', 'mainwp_child_remove_wp_version', 'mainwp_child_server'); + foreach ($to_delete as $delete) + { + if (get_option($delete)) + { + delete_option($delete); + } + } + } + + function getWPFilesystem() + { + global $wp_filesystem; + + if (empty($wp_filesystem)) + { + ob_start(); + if (file_exists(ABSPATH . '/wp-admin/includes/screen.php')) include_once(ABSPATH . '/wp-admin/includes/screen.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/template.php')) include_once(ABSPATH . '/wp-admin/includes/template.php'); + $creds = request_filesystem_credentials('test', '', false, false, $extra_fields = null); + ob_end_clean(); + if (empty($creds)) + { + define('FS_METHOD', 'direct'); + } + WP_Filesystem($creds); + } + + if (empty($wp_filesystem)) + { + MainWPHelper::error($this->FTP_ERROR); + } + else if (is_wp_error($wp_filesystem->errors)) + { + $errorCodes = $wp_filesystem->errors->get_error_codes(); + if (!empty($errorCodes)) + { + MainWPHelper::error(__('Wordpress Filesystem error: ','mainwp-child') . $wp_filesystem->errors->get_error_message()); + } + } + + return $wp_filesystem; + } + + function getTotalFileSize($directory = WP_CONTENT_DIR) + { + if (MainWPHelper::function_exists('popen')) + { + $popenHandle = @popen('du -s ' . $directory . ' --exclude "' . str_replace(ABSPATH, '', WP_CONTENT_DIR) . '/uploads/mainwp"', 'r'); + if (gettype($popenHandle) == 'resource') + { + $size = @fread($popenHandle, 1024); + @pclose($popenHandle); + $size = substr($size, 0, strpos($size, "\t")); + if (ctype_digit($size)) + { + return $size / 1024; + } + } + } + if (MainWPHelper::function_exists('shell_exec')) + { + $size = @shell_exec('du -s ' . $directory . ' --exclude "' . str_replace(ABSPATH, '', WP_CONTENT_DIR) . '/uploads/mainwp"', 'r'); + if ($size != NULL) + { + $size = substr($size, 0, strpos($size, "\t")); + if (ctype_digit($size)) + { + return $size / 1024; + } + } + } + if (class_exists('COM')) + { + $obj = new COM('scripting.filesystemobject'); + + if (is_object($obj)) + { + $ref = $obj->getfolder($directory); + + $size = $ref->size; + + $obj = null; + if (ctype_digit($size)) + { + return $size / 1024; + } + } + } + + function dirsize($dir) + { + $dirs = array($dir); + $size = 0; + while (isset ($dirs[0])) + { + $path = array_shift($dirs); + if (stristr($path, WP_CONTENT_DIR . '/uploads/mainwp')) continue; + foreach (glob($path . '/*') AS $next) + { + if (is_dir($next)) + { + $dirs[] = $next; + } + else + { + $fs = filesize($next); + $size += $fs; + } + } + } + return $size / 1024 / 1024; + } + + return dirsize($directory); + } + + function serverInformation() + { + @ob_start(); + MainWPChildServerInformation::render(); + $output['information'] = @ob_get_contents(); + @ob_end_clean(); + @ob_start(); + MainWPChildServerInformation::renderCron(); + $output['cron'] = @ob_get_contents(); + @ob_end_clean(); + + MainWPHelper::write($output); + } + + function maintenance_site() + { + global $wpdb; + $maint_options = $_POST['options']; + if (!is_array($maint_options)) + { + $information['status'] = 'FAIL'; + $maint_options = array(); + } + + if (in_array('revisions', $maint_options)) + { + $sql_clean = "DELETE FROM $wpdb->posts WHERE post_type = 'revision'"; + $wpdb->query($sql_clean); + } + + if (in_array('autodraft', $maint_options)) + { + $sql_clean = "DELETE FROM $wpdb->posts WHERE post_status = 'auto-draft'"; + $wpdb->query($sql_clean); + } + + if (in_array('trashpost', $maint_options)) + { + $sql_clean = "DELETE FROM $wpdb->posts WHERE post_status = 'trash'"; + $wpdb->query($sql_clean); + } + + if (in_array('spam', $maint_options)) + { + $sql_clean = "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam'"; + $wpdb->query($sql_clean); + } + + if (in_array('pending', $maint_options)) + { + $sql_clean = "DELETE FROM $wpdb->comments WHERE comment_approved = '0'"; + $wpdb->query($sql_clean); + } + + if (in_array('trashcomment', $maint_options)) + { + $sql_clean = "DELETE FROM $wpdb->comments WHERE comment_approved = 'trash'"; + $wpdb->query($sql_clean); + } + + if (in_array('tags', $maint_options)) + { + $post_tags = get_terms('post_tag', array('hide_empty' => false)); + if (is_array($post_tags)) + { + foreach ($post_tags as $tag) + { + if ($tag->count == 0) + { + wp_delete_term($tag->term_id, 'post_tag'); + } + } + } + } + + if (in_array('categories', $maint_options)) + { + $post_cats = get_terms('category', array('hide_empty' => false)); + if (is_array($post_cats)) + { + foreach ($post_cats as $cat) + { + if ($cat->count == 0) + { + wp_delete_term($cat->term_id, 'category'); + } + } + } + } + + if (in_array('optimize', $maint_options)) + { + $this->maintenance_optimize(true); + } + + if (!isset($information['status'])) $information['status'] = 'SUCCESS'; + MainWPHelper::write($information); + } + + function maintenance_optimize($optimize) + { + if (!$optimize) return; + + global $wpdb; + + $sql = 'SHOW TABLE STATUS FROM `' . DB_NAME . '`'; + $result = @MainWPChildDB::_query($sql, $wpdb->dbh); + if (@MainWPChildDB::num_rows($result) && @MainWPChildDB::is_result($result)) + { + while ($row = MainWPChildDB::fetch_array($result)) + { + $sql = 'OPTIMIZE TABLE ' . $row[0]; + MainWPChildDB::_query($sql, $wpdb->dbh); + } + } + } + + public function keyword_links_action() { + MainWPKeywordLinks::Instance()->action(); + } + +} + +?> \ No newline at end of file diff --git a/class/MainWPChildDB.class.php b/class/MainWPChildDB.class.php new file mode 100644 index 00000000..cfedcfa1 --- /dev/null +++ b/class/MainWPChildDB.class.php @@ -0,0 +1,119 @@ +dbh instanceof mysqli); + } + + public static function _query($query, $link) + { + if (self::use_mysqli()) + { + return mysqli_query($link, $query); + } + else + { + return mysql_query($query, $link); + } + } + + public static function fetch_array($result) + { + if (self::use_mysqli()) + { + return mysqli_fetch_array($result, MYSQLI_ASSOC); + } + else + { + return mysql_fetch_array($result, MYSQL_ASSOC); + } + } + + public static function num_rows($result) + { + if (self::use_mysqli()) + { + return mysqli_num_rows($result); + } + else + { + return mysql_num_rows($result); + } + } + + public static function connect($host, $user, $pass) + { + if (self::use_mysqli()) + { + return mysqli_connect($host, $user, $pass); + } + else + { + return mysql_connect($host, $user, $pass); + } + } + + public static function select_db($db) + { + if (self::use_mysqli()) + { + /** @var $wpdb wpdb */ + global $wpdb; + + return mysqli_select_db($wpdb->dbh, $db); + } + else + { + return mysql_select_db($db); + } + } + + public static function error() + { + if (self::use_mysqli()) + { + /** @var $wpdb wpdb */ + global $wpdb; + + return mysqli_error($wpdb->dbh); + } + else + { + return mysql_error(); + } + } + + public static function real_escape_string($value) + { + /** @var $wpdb wpdb */ + global $wpdb; + + if (self::use_mysqli()) + { + return mysqli_real_escape_string($wpdb->dbh, $value); + } + else + { + return mysql_real_escape_string($value, $wpdb->dbh); + } + } + + public static function is_result($result) + { + if (self::use_mysqli()) + { + return ($result instanceof mysqli_result); + } + else + { + return is_resource($result); + } + } +} diff --git a/class/MainWPChildServerInformation.class.php b/class/MainWPChildServerInformation.class.php new file mode 100644 index 00000000..1c011e2e --- /dev/null +++ b/class/MainWPChildServerInformation.class.php @@ -0,0 +1,450 @@ + +
+ + + + + + + + + + + + =', '3.4', 'getWordpressVersion'); + self::renderRow('PHP Version', '>=', '5.2.4', 'getPHPVersion'); + self::renderRow('MySQL Version', '>=', '5.0', 'getMySQLVersion'); + self::renderRow('PHP Max Execution Time', '>=', '30', 'getMaxExecutionTime', 'seconds', '=', '0'); + self::renderRow('PHP Upload Max Filesize', '>=', '2M', 'getUploadMaxFilesize', '(2MB+ best for upload of big plugins)'); + self::renderRow('PHP Post Max Size', '>=', '2M', 'getPostMaxSize', '(2MB+ best for upload of big plugins)'); +// self::renderRow('PHP Memory Limit', '>=', '128M', 'getPHPMemoryLimit', '(256M+ best for big backups)'); + self::renderRow('PCRE Backtracking Limit', '>=', '10000', 'getOutputBufferSize'); + self::renderRow('SSL Extension Enabled', '=', true, 'getSSLSupport'); + ?> + +
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + $cron) + { + foreach ($cron as $hook => $cron_info) + { + foreach ($cron_info as $key => $schedule ) + { + ?> + + + +
+ is_writable($path)) + { + return self::renderDirectoryRow('MainWP upload directory', $path, 'Writable', 'Directory not writable', false); + } + } + else + { + if (!is_writable($path)) + { + return self::renderDirectoryRow('MainWP upload directory', $path, 'Writable', 'Directory not writable', false); + } + } + + return self::renderDirectoryRow('MainWP upload directory', $path, 'Writable', '/', true); + } + + protected static function renderDirectoryRow($pName, $pDirectory, $pCheck, $pResult, $pPassed) + { + ?> + + + + + + Pass' : 'Warning'); ?> + + + + + + + Pass' : 'Warning'); ?> + + get_var('SHOW VARIABLES LIKE "version"', 1); + } + + protected static function getPHPMemoryLimit() + { + return ini_get('memory_limit'); + } + protected static function getOS() + { + echo PHP_OS; + } + protected static function getArchitecture() + { + echo (PHP_INT_SIZE * 8)?> bit get_results("SHOW VARIABLES LIKE 'sql_mode'"); + if (is_array($mysqlinfo)) $sql_mode = $mysqlinfo[0]->Value; + if (empty($sql_mode)) $sql_mode = __('NOT SET'); + echo $sql_mode; + } + protected static function getPHPAllowUrlFopen() + { + if(ini_get('allow_url_fopen')) $allow_url_fopen = __('ON'); + else $allow_url_fopen = __('OFF'); + echo $allow_url_fopen; + } + protected static function getPHPExif() + { + if (is_callable('exif_read_data')) $exif = __('YES'). " ( V" . substr(phpversion('exif'),0,4) . ")" ; + else $exif = __('NO'); + echo $exif; + } + protected static function getPHPIPTC() + { + if (is_callable('iptcparse')) $iptc = __('YES'); + else $iptc = __('NO'); + echo $iptc; + } + protected static function getPHPXML() + { + if (is_callable('xml_parser_create')) $xml = __('YES'); + else $xml = __('NO'); + echo $xml; + } + + // new + + protected static function getCurrentlyExecutingScript() { + echo $_SERVER['PHP_SELF']; + } + + protected static function getServerGetawayInterface() { + echo $_SERVER['GATEWAY_INTERFACE']; + } + + protected static function getServerIP() { + echo $_SERVER['SERVER_ADDR']; + } + + protected static function getSeverName() { + echo $_SERVER['SERVER_NAME']; + } + + protected static function getServerSoftware() { + echo $_SERVER['SERVER_SOFTWARE']; + } + + protected static function getServerProtocol() { + echo $_SERVER['SERVER_PROTOCOL']; + } + + protected static function getServerRequestMethod() { + echo $_SERVER['REQUEST_METHOD']; + } + + protected static function getServerRequestTime(){ + echo $_SERVER['REQUEST_TIME']; + } + + protected static function getServerQueryString() { + echo $_SERVER['QUERY_STRING']; + } + + protected static function getServerHTTPAccept() { + echo $_SERVER['HTTP_ACCEPT']; + } + + protected static function getServerAcceptCharset() { + if (!isset($_SERVER['HTTP_ACCEPT_CHARSET']) || ($_SERVER['HTTP_ACCEPT_CHARSET'] == '')) { + echo __('N/A','mainwp'); + } + else + { + echo $_SERVER['HTTP_ACCEPT_CHARSET']; + } + } + + protected static function getHTTPHost() { + echo $_SERVER['HTTP_HOST']; + } + + protected static function getCompleteURL() { + echo $_SERVER['HTTP_REFERER']; + } + + protected static function getUserAgent() { + echo $_SERVER['HTTP_USER_AGENT']; + } + + protected static function getHTTPS() { + if ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != '' ) { + echo __('ON','mainwp') . ' - ' . $_SERVER['HTTPS'] ; + } + else { + echo __('OFF','mainwp') ; + } + } + + protected static function getRemoteAddress() { + echo $_SERVER['REMOTE_ADDR']; + } + + protected static function getRemoteHost() { + if (!isset($_SERVER['REMOTE_HOST']) || ($_SERVER['REMOTE_HOST'] == '')) { + echo __('N/A','mainwp'); + } + else { + echo $_SERVER['REMOTE_HOST'] ; + } + } + + protected static function getRemotePort() { + echo $_SERVER['REMOTE_PORT']; + } + + protected static function getScriptFileName() { + echo $_SERVER['SCRIPT_FILENAME']; + } + + protected static function getServerAdmin() { + echo $_SERVER['SERVER_ADMIN']; + } + + protected static function getServerPort() { + echo $_SERVER['SERVER_PORT']; + } + + protected static function getServerSignature() { + echo $_SERVER['SERVER_SIGNATURE']; + } + + protected static function getServerPathTranslated() { + if (!isset($_SERVER['PATH_TRANSLATED']) || ($_SERVER['PATH_TRANSLATED'] == '')) { + echo __('N/A','mainwp') ; + } + else { + echo $_SERVER['PATH_TRANSLATED'] ; + } + } + + protected static function getScriptName() { + echo $_SERVER['SCRIPT_NAME']; + } + + protected static function getCurrentPageURI() { + echo $_SERVER['REQUEST_URI']; + } + protected static function getWPRoot() { + echo ABSPATH ; + } + + function formatSizeUnits($bytes) + { + if ($bytes >= 1073741824) + { + $bytes = number_format($bytes / 1073741824, 2) . ' GB'; + } + elseif ($bytes >= 1048576) + { + $bytes = number_format($bytes / 1048576, 2) . ' MB'; + } + elseif ($bytes >= 1024) + { + $bytes = number_format($bytes / 1024, 2) . ' KB'; + } + elseif ($bytes > 1) + { + $bytes = $bytes . ' bytes'; + } + elseif ($bytes == 1) + { + $bytes = $bytes . ' byte'; + } + else + { + $bytes = '0 bytes'; + } + + return $bytes; + + } + +} + diff --git a/class/MainWPClone.class.php b/class/MainWPClone.class.php new file mode 100644 index 00000000..a9412906 --- /dev/null +++ b/class/MainWPClone.class.php @@ -0,0 +1,1174 @@ +')) + { + wp_enqueue_script('jquery-ui', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js', array('jquery')); + wp_enqueue_style('jquery-ui-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/smoothness/jquery-ui.css'); + } + else + { + wp_enqueue_script('jquery-ui-tooltip'); + wp_enqueue_script('jquery-ui-autocomplete'); + wp_enqueue_script('jquery-ui-progressbar'); + wp_enqueue_script('jquery-ui-dialog'); + wp_enqueue_style('jquery-ui-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css'); + } + } + public static function renderHeader() + { + self::renderStyle(); + ?> +
+ +
+ false); + $movefile = wp_handle_upload($uploadedfile, $upload_overrides); + if ($movefile) + { + $uploadFile = str_replace(ABSPATH, '', $movefile['file']); + } + else + { + $uploadError = __('File could not be uploaded.','mainwp-child'); + } + } + else + { + $uploadError = __('File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.','mainwp-child'); + } + } + + $sitesToClone = get_option('mainwp_child_clone_sites'); + $uploadSizeInBytes = min(MainWPHelper::return_bytes(ini_get('upload_max_filesize')), MainWPHelper::return_bytes(ini_get('post_max_size'))); + $uploadSize = MainWPHelper::human_filesize($uploadSizeInBytes); + self::renderHeader(); + + ?>

' . __('Cloning is currently off - To turn on return to your main dashboard and turn cloning on on the Migrate/Clone page.','mainwp-child') . ''; + return; + } + + if (!is_writable(WP_CONTENT_DIR)) + { + echo '
' . __('Your content directory is not writable. Please set 0755 permission to ','mainwp-child') . basename(WP_CONTENT_DIR) . '. (' . WP_CONTENT_DIR . ')
'; + $error = true; + } + ?> + + +
' . __('Cloning is currently on but no sites have been allowed, to allow sites return to your main dashboard and turn cloning on on the Migrate/Clone page.','mainwp-child') . ''; + } + else + { +?> +
+
+
+

+
+
+ $siteToClone) + { + ?> +
+
MB
+
+
+
+ +
+
+
+
+
+
+
+
+ +

+
+ )
+
+


+
+ false); + $movefile = wp_handle_upload($uploadedfile, $upload_overrides); + if ($movefile) + { + $uploadFile = str_replace(ABSPATH, '', $movefile['file']); + } + else + { + $uploadError = __('File could not be uploaded.','mainwp-child'); + } + } + else + { + $uploadError = __('File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.','mainwp-child'); + } + } + + $uploadSizeInBytes = min(MainWPHelper::return_bytes(ini_get('upload_max_filesize')), MainWPHelper::return_bytes(ini_get('post_max_size'))); + $uploadSize = MainWPHelper::human_filesize($uploadSizeInBytes); + self::renderHeader(); + + ?>

' . __('Your content directory is not writable. Please set 0755 permission to ','mainwp-child') . basename(WP_CONTENT_DIR) . '. (' . WP_CONTENT_DIR . ')'; + $error = true; + } + ?> + + +
+ )
+
+


+
+ +
+ + + + 'createCloneBackup', 'key' => $key, 'file' => $rand, 'wpversion' => $wp_version)); + + if (!$result['backup']) throw new Exception(__('Could not create backupfile on child','mainwp-child')); + @session_start(); + + update_option('mainwp_temp_clone_plugins', $result['plugins']); + update_option('mainwp_temp_clone_themes', $result['themes']); + + $output = array('url' => $result['backup'], 'size' => round($result['size'] / 1024, 0)); + } + catch (Exception $e) + { + $output = array('error' => $e->getMessage()); + } + + die(json_encode($output)); + } + + public static function cloneBackupCreatePoll() + { + try + { + if (!isset($_POST['siteId'])) throw new Exception(__('No site given','mainwp-child')); + $siteId = $_POST['siteId']; + $rand = $_POST['rand']; + + $sitesToClone = get_option('mainwp_child_clone_sites'); + if (!is_array($sitesToClone) || !isset($sitesToClone[$siteId])) throw new Exception(__('Site not found','mainwp-child')); + + $siteToClone = $sitesToClone[$siteId]; + $url = $siteToClone['url']; + + $key = $siteToClone['extauth']; + + MainWPHelper::endSession(); + //Send request to the childsite! + $result = MainWPHelper::fetchUrl($url, array('cloneFunc' => 'createCloneBackupPoll', 'key' => $key, 'file' => $rand)); + + if (!isset($result['size'])) throw new Exception(__('Invalid response','mainwp-child')); + + $output = array('size' => round($result['size'] / 1024, 0)); + } + catch (Exception $e) + { + $output = array('error' => $e->getMessage()); + } + //Return size in kb + die(json_encode($output)); + } + + public static function cloneBackupDownload() + { + try + { + if (!isset($_POST['url'])) throw new Exception(__('No download link given','mainwp-child')); + $url = $_POST['url']; + + MainWPHelper::endSession(); + //Send request to the childsite! + $filename = 'download-'.basename($url); + $dirs = MainWPHelper::getMainWPDir('backup', false); + $backupdir = $dirs[0]; + + if ($dh = opendir($backupdir)) + { + while (($file = readdir($dh)) !== false) + { + if ($file != '.' && $file != '..' && preg_match('/^download-(.*).zip/', $file)) + { + @unlink($backupdir . $file); + } + } + closedir($dh); + } + + $filename = $backupdir . $filename; + + $response = wp_remote_get($url, array( 'timeout' => 300000, 'stream' => true, 'filename' => $filename ) ); + + if ( is_wp_error( $response ) ) { + unlink( $filename ); + return $response; + } + + if ( 200 != wp_remote_retrieve_response_code( $response ) ){ + unlink( $filename ); + return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) ); + } + + $output = array('done' => $filename); + + //Delete backup on child + try + { + if (isset($_POST['siteId'])) + { + $siteId = $_POST['siteId']; + $sitesToClone = get_option('mainwp_child_clone_sites'); + if (is_array($sitesToClone) && isset($sitesToClone[$siteId])) + { + $siteToClone = $sitesToClone[$siteId]; + + MainWPHelper::fetchUrl($siteToClone['url'], array('cloneFunc' => 'deleteCloneBackup', 'key' => $siteToClone['extauth'], 'file' => basename($url))); + } + } + } + catch (Exception $e) + { + throw $e; + } + } + catch (Exception $e) + { + $output = array('error' => $e->getMessage()); + } + + die(json_encode($output)); + } + + public static function cloneBackupDownloadPoll() + { + try + { + MainWPHelper::endSession(); + $dirs = MainWPHelper::getMainWPDir('backup', false); + $backupdir = $dirs[0]; + + $files = glob($backupdir . 'download-*.zip'); + + if (count($files) == 0) throw new Exception(__('No download file found','mainwp-child')); + $output = array('size' => filesize($files[0]) / 1024); + } + catch (Exception $e) + { + $output = array('error' => $e->getMessage()); + } + //return size in kb + die(json_encode($output)); + } + + public static function cloneBackupExtract() + { + try + { + MainWPHelper::endSession(); + + $file = $_POST['file']; + $testFull = false; + if ($file == '') + { + $dirs = MainWPHelper::getMainWPDir('backup', false); + $backupdir = $dirs[0]; + + $files = glob($backupdir . 'download-*.zip'); + + if (count($files) == 0) throw new Exception(__('No download file found','mainwp-child')); + $file = $files[0]; + } + else + { + $file = ABSPATH . $file; + if (!file_exists($file)) throw new Exception(__('Backup file not found','mainwp-child')); + $testFull = true; + } + + //return size in kb + $cloneInstall = new MainWPCloneInstall($file); + + //todo: RS: refactor to get those plugins after install (after .18 release) + $cloneInstall->readConfigurationFile(); + + $plugins = get_option('mainwp_temp_clone_plugins'); + $themes = get_option('mainwp_temp_clone_themes'); + + if ($testFull) + { + $cloneInstall->testDownload(); + } + $cloneInstall->removeConfigFile(); + $cloneInstall->extractBackup(); + + $pubkey = get_option('mainwp_child_pubkey'); + $uniqueId = get_option('mainwp_child_uniqueId'); + $server = get_option('mainwp_child_server'); + $nonce = get_option('mainwp_child_nonce'); + $nossl = get_option('mainwp_child_nossl'); + $nossl_key = get_option('mainwp_child_nossl_key'); + $sitesToClone = get_option('mainwp_child_clone_sites'); + + $cloneInstall->install(); + $cloneInstall->updateWPConfig(); + + +// $cloneInstall->update_option('mainwp_child_pubkey', $pubkey); +// $cloneInstall->update_option('mainwp_child_uniqueId', $uniqueId); +// $cloneInstall->update_option('mainwp_child_server', $server); +// $cloneInstall->update_option('mainwp_child_nonce', $nonce); +// $cloneInstall->update_option('mainwp_child_nossl', $nossl); +// $cloneInstall->update_option('mainwp_child_nossl_key', $nossl_key); +// $cloneInstall->update_option('mainwp_child_clone_sites', $sitesToClone); +// $cloneInstall->update_option('mainwp_child_clone_permalink', true); + update_option('mainwp_child_pubkey', $pubkey); + update_option('mainwp_child_uniqueId', $uniqueId); + update_option('mainwp_child_server', $server); + update_option('mainwp_child_nonce', $nonce); + update_option('mainwp_child_nossl', $nossl); + update_option('mainwp_child_nossl_key', $nossl_key); + update_option('mainwp_child_clone_sites', $sitesToClone); + if (!MainWPHelper::startsWith(basename($file), 'download-backup-')) + { + update_option('mainwp_child_restore_permalink', true); + } + else + { + update_option('mainwp_child_clone_permalink', true); + } + + $cloneInstall->clean(); + if ($plugins !== false) + { + $out = array(); + if (is_array($plugins)) + { + $dir = WP_CONTENT_DIR . '/plugins/'; + $fh = @opendir($dir); + while ($entry = @readdir($fh)) + { + if (!is_dir($dir . $entry)) continue; + if (($entry == '.') || ($entry == '..')) continue; + + if (!in_array($entry, $plugins)) MainWPHelper::delete_dir($dir . $entry); + } + @closedir($fh); + } + + delete_option('mainwp_temp_clone_plugins'); + } + if ($themes !== false) + { + $out = array(); + if (is_array($themes)) + { + $dir = WP_CONTENT_DIR . '/themes/'; + $fh = @opendir($dir); + while ($entry = @readdir($fh)) + { + if (!is_dir($dir . $entry)) continue; + if (($entry == '.') || ($entry == '..')) continue; + + if (!in_array($entry, $themes)) MainWPHelper::delete_dir($dir . $entry); + } + @closedir($fh); + } + + delete_option('mainwp_temp_clone_themes'); + } + $output = array('result' => 'ok'); + //todo: remove old tables if other prefix? + + wp_logout(); + wp_set_current_user(0); + } + catch (Exception $e) + { + $output = array('error' => $e->getMessage()); + } + //return size in kb + die(json_encode($output)); + } + + public static function permalinkChanged($action) + { + if ($action == 'update-permalink') + { + if (isset($_POST['permalink_structure']) || isset($_POST['category_base']) || isset($_POST['tag_base'])) + { + delete_option('mainwp_child_clone_permalink'); + delete_option('mainwp_child_restore_permalink'); + } + } + } + + public static function permalinkAdminNotice() + { + if (isset($_POST['permalink_structure']) || isset($_POST['category_base']) || isset($_POST['tag_base'])) return; + ?> + +
.
+ '); + } + + self::renderStyle(); + ?> +

+
+
+

+
+ + + + file = $file; + } + + /** + * Check for default PHP zip support + * + * @return bool + */ + public function checkZipSupport() + { + return class_exists('ZipArchive'); + } + + /** + * Check if we could run zip on console + * + * @return bool + */ + public function checkZipConsole() + { + //todo: implement +// return function_exists('system'); + return false; + } + + public function checkWPZip() + { + return function_exists('unzip_file'); + } + + + public function removeConfigFile() + { + if (!$this->file || !file_exists($this->file)) + return false; + + if ($this->checkZipConsole()) + { + //todo: implement + } + else if ($this->checkZipSupport()) + { + $zip = new ZipArchive(); + $zipRes = $zip->open($this->file); + if ($zipRes) + { + $zip->deleteName('wp-config.php'); + $zip->deleteName('clone'); + $zip->close(); + return true; + } + + return false; + } + else + { + //use pclzip + $zip = new PclZip($this->file); + $list = $zip->delete(PCLZIP_OPT_BY_NAME, 'wp-config.php'); + $list2 = $zip->delete(PCLZIP_OPT_BY_NAME, 'clone'); + if ($list == 0) return false; + return true; + } + return false; + } + + public function testDownload() + { + if (!$this->file_exists('wp-content/')) throw new Exception(__('Not a full backup.','mainwp-child')); + if (!$this->file_exists('wp-admin/')) throw new Exception(__('Not a full backup.','mainwp-child')); + if (!$this->file_exists('wp-content/dbBackup.sql')) throw new Exception(__('Database backup not found.','mainwp-child')); + } + + private function file_exists($file) + { + if ($this->file == 'extracted') return file_get_contents('../clone/config.txt'); + + if (!$this->file || !file_exists($this->file)) + return false; + + if ($this->checkZipConsole()) + { + //todo: implement + } + else if ($this->checkZipSupport()) + { + $zip = new ZipArchive(); + $zipRes = $zip->open($this->file); + if ($zipRes) + { + $content = $zip->locateName($file); + $zip->close(); + return $content !== false; + } + + return false; + } + else + { + return true; + } + return false; + } + + public function readConfigurationFile() + { + $configContents = $this->getConfigContents(); + if ($configContents === FALSE) throw new Exception(__('Cant read configuration file from backup','mainwp-child')); + $this->config = unserialize(base64_decode($configContents)); + + if (isset($this->config['plugins'])) update_option('mainwp_temp_clone_plugins', $this->config['plugins']); + if (isset($this->config['themes'])) update_option('mainwp_temp_clone_themes', $this->config['themes']); + } + + public function setConfig($key, $val) + { + $this->config[$key] = $val; + } + + public function testDatabase() + { + $link = @MainWPChildDB::connect($this->config['dbHost'], $this->config['dbUser'], $this->config['dbPass']); + if (!$link) throw new Exception(__('Invalid database host or user/password.','mainwp-child')); + + $db_selected = @MainWPChildDB::select_db($this->config['dbName'], $link); + if (!$db_selected) throw new Exception(__('Invalid database name','mainwp-child')); + } + + public function clean() + { + if (file_exists(WP_CONTENT_DIR . '/dbBackup.sql')) @unlink(WP_CONTENT_DIR . '/dbBackup.sql'); + if (file_exists(ABSPATH . 'clone/config.txt')) @unlink(ABSPATH . 'clone/config.txt'); + if (MainWPHelper::is_dir_empty(ABSPATH . 'clone')) @rmdir(ABSPATH . 'clone'); + + try + { + $dirs = MainWPHelper::getMainWPDir('backup', false); + $backupdir = $dirs[0]; + + $files = glob($backupdir . '*.zip'); + foreach ($files as $file) + { + @unlink($file); + } + } + catch (Exception $e) + { + + } + } + + public function updateWPConfig() + { + $wpConfig = file_get_contents(ABSPATH . 'wp-config.php'); + $wpConfig = $this->replaceVar('table_prefix', $this->config['prefix'], $wpConfig); + if (isset($this->config['lang'])) + { + $wpConfig = $this->replaceDefine('WPLANG', $this->config['lang'], $wpConfig); + } + file_put_contents(ABSPATH . 'wp-config.php', $wpConfig); + } + + public function update_option($name, $value) + { + global $wpdb; + + $var = $wpdb->get_var('SELECT option_value FROM '.$this->config['prefix'].'options WHERE option_name = "'.$name.'"'); + if ($var == NULL) + { + $wpdb->query('INSERT INTO '.$this->config['prefix'].'options (`option_name`, `option_value`) VALUES ("'.$name.'", "'.MainWPChildDB::real_escape_string(maybe_serialize($value)).'")'); + } + else + { + $wpdb->query('UPDATE '.$this->config['prefix'].'options SET option_value = "'.MainWPChildDB::real_escape_string(maybe_serialize($value)).'" WHERE option_name = "'.$name.'"'); + } + } + + /** + * Run the installation + * + * @return bool + */ + public function install() + { + global $wpdb; + + $table_prefix = $this->config['prefix']; + $home = get_option('home'); + $site_url = get_option('siteurl'); + // Install database + define('WP_INSTALLING', true); + define('WP_DEBUG', false); + $query = ''; + $tableName = ''; + $wpdb->query('SET foreign_key_checks = 0'); + $handle = @fopen(WP_CONTENT_DIR . '/dbBackup.sql', 'r'); + if ($handle) + { + $readline = ''; + while (($line = fgets($handle, 81920)) !== false) + { + $readline .= $line; + if (!stristr($line, ";\n") && !feof($handle)) continue; + + $splitLine = explode(";\n", $readline); + for ($i = 0; $i < count($splitLine) - 1; $i++) + { + $wpdb->query($splitLine[$i]); + } + + $readline = $splitLine[count($splitLine) - 1]; + +// if (preg_match('/^(DROP +TABLE +IF +EXISTS|CREATE +TABLE|INSERT +INTO) +(\S+)/is', $readline, $match)) +// { +// if (trim($query) != '') +// { +// $queryTable = $tableName; +// $query = preg_replace('/^(DROP +TABLE +IF +EXISTS|CREATE +TABLE|INSERT +INTO) +(\S+)/is', '$1 `' . $queryTable . '`', $query); +// +// $query = str_replace($this->config['home'], $home, $query); +// $query = str_replace($this->config['siteurl'], $site_url, $query); +// $query = str_replace($this->config['abspath'], ABSPATH, $query); +//// $query = str_replace('\"', '\\\"', $query); +//// $query = str_replace("\\\\'", "\\'", $query); +//// $query = str_replace('\r\n', '\\\r\\\n', $query); +// +// if ($wpdb->query($query) === false) throw new Exception('Error importing database'); +// } +// +// $query = $readline; +// $readline = ''; +// $tableName = trim($match[2], '`; '); +// } +// else +// { +// $query .= $readline; +// $readline = ''; +// } + } + + if (trim($readline) != '') + { + $wpdb->query($readline); + } +// +// if (trim($query) != '') +// { +// $queryTable = $tableName; +// $query = preg_replace('/^(DROP +TABLE +IF +EXISTS|CREATE +TABLE|INSERT +INTO) +(\S+)/is', '$1 `' . $queryTable . '`', $query); +// +// $query = str_replace($this->config['home'], $home, $query); +// $query = str_replace($this->config['siteurl'], $site_url, $query); +//// $query = str_replace('\"', '\\\"', $query); +//// $query = str_replace("\\\\'", "\\'", $query); +//// $query = str_replace('\r\n', '\\\r\\\n', $query); +// if ($wpdb->query($query) === false) throw new Exception(__('Error importing database','mainwp-child')); +// } +// + if (!feof($handle)) + { + throw new Exception(__('Error: unexpected end of file for database','mainwp-child')); + } + fclose($handle); + + $tables = array(); + $tables_db = $wpdb->get_results('SHOW TABLES FROM `' . DB_NAME . '`', ARRAY_N); + + foreach ($tables_db as $curr_table) + { + $tables[] = $curr_table[0]; + } + + $this->icit_srdb_replacer($wpdb->dbh, $this->config['home'], $home, $tables); + $this->icit_srdb_replacer($wpdb->dbh, $this->config['siteurl'], $site_url, $tables); + } + + // Update site url +// $wpdb->query('UPDATE '.$table_prefix.'options SET option_value = "'.$site_url.'" WHERE option_name = "siteurl"'); +// $wpdb->query('UPDATE '.$table_prefix.'options SET option_value = "'.$home.'" WHERE option_name = "home"'); + +// $rows = $wpdb->get_results( 'SELECT * FROM ' . $table_prefix.'options', ARRAY_A); +// foreach ($rows as $row) +// { +// $option_val = $row['option_value']; +// if (!$this->is_serialized($option_val)) continue; +// +// $option_val = $this->recalculateSerializedLengths($option_val); +// $option_id = $row['option_id']; +// $wpdb->query('UPDATE '.$table_prefix.'options SET option_value = "'.MainWPChildDB::real_escape_string($option_val).'" WHERE option_id = '.$option_id); +// } + $wpdb->query('SET foreign_key_checks = 1'); + return true; + } + + public function install_legacy() + { + global $wpdb; + + $table_prefix = $this->config['prefix']; + $home = get_option('home'); + $site_url = get_option('siteurl'); + // Install database + define('WP_INSTALLING', true); + define('WP_DEBUG', false); + $query = ''; + $tableName = ''; + $wpdb->query('SET foreign_key_checks = 0'); + $handle = @fopen(WP_CONTENT_DIR . '/dbBackup.sql', 'r'); + if ($handle) + { + $readline = ''; + while (($line = fgets($handle, 81920)) !== false) + { + $readline .= $line; + if (!stristr($line, "\n") && !feof($handle)) continue; + + if (preg_match('/^(DROP +TABLE +IF +EXISTS|CREATE +TABLE|INSERT +INTO) +(\S+)/is', $readline, $match)) + { + if (trim($query) != '') + { + $queryTable = $tableName; + $query = preg_replace('/^(DROP +TABLE +IF +EXISTS|CREATE +TABLE|INSERT +INTO) +(\S+)/is', '$1 `' . $queryTable . '`', $query); + + $query = str_replace($this->config['home'], $home, $query); + $query = str_replace($this->config['siteurl'], $site_url, $query); + $query = str_replace($this->config['abspath'], ABSPATH, $query); +// $query = str_replace('\"', '\\\"', $query); +// $query = str_replace("\\\\'", "\\'", $query); +// $query = str_replace('\r\n', '\\\r\\\n', $query); + + if ($wpdb->query($query) === false) throw new Exception('Error importing database'); + } + + $query = $readline; + $readline = ''; + $tableName = trim($match[2], '`; '); + } + else + { + $query .= $readline; + $readline = ''; + } + } + + if (trim($query) != '') + { + $queryTable = $tableName; + $query = preg_replace('/^(DROP +TABLE +IF +EXISTS|CREATE +TABLE|INSERT +INTO) +(\S+)/is', '$1 `' . $queryTable . '`', $query); + + $query = str_replace($this->config['home'], $home, $query); + $query = str_replace($this->config['siteurl'], $site_url, $query); +// $query = str_replace('\"', '\\\"', $query); +// $query = str_replace("\\\\'", "\\'", $query); +// $query = str_replace('\r\n', '\\\r\\\n', $query); + if ($wpdb->query($query) === false) throw new Exception(__('Error importing database','mainwp-child')); + } + + if (!feof($handle)) + { + throw new Exception(__('Error: unexpected end of file for database','mainwp-child')); + } + fclose($handle); + } + + // Update site url + $wpdb->query('UPDATE '.$table_prefix.'options SET option_value = "'.$site_url.'" WHERE option_name = "siteurl"'); + $wpdb->query('UPDATE '.$table_prefix.'options SET option_value = "'.$home.'" WHERE option_name = "home"'); + + $rows = $wpdb->get_results( 'SELECT * FROM ' . $table_prefix.'options', ARRAY_A); + foreach ($rows as $row) + { + $option_val = $row['option_value']; + if (!$this->is_serialized($option_val)) continue; + + $option_val = $this->recalculateSerializedLengths($option_val); + $option_id = $row['option_id']; + $wpdb->query('UPDATE '.$table_prefix.'options SET option_value = "'.MainWPChildDB::real_escape_string($option_val).'" WHERE option_id = '.$option_id); + } + $wpdb->query('SET foreign_key_checks = 1'); + return true; + } + + protected function recalculateSerializedLengths($pObject) + { + return preg_replace_callback('|s:(\d+):"(.*?)";|', array($this, 'recalculateSerializedLengths_callback'), $pObject); + } + + protected function recalculateSerializedLengths_callback($matches) + { + return 's:'.strlen($matches[2]).':"'.$matches[2].'";'; + } + + /** + * Check value to find if it was serialized. + * + * If $data is not an string, then returned value will always be false. + * Serialized data is always a string. + * + * @since 2.0.5 + * + * @param mixed $data Value to check to see if was serialized. + * @return bool False if not serialized and true if it was. + */ + function is_serialized( $data ) { + // if it isn't a string, it isn't serialized + if ( ! is_string( $data ) ) + return false; + $data = trim( $data ); + if ( 'N;' == $data ) + return true; + $length = strlen( $data ); + if ( $length < 4 ) + return false; + if ( ':' !== $data[1] ) + return false; + $lastc = $data[$length-1]; + if ( ';' !== $lastc && '}' !== $lastc ) + return false; + $token = $data[0]; + switch ( $token ) { + case 's' : + if ( '"' !== $data[$length-2] ) + return false; + case 'a' : + case 'O' : + return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data ); + case 'b' : + case 'i' : + case 'd' : + return (bool) preg_match( "/^{$token}:[0-9.E-]+;\$/", $data ); + } + return false; + } + + public function cleanUp() + { + // Clean up! + @unlink('../dbBackup.sql'); + } + + public function getConfigContents() + { + if ($this->file == 'extracted') return file_get_contents('../clone/config.txt'); + + if (!$this->file || !file_exists($this->file)) + return false; + + if ($this->checkZipConsole()) + { + //todo: implement + } + else if ($this->checkZipSupport()) + { + $zip = new ZipArchive(); + $zipRes = $zip->open($this->file); + if ($zipRes) + { + $content = $zip->getFromName('clone/config.txt'); +// $zip->deleteName('clone/config.txt'); +// $zip->deleteName('clone/'); + $zip->close(); + return $content; + } + + return false; + } + else + { + //use pclzip + $zip = new PclZip($this->file); + $content = $zip->extract(PCLZIP_OPT_BY_NAME, 'clone/config.txt', + PCLZIP_OPT_EXTRACT_AS_STRING); + if (!is_array($content) || !isset($content[0]['content'])) return false; + return $content[0]['content']; + } + return false; + } + + /** + * Extract backup + * + * @return bool + */ + public function extractBackup() + { + if (!$this->file || !file_exists($this->file)) + return false; + + if ($this->checkWPZip()) + return $this->extractWPZipBackup(); + else if ($this->checkZipConsole()) + return $this->extractZipConsoleBackup(); + else if ($this->checkZipSupport()) + return $this->extractZipBackup(); + else + return $this->extractZipPclBackup(); + + return false; + } + + /** + * Extract backup using default PHP zip library + * + * @return bool + */ + public function extractZipBackup() + { + $zip = new ZipArchive(); + $zipRes = $zip->open($this->file); + if ($zipRes) + { + @$zip->extractTo(ABSPATH); + $zip->close(); + return true; + } + return false; + } + + public function extractWPZipBackup() + { + MainWPHelper::getWPFilesystem(); + global $wp_filesystem; + $tmpdir = ABSPATH; + if (($wp_filesystem->method == 'ftpext') && defined('FTP_BASE')) + { + $ftpBase = FTP_BASE; + $ftpBase = trailingslashit($ftpBase); + $tmpdir = str_replace(ABSPATH, $ftpBase, $tmpdir); + } + + unzip_file($this->file, $tmpdir); + + return true; + } + + /** + * Extract backup using pclZip library + * + * @return bool + */ + public function extractZipPclBackup() + { + $zip = new PclZip($this->file); + if ($zip->extract(PCLZIP_OPT_PATH, ABSPATH, PCLZIP_OPT_REPLACE_NEWER) == 0) + { + return false; + } + if ($zip->error_code != PCLZIP_ERR_NO_ERROR) throw new Exception($zip->errorInfo(true)); + return true; + } + + /** + * Extract backup using zip on console + * + * @return bool + */ + public function extractZipConsoleBackup() + { + //todo implement + //system('zip'); + return false; + } + + /** + * Replace define statement to work with wp-config.php + * + * @param string $constant The constant name + * @param string $value The new value + * @param string $content The PHP file content + * @return string Replaced define statement with new value + */ + protected function replaceDefine($constant, $value, $content) + { + return preg_replace('/(define *\( *[\'"]' . $constant . '[\'"] *, *[\'"])(.*?)([\'"] *\))/is', '${1}' . $value . '${3}', $content); + } + + /** + * Replace variable value to work with wp-config.php + * + * @param string $varname The variable name + * @param string $value The new value + * @param string $content The PHP file content + * @return string Replaced variable value with new value + */ + protected function replaceVar($varname, $value, $content) + { + return preg_replace('/(\$' . $varname . ' *= *[\'"])(.*?)([\'"] *;)/is', '${1}' . $value . '${3}', $content); + } + + function recurse_chmod($mypath, $arg) + { + $d = opendir($mypath); + while (($file = readdir($d)) !== false) + { + if ($file != "." && $file != "..") + { + $typepath = $mypath . "/" . $file; + if (filetype($typepath) == 'dir') + { + recurse_chmod($typepath, $arg); + } + chmod($typepath, $arg); + } + } + } + + + /** + * The main loop triggered in step 5. Up here to keep it out of the way of the + * HTML. This walks every table in the db that was selected in step 3 and then + * walks every row and column replacing all occurences of a string with another. + * We split large tables into 50,000 row blocks when dealing with them to save + * on memmory consumption. + * + * @param mysql $connection The db connection object + * @param string $search What we want to replace + * @param string $replace What we want to replace it with. + * @param array $tables The tables we want to look at. + * + * @return array Collection of information gathered during the run. + */ + function icit_srdb_replacer( $connection, $search = '', $replace = '', $tables = array( ) ) { + global $guid, $exclude_cols; + + $report = array( 'tables' => 0, + 'rows' => 0, + 'change' => 0, + 'updates' => 0, + 'start' => microtime( ), + 'end' => microtime( ), + 'errors' => array( ), + ); + + if ( is_array( $tables ) && ! empty( $tables ) ) { + foreach( $tables as $table ) { + $report[ 'tables' ]++; + + $columns = array( ); + + // Get a list of columns in this table + $fields = MainWPChildDB::_query( 'DESCRIBE ' . $table, $connection ); + while( $column = MainWPChildDB::fetch_array( $fields ) ) + $columns[ $column[ 'Field' ] ] = $column[ 'Key' ] == 'PRI' ? true : false; + + // Count the number of rows we have in the table if large we'll split into blocks, This is a mod from Simon Wheatley + $row_count = MainWPChildDB::_query( 'SELECT COUNT(*) FROM ' . $table, $connection ); + $rows_result = MainWPChildDB::fetch_array( $row_count ); + $row_count = $rows_result[ 0 ]; + if ( $row_count == 0 ) + continue; + + $page_size = 50000; + $pages = ceil( $row_count / $page_size ); + + for( $page = 0; $page < $pages; $page++ ) { + + $current_row = 0; + $start = $page * $page_size; + $end = $start + $page_size; + // Grab the content of the table + $data = MainWPChildDB::_query( sprintf( 'SELECT * FROM %s LIMIT %d, %d', $table, $start, $end ), $connection ); + + if ( ! $data ) + $report[ 'errors' ][] = MainWPChildDB::error( ); + + while ( $row = MainWPChildDB::fetch_array( $data ) ) { + + $report[ 'rows' ]++; // Increment the row counter + $current_row++; + + $update_sql = array( ); + $where_sql = array( ); + $upd = false; + + foreach( $columns as $column => $primary_key ) { + if ( $guid == 1 && in_array( $column, $exclude_cols ) ) + continue; + + $edited_data = $data_to_fix = $row[ $column ]; + + // Run a search replace on the data that'll respect the serialisation. + $edited_data = $this->recursive_unserialize_replace( $search, $replace, $data_to_fix ); + + // Something was changed + if ( $edited_data != $data_to_fix ) { + $report[ 'change' ]++; + $update_sql[] = $column . ' = "' . MainWPChildDB::real_escape_string( $edited_data ) . '"'; + $upd = true; + } + + if ( $primary_key ) + $where_sql[] = $column . ' = "' . MainWPChildDB::real_escape_string( $data_to_fix ) . '"'; + } + + if ( $upd && ! empty( $where_sql ) ) { + $sql = 'UPDATE ' . $table . ' SET ' . implode( ', ', $update_sql ) . ' WHERE ' . implode( ' AND ', array_filter( $where_sql ) ); + $result = MainWPChildDB::_query( $sql, $connection ); + if ( ! $result ) + $report[ 'errors' ][] = MainWPChildDB::error( ); + else + $report[ 'updates' ]++; + + } elseif ( $upd ) { + $report[ 'errors' ][] = sprintf( '"%s" has no primary key, manual change needed on row %s.', $table, $current_row ); + } + + } + } + } + + } + $report[ 'end' ] = microtime( ); + + return $report; + } + + /** + * Take a serialised array and unserialise it replacing elements as needed and + * unserialising any subordinate arrays and performing the replace on those too. + * + * @param string $from String we're looking to replace. + * @param string $to What we want it to be replaced with + * @param array $data Used to pass any subordinate arrays back to in. + * @param bool $serialised Does the array passed via $data need serialising. + * + * @return array The original array with all elements replaced as needed. + */ + function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) { + + // some unseriliased data cannot be re-serialised eg. SimpleXMLElements + try { + + if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { + $data = $this->recursive_unserialize_replace( $from, $to, $unserialized, true ); + } + + elseif ( is_array( $data ) ) { + $_tmp = array( ); + foreach ( $data as $key => $value ) { + $_tmp[ $key ] = $this->recursive_unserialize_replace( $from, $to, $value, false ); + } + + $data = $_tmp; + unset( $_tmp ); + } + + else { + if ( is_string( $data ) ) + $data = str_replace( $from, $to, $data ); + } + + if ( $serialised ) + return serialize( $data ); + + } catch( Exception $error ) { + + } + + return $data; + } +} \ No newline at end of file diff --git a/class/MainWPHeatmapTracker.class.php b/class/MainWPHeatmapTracker.class.php new file mode 100644 index 00000000..d516cdc5 --- /dev/null +++ b/class/MainWPHeatmapTracker.class.php @@ -0,0 +1,399 @@ +server = get_option('mainwp_child_server'); + add_action('template_redirect', array($this, 'trackerJs')); + add_action('wp_ajax_heatmapSaveClick', array($this, 'saveClickCallback')); + add_action('wp_ajax_nopriv_heatmapSaveClick', array($this, 'saveClickCallback')); + } + + /** + * Get Instance + */ + public static function getInstance() + { + if ( self::$instance instanceof HeatmapTracker ) + return self::$instance; + self::$instance = new HeatmapTracker(true); + return self::$instance; + } + + /** + * Parse which page we are on using URL + */ + public function getPageObject( $pageUrl ) + { + global $wp_rewrite; + // If post type, we are using url_to_postid function + $postId = url_to_postid($pageUrl); + if ( $postId ) + { + $postType = get_post_type_object(get_post($postId)->post_type); + return array( + 'value' => $postId, + 'title' => get_the_title($postId), + 'type' => get_post($postId)->post_type, + 'label' => ( is_array($postType->labels) ? $postType->labels['name'] : $postType->labels->name ) + ); + } + $path = str_replace(get_site_url(), '', $pageUrl); + $path = trim($path, '/'); + // If path is empty, then it is front page + if ( empty($path) ) + return array( + 'value' => get_option('page_on_front') ? get_option('page_on_front') : '', + 'title' => '', + 'type' => 'front_page', + 'label' => __('Home Page') + ); + // Otherwise, we will try to match through rewrite or by query + $rewrite = $wp_rewrite->wp_rewrite_rules(); + if ( is_array($rewrite) && count($rewrite) > 0 ) + { + foreach ( $rewrite as $match => $query ) + { + if ( preg_match("#^$match#", $path, $matches) || preg_match("#^$match#", urldecode($path), $matches) ) + { + $query = preg_replace("!^.*\?!", '', $query); + $query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); + parse_str($query, $query_vars); + break; + } + } + } + else + { + $query = preg_replace("!^.*\?!", '', $path); + parse_str($query, $query_vars); + } + // Workaround for fail pagename rewrite match + if ( isset($query_vars['pagename']) && strpos($query_vars['pagename'], '?') !== false ) + { + $query = preg_replace("!^.*\?!", '', $query_vars['pagename']); + parse_str($query, $query_vars); + } + $querypost = new WP_Query($query_vars); + if ( $querypost->is_date() ) + { + if ( $querypost->query_vars['m'] ) + $date = $querypost->query_vars['m']; + else if ( $querypost->is_day() ) + $date = $querypost->query_vars['year'].zeroise($querypost->query_vars['monthnum'], 2).zeroise($querypost->query_vars['day'], 2); + else if ( $querypost->is_month() ) + $date = $querypost->query_vars['year'].zeroise($querypost->query_vars['monthnum'], 2); + else if ( $querypost->is_year() ) + $date = $querypost->query_vars['year']; + return array( + 'value' => $date, + 'title' => '', + 'type' => 'archive', + 'label' => __("Archive") + ); + } + else if ( $querypost->is_category() || $querypost->is_tag() || $querypost->is_tax() ) + { + $tax_query = $querypost->tax_query->queries; + $taxonomy = get_taxonomy($tax_query[0]['taxonomy']); + if ( $tax_query[0]['field'] == 'term_id' ) + $term_id = $tax_query[0]['terms'][0]; + else if ( $tax_query[0]['field'] == 'slug' ) + $term_id = get_term_by('slug', $tax_query[0]['terms'][0], $taxonomy->name)->term_id; + return array( + 'value' => $term_id, + 'title' => get_term($term_id, $taxonomy->name)->name, + 'type' => $taxonomy->name, + 'label' => ( is_array($taxonomy->labels->name) ? $taxonomy->labels['name'] : $taxonomy->labels->name ) + ); + } + else if ( $querypost->is_search() ) + { + return array( + 'value' => $querypost->query_vars['s'], + 'title' => '', + 'type' => 'search', + 'label' => __("Search") + ); + } + else if ( $querypost->is_home() ) + { + return array( + 'value' => '', + 'title' => '', + 'type' => 'home', + 'label' => __("Blog Home Page") + ); + } + } + + /** + * Save click callback for AJAX processing + */ + public function saveClickCallback() + { + if ( ! wp_verify_nonce($_POST['nonce'], 'heatmapSaveClick') ) + return false; + $data = isset($_POST['data']) && is_array($_POST['data']) ? $_POST['data'] : array(); + $storeData = get_option('mainwp_child_click_data'); + if ( ! is_array($storeData) ) + $storeData = array(); + foreach ( $data as $d ) + { + $coord = isset($d['coord']) && preg_match('/^\d+,\d+$/', $d['coord']) ? explode(',', $d['coord']) : null; + $type = isset($d['type']) && preg_match('/^(left|right|middle)$/', $d['type']) ? $d['type'] : 'left'; + $viewport = isset($d['viewport']) && preg_match('/^\d+,\d+$/', $d['viewport']) ? explode(',', $d['viewport']) : null; + $element = isset($d['element']) && preg_match('/^[A-Za-z0-9#:().>_-]+$/is', $d['element']) ? $d['element'] : null; + $attr = array(); + if ( isset($d['url']) && $d['url'] ) + $attr['url'] = esc_url_raw($d['url']); + if ( isset($d['title']) && $d['title'] ) + $attr['title'] = sanitize_text_field($d['title']); + if ( isset($d['alt']) && $d['alt'] ) + $attr['alt'] = sanitize_text_field($d['alt']); + if ( isset($d['text']) && $d['text'] ) + $attr['text'] = sanitize_text_field($d['text']); + $useragent = $_SERVER['HTTP_USER_AGENT']; + $object = $this->getPageObject($_SERVER['HTTP_REFERER']); + if ( ! is_null($coord) && ! is_null($viewport) && ! is_null($element) ) + { + $storeData[] = array( + 'url' => $_SERVER['HTTP_REFERER'], + 'object' => $object, + 'coord' => $coord, + 'viewport' => $viewport, + 'type' => $type, + 'element' => $element, + 'attr' => $attr, + 'useragent' => $useragent, + 'date' => current_time('mysql') + ); + } + } + update_option('mainwp_child_click_data', $storeData); + // Customize when we need to send the data + $this->sendClick(); + exit; + } + + public function sendClick() + { + $url = $this->server.'admin-ajax.php'; + $clickData = get_option('mainwp_child_click_data'); + $key = get_option('mainwp_child_pubkey'); + if ( ! is_array($clickData) ) + return false; + $timestamp = time(); + $signature = $this->createSignature($key, $timestamp, $clickData); + $request = wp_remote_post($url, array( + 'headers' => array( + 'Referer' => site_url() + ), + 'body' => array( + 'timestamp' => $timestamp, + 'signature' => $signature, + 'data' => base64_encode(serialize($clickData)), + 'action' => 'heatmapSendClick' + ) + )); + if ( is_array($request) && intval($request['body']) > 0 ) + delete_option('mainwp_child_click_data'); + } + + public function checkSignature( $signature, $timestamp, $data ) + { + $key = get_option('mainwp_child_pubkey'); + if ( ! $key ) + return false; + $createSign = $this->createSignature($key, $timestamp, $data); + return ( $signature == $createSign ); + } + + public function createSignature( $key, $timestamp, $data ) + { + $datamd5 = md5($timestamp.base64_encode(serialize($data))); + $signature = md5($key.$datamd5); + return $signature; + } + + /** + * Whether the heatmap is requested to display or not + */ + public function displayHeatmap() + { + return ( isset($_REQUEST['heatmap']) && $_REQUEST['heatmap'] == '1' ); + /*return ( ( isset($_REQUEST['heatmap']) && $_REQUEST['heatmap'] == '1' ) && + ( isset($_REQUEST['signature']) && isset($_REQUEST['timestamp']) && isset($_REQUEST['data']) && + $this->checkSignature($_REQUEST['signature'], $_REQUEST['timestamp'], $_REQUEST['data']) ) + );*/ + } + + /** + * Add tracker Javascript + */ + public function trackerJs() + { + if ( ! is_admin() ) + { + wp_enqueue_script('jquery'); + wp_enqueue_script('heatmapTracker', plugins_url('/js/tracker.js', dirname(__FILE__))); + if ( $this->displayHeatmap() ) + { + wp_enqueue_script('heatmapJs', plugins_url('/js/heatmap.js', dirname(__FILE__))); + wp_enqueue_script('heatmapInit', plugins_url('/js/heatmapinit.js', dirname(__FILE__))); + } + add_action('wp_head', array($this, 'trackerJsInline'), 1); + } + } + + /** + * Add necessary inline tracker Javascript + */ + public function trackerJsInline() + { + echo ''; + } + + /** + * Generate heatmap, print click data variable (wrap it on ) + * + * Available args: + * string $start Start date (d/m/Y) + * string $end End date (d/m/Y) + * string $browser Filter to only click by specified browser, see getBrowser method for list of supported browser name + * string $browserVersion The specific browser version to target at, could use some wildcard (for example: 7.*) + * string $platform Filter to only click by specified platform, see getBrowser method for list of supported platform name + * int $width Filter to width + * + * @param string $object_type Object type + * @param int|string $object_value Object value + * @param array $args Additional arguments + * + */ + public function generateHeatmap( $object_type, $object_value, $args ) + { + global $wpdb; + $defaults = array( + 'start' => '', + 'end' => '', + 'browser' => 'all', + 'browserVersion' => 'all', + 'platform' => 'all', + 'width' => 0 + ); + $args = wp_parse_args($args, $defaults); + extract($args); + + $data = array(); + $data['object_type'] = $object_type; + $data['object_value'] = $object_value; + $data['start_date'] = $start; + $data['end_date'] = $end; + $data['browser'] = $browser; + $data['platform'] = $platform; + $data['width'] = $width; + + $url = $this->server.'admin-ajax.php'; + $key = get_option('mainwp_child_pubkey'); + $timestamp = time(); + $signature = $this->createSignature($key, $timestamp, $data); + $request = wp_remote_post($url, array( + 'headers' => array( + 'Referer' => site_url() + ), + 'body' => array( + 'timestamp' => $timestamp, + 'signature' => $signature, + 'data' => base64_encode(serialize($data)), + 'action' => 'heatmapGetClickData' + ), + 'timeout' => 60 + )); + + if ( is_array($request) ) + { + $clicks = ( ! empty($request['body']) ) ? json_decode($request['body']) : array(); + $clickData = array(); + foreach ( $clicks as $click ) + { + $clickData[] = array( + 'x' => $click->x, + 'y' => $click->y, + 'w' => $click->w, + 'h' => $click->h + ); + } + ?> + var heatmapClick = ; + var heatmapError = 0; + + var heatmapError = 1; + diff --git a/class/MainWPHelper.class.php b/class/MainWPHelper.class.php new file mode 100644 index 00000000..0780571e --- /dev/null +++ b/class/MainWPHelper.class.php @@ -0,0 +1,536 @@ +' . base64_encode(serialize($val)) . ''); + } + + static function error($error) + { + $information['error'] = $error; + MainWPHelper::write($information); + } + + static function uploadImage($img_url) + { + include_once(ABSPATH . 'wp-admin/includes/file.php'); //Contains download_url + //Download $img_url + $temporary_file = download_url($img_url); + + if (is_wp_error($temporary_file)) + { + throw new Exception('Error: ' . $temporary_file->get_error_message()); + } + else + { + $upload_dir = wp_upload_dir(); + $local_img_path = $upload_dir['path'] . DIRECTORY_SEPARATOR . basename($img_url); //Local name + $local_img_url = $upload_dir['url'] . '/' . basename($img_url); + $moved = @rename($temporary_file, $local_img_path); + if ($moved) + { + $wp_filetype = wp_check_filetype(basename($img_url), null); //Get the filetype to set the mimetype + $attachment = array( + 'post_mime_type' => $wp_filetype['type'], + 'post_title' => preg_replace('/\.[^.]+$/', '', basename($img_url)), + 'post_content' => '', + 'post_status' => 'inherit' + ); + $attach_id = wp_insert_attachment($attachment, $local_img_path); //Insert the image in the database + require_once(ABSPATH . 'wp-admin/includes/image.php'); + $attach_data = wp_generate_attachment_metadata($attach_id, $local_img_path); + wp_update_attachment_metadata($attach_id, $attach_data); //Update generated metadata + + return array('id' => $attach_id, 'url' => $local_img_url); + } + } + if (file_exists($temporary_file)) + { + unlink($temporary_file); + } + return null; + } + + static function createPost($new_post, $post_custom, $post_category, $post_featured_image, $upload_dir, $post_tags) + { + global $current_user; + + //Set up a new post (adding addition information) + $usr = get_user_by('login', $_POST['user']); + //$new_post['post_author'] = $current_user->ID; + $new_post['post_author'] = $usr->ID; // to fix missing post author + $ezine_post = !empty($post_custom['_ezine_post_article_source']) ? true : false; + $terms = $new_post['_ezin_post_category']; + unset($new_post['_ezin_post_category']); + + $wp_error = null; + + //Search for all the images added to the new post + //some images have a href tag to click to navigate to the image.. we need to replace this too + if (!$ezine_post) { + $foundMatches = preg_match_all('/(]+href=\"(.*?)\"[^>]*>)?(\/]*src=\"((.*?)(png|gif|jpg|jpeg))\")/ix', $new_post['post_content'], $matches, PREG_SET_ORDER); + } + else + { + if (isset($new_post['post_date_gmt']) && !empty($new_post['post_date_gmt'])) { + $post_date_timestamp = strtotime($new_post['post_date_gmt']) + get_option('gmt_offset') * 60 * 60; + $new_post['post_date'] = date('Y-m-d H:i:s', $post_date_timestamp); + $new_post['post_status'] = ($post_date_timestamp <= current_time('timestamp')) ? 'publish' : 'future'; + } else { + $new_post['post_status'] = 'publish'; + } + $foundMatches = 0; + } + + if ($foundMatches > 0) + { + //We found images, now to download them so we can start balbal + foreach ($matches as $match) + { + $hrefLink = $match[2]; + $imgUrl = $match[4]; + + if (!isset($upload_dir['baseurl']) || (strripos($imgUrl, $upload_dir['baseurl']) != 0)) continue; + + if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $imgUrl, $imgMatches)) { + $search = $imgMatches[0]; + $replace = '.'.$match[6]; + $originalImgUrl = str_replace($search, $replace, $imgUrl); + } else { + $originalImgUrl = $imgUrl; + } + + $downloadfile = MainWPHelper::uploadImage($originalImgUrl); + $localUrl = $downloadfile['url']; + $linkToReplaceWith = dirname($localUrl); + if ($hrefLink != '') + { + $lnkToReplace = dirname($hrefLink); + if ($lnkToReplace != 'http:' && $lnkToReplace != 'https:') $new_post['post_content'] = str_replace($lnkToReplace, $linkToReplaceWith, $new_post['post_content']); + } + + $lnkToReplace = dirname($imgUrl); + if ($lnkToReplace != 'http:' && $lnkToReplace != 'https:') $new_post['post_content'] = str_replace($lnkToReplace, $linkToReplaceWith, $new_post['post_content']); + } + } + + if (isset($post_tags) && $post_tags != '') $new_post['tags_input'] = $post_tags; + + //Save the post to the wp + remove_filter('content_save_pre', 'wp_filter_post_kses'); // to fix brake scripts or html + $new_post_id = wp_insert_post($new_post, $wp_error); + + //Show errors if something went wrong + if (is_wp_error($wp_error)) + { + return $wp_error->get_error_message(); + } + if ($new_post_id == 0) + { + return 'Undefined error'; + } + + if (!empty($terms)) { + wp_set_object_terms($new_post_id, array_map( intval, $terms), 'category'); + } + + $permalink = get_permalink( $new_post_id ); + + //Set custom fields + $not_allowed = array('_slug', '_tags', '_edit_lock', '_selected_sites', '_selected_groups', '_selected_by', '_categories', '_edit_last', '_sticky'); + $not_allowed[] = '_mainwp_boilerplate_sites_posts'; + $not_allowed[] = '_ezine_post_keyword'; + $not_allowed[] = '_ezine_post_display_sig'; + $not_allowed[] = '_ezine_post_remove_link'; + $not_allowed[] = '_ezine_post_grab_image'; + $not_allowed[] = '_ezine_post_grab_image_placement'; + $not_allowed[] = '_ezine_post_template_id'; + + foreach ($post_custom as $meta_key => $meta_values) + { + if (!in_array($meta_key, $not_allowed)) + { + foreach ($meta_values as $meta_value) + { + add_post_meta($new_post_id, $meta_key, $meta_value); + } + } + else if ($meta_key == '_sticky') + { + foreach ($meta_values as $meta_value) + { + if (base64_decode($meta_value) == 'sticky') + { + stick_post($new_post_id); + } + } + } + } + + //If categories exist, create them (second parameter of wp_create_categories adds the categories to the post) + include_once(ABSPATH . 'wp-admin/includes/taxonomy.php'); //Contains wp_create_categories + if (isset($post_category) && $post_category != '') + { + $categories = explode(',', $post_category); + if (count($categories) > 0) + { + $post_category = wp_create_categories($categories, $new_post_id); + } + } + + //If featured image exists - set it + if ($post_featured_image != null) + { + try + { + $upload = MainWPHelper::uploadImage($post_featured_image); //Upload image to WP + + if ($upload != null) + { + update_post_meta($new_post_id, '_thumbnail_id', $upload['id']); //Add the thumbnail to the post! + } + } + catch (Exception $e) + { + + } + } + $ret['success'] = true; + $ret['link'] = $permalink; + $ret['added_id'] = $new_post_id; + return $ret; + } + + static function getMainWPDir($what = null, $dieOnError = true) + { + $upload_dir = wp_upload_dir(); + $dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'mainwp' . DIRECTORY_SEPARATOR; + self::checkDir($dir, $dieOnError); + if (!file_exists($dir . 'index.php')) + { + @touch($dir . 'index.php'); + } + $url = $upload_dir['baseurl'] . '/mainwp/'; + + if ($what == 'backup') + { + $dir .= 'backup' . DIRECTORY_SEPARATOR; + self::checkDir($dir, $dieOnError); + if (!file_exists($dir . 'index.php')) + { + @touch($dir . 'index.php'); + } + $url .= 'backup/'; + } + + return array($dir, $url); + } + + static function checkDir($dir, $dieOnError) + { + MainWPHelper::getWPFilesystem(); + global $wp_filesystem; + if (!file_exists($dir)) + { + if (empty($wp_filesystem)) + { + @mkdir($dir, 0777, true); + } + else + { + if (($wp_filesystem->method == 'ftpext') && defined('FTP_BASE')) + { + $ftpBase = FTP_BASE; + $ftpBase = trailingslashit($ftpBase); + $tmpdir = str_replace(ABSPATH, $ftpBase, $dir); + } + else + { + $tmpdir = $dir; + } + $wp_filesystem->mkdir($tmpdir, 0777); + } + + if (!file_exists($dir)) + { + $error = __('Unable to create directory ', 'mainwp-child') . str_replace(ABSPATH, '', $dir) . '.' . __(' Is its parent directory writable by the server?', 'mainwp-child'); + if ($dieOnError) + self::error($error); + else + throw new Exception($error); + } + } + } + + public static function validateMainWPDir() + { + $done = false; + $dir = MainWPHelper::getMainWPDir(); + $dir = $dir[0]; + if (MainWPHelper::getWPFilesystem()) + { + global $wp_filesystem; + try + { + MainWPHelper::checkDir($dir, false); + } + catch (Exception $e) + { + + } + if (!empty($wp_filesystem)) + { + if ($wp_filesystem->is_writable($dir)) $done = true; + } + } + + if (!$done) + { + if (!file_exists($dir)) @mkdirs($dir); + if (is_writable($dir)) $done = true; + } + + return $done; + } + + static function search($array, $key) + { + if (is_object($array)) $array = (array)$array; + if (is_array($array) || is_object($array)) + { + if (isset($array[$key])) return $array[$key]; + + foreach ($array as $subarray) + { + $result = self::search($subarray, $key); + if ($result != null) return $result; + } + } + + return null; + } + + /** + * @return WP_Filesystem_Base + */ + public static function getWPFilesystem() + { + global $wp_filesystem; + + if (empty($wp_filesystem)) + { + ob_start(); + if (file_exists(ABSPATH . '/wp-admin/includes/screen.php')) include_once(ABSPATH . '/wp-admin/includes/screen.php'); + if (file_exists(ABSPATH . '/wp-admin/includes/template.php')) include_once(ABSPATH . '/wp-admin/includes/template.php'); + $creds = request_filesystem_credentials('test'); + ob_end_clean(); + if (empty($creds)) + { + define('FS_METHOD', 'direct'); + } + $init = WP_Filesystem($creds); + } + else + { + $init = true; + } + + return $init; + } + + public static function startsWith($haystack, $needle) + { + return !strncmp($haystack, $needle, strlen($needle)); + } + + function endsWith($haystack, $needle) + { + $length = strlen($needle); + if ($length == 0) { + return true; + } + + return (substr($haystack, -$length) === $needle); + } + + public static function getNiceURL($pUrl, $showHttp = false) + { + $url = $pUrl; + + if (self::startsWith($url, 'http://')) + { + if (!$showHttp) $url = substr($url, 7); + } + else if (self::startsWith($pUrl, 'https://')) + { + if (!$showHttp) $url = substr($url, 8); + } + else + { + if ($showHttp) $url = 'http://'.$url; + } + + if (self::endsWith($url, '/')) + { + if (!$showHttp) $url = substr($url, 0, strlen($url) - 1); + } + else + { + $url = $url . '/'; + } + return $url; + } + + public static function endSession() + { + session_write_close(); + ob_end_flush(); + } + + static function fetchUrl($url, $postdata) + { + try + { + $tmpUrl = $url; + if (substr($tmpUrl, -1) != '/') { $tmpUrl .= '/'; } + + return self::_fetchUrl($tmpUrl . 'wp-admin/', $postdata); + } + catch (Exception $e) + { + try + { + return self::_fetchUrl($url, $postdata); + } + catch (Exception $ex) + { + throw $e; + } + } + } + + public static function _fetchUrl($url, $postdata) + { + $agent= 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($ch, CURLOPT_USERAGENT, $agent); + $data = curl_exec($ch); + $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $err = curl_error($ch); + curl_close($ch); + + if (($data === false) && ($http_status == 0)) { + throw new Exception('Http Error: ' . $err); + } + else if (preg_match('/(.*)<\/mainwp>/', $data, $results) > 0) { + $result = $results[1]; + $information = unserialize(base64_decode($result)); + return $information; + } + else if ($data == '') + { + throw new Exception(__('Something went wrong while contacting the child site. Please check if there is an error on the child site. This error could also be caused by trying to clone or restore a site to large for your server settings.','mainwp-child')); + } + else + { + throw new Exception(__('Child plugin is disabled or the security key is incorrect. Please resync with your main installation.','mainwp-child')); + } + } + + + public static function randString($length, $charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') + { + $str = ''; + $count = strlen($charset); + while ($length--) + { + $str .= $charset[mt_rand(0, $count - 1)]; + } + return $str; + } + + public static function return_bytes($val) { + $val = trim($val); + $last = strtolower($val[strlen($val)-1]); + switch($last) { + // The 'G' modifier is available since PHP 5.1.0 + case 'g': + $val *= 1024; + case 'm': + $val *= 1024; + case 'k': + $val *= 1024; + } + + return $val; + } + + public static function human_filesize($bytes, $decimals = 2) { + $size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB'); + $factor = floor((strlen($bytes) - 1) / 3); + return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[$factor]; + } + + public static function is_dir_empty($dir) + { + if (!is_readable($dir)) return null; + return (count(scandir($dir)) == 2); + } + + public static function delete_dir( $dir ) { + $nodes = glob($dir . '*'); + + if (is_array($nodes)) + { + foreach ($nodes as $node) + { + if (is_dir($node)) + { + self::delete_dir($node . DIRECTORY_SEPARATOR); + } + else + { + @unlink($node); + } + } + } + @rmdir($dir); + } + + public static function function_exists($func) { + if (!function_exists($func)) return false; + + if (extension_loaded('suhosin')) { + $suhosin = @ini_get("suhosin.executor.func.blacklist"); + if (empty($suhosin) == false) { + $suhosin = explode(',', $suhosin); + $suhosin = array_map('trim', $suhosin); + $suhosin = array_map('strtolower', $suhosin); + return (function_exists($func) == true && array_search($func, $suhosin) === false); + } + } + return true; + } + + public static function getTimestamp($timestamp) + { + $gmtOffset = get_option('gmt_offset'); + + return ($gmtOffset ? ($gmtOffset * HOUR_IN_SECONDS) + $timestamp : $timestamp); + } + + public static function formatTimestamp($timestamp) + { + return date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $timestamp); + } +} + +?> diff --git a/class/MainWPKeywordLinks.class.php b/class/MainWPKeywordLinks.class.php new file mode 100644 index 00000000..24cafbd2 --- /dev/null +++ b/class/MainWPKeywordLinks.class.php @@ -0,0 +1,775 @@ +server = get_option('mainwp_child_server'); + add_action('wp_ajax_keywordLinksSaveClick', array($this, 'saveClickCallback')); + add_action('wp_ajax_nopriv_keywordLinksSaveClick', array($this, 'saveClickCallback')); + add_action('template_redirect', array($this, 'keywordLinksJS')); + $this->config = get_option('mainwp_kwl_options', array()); + $this->keyword_links = get_option('mainwp_kwl_keyword_links', array()); + if (empty($this->keyword_links)) + $this->keyword_links = array(); + $this->siteurl = get_option('siteurl'); + add_action('permalink_structure_changed', array(&$this, 'permalinkChanged'), 10, 2); + } + + public function keywordLinksJS() + { + if (!is_admin() && get_option('mainwp_kwl_enable_statistic')) + { + wp_enqueue_script('jquery'); + wp_enqueue_script('keywordLinks', plugins_url('/js/keywordlinks.js', dirname(__FILE__))); + add_action('wp_head', array($this, 'head_loading'), 1); + } + } + + public function head_loading() + { + ?> + + update_htaccess(false, true); // force clear + } + } else { + $this->update_htaccess(true); // force update + } + } + + function mod_rewrite_rules($pRules) + { + $home_root = parse_url(home_url()); + if (isset($home_root['path'])) + $home_root = trailingslashit($home_root['path']); + else + $home_root = '/'; + + $rules = "\n"; + $rules .= "RewriteEngine On\n"; + $rules .= "RewriteBase $home_root\n"; + + //add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all) + foreach ($pRules as $match => $query) + { + // Apache 1.3 does not support the reluctant (non-greedy) modifier. + $match = str_replace('.+?', '.+', $match); + + $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; + } + + $rules .= "\n"; + + return $rules; + } + + function update_htaccess($force_update = false, $force_clear = false) + { + if ($force_clear) + $this->do_update_htaccess(true); + else if ($force_update) { + return $this->do_update_htaccess(); + } else { + if ('' == get_option( 'permalink_structure') && get_option('mainwp_keyword_links_htaccess_set') != 'yes') + $this->do_update_htaccess(); // need to update + else if ('' != get_option( 'permalink_structure') && get_option('mainwp_keyword_links_htaccess_set') == 'yes') + $this->do_update_htaccess(); // need to update + } + return true; + } + + public static function clear_htaccess() { + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + $home_path = ABSPATH; + $htaccess_file = $home_path . '.htaccess'; + if (function_exists('save_mod_rewrite_rules')) + { + $rules = explode("\n", ''); + insert_with_markers($htaccess_file, 'MainWP Keyword Links Extension', $rules); + } + update_option('mainwp_keyword_links_htaccess_set', ''); + } + + public function do_update_htaccess($force_clear = false) { + if ($force_clear) { + self::clear_htaccess(); + return true; + } else if ('' == get_option( 'permalink_structure')) { + include_once(ABSPATH . '/wp-admin/includes/misc.php'); + $redirection_folder = $this->get_option('redirection_folder', 'goto'); + if (empty($redirection_folder)) + $redirection_folder = "goto"; + + //Create rewrite ruler + $rules = $this->mod_rewrite_rules(array($redirection_folder.'/' => 'index.php')); + $home_path = ABSPATH; + $htaccess_file = $home_path . '.htaccess'; + if (function_exists('save_mod_rewrite_rules')) + { + $rules = explode("\n", $rules); + insert_with_markers($htaccess_file, 'MainWP Keyword Links Extension', $rules); + } + update_option('mainwp_keyword_links_htaccess_set', 'yes'); + return true; + } else { + self::clear_htaccess(); + return true; + } + return false; + } + + + + public function saveClickCallback() + { + if ( ! wp_verify_nonce($_POST['nonce'], 'keywordLinksSaveClick') ) + return false; + $link_id = intval($_POST['link_id']); + if ($link_id) { + $this->add_statistic($link_id, $_POST['ip'], $_POST['referer']); + } + exit; + } + + public function sendClick() + { + $url = $this->server.'admin-ajax.php'; + $clickData = get_option('mainwp_kwl_click_statistic_data'); + $key = get_option('mainwp_child_pubkey'); + if ( ! is_array($clickData) ) + return false; + $timestamp = time(); + $signature = $this->createSignature($key, $timestamp, $clickData); + $request = wp_remote_post($url, array( + 'headers' => array( + 'Referer' => site_url() + ), + 'body' => array( + 'timestamp' => $timestamp, + 'signature' => $signature, + 'data' => base64_encode(serialize($clickData)), + 'action' => 'keywordLinksSendClick' + ) + )); + if ( is_array($request) && intval($request['body']) > 0 ) + delete_option('mainwp_kwl_click_statistic_data'); + } + + public function createSignature( $key, $timestamp, $data ) + { + $datamd5 = md5($timestamp.base64_encode(serialize($data))); + $signature = md5($key.$datamd5); + return $signature; + } + + public function checkSignature( $signature, $timestamp, $data ) + { + $key = get_option('mainwp_child_pubkey'); + if ( ! $key ) + return false; + $createSign = $this->createSignature($key, $timestamp, $data); + return ( $signature == $createSign ); + } + + public function get_option($key, $default = '') { + if (isset($this->config[$key])) + return $this->config[$key]; + return $default; + } + + public function set_option($key, $value) { + $this->config[$key] = $value; + return update_option('mainwp_kwl_options', $this->config); + } + + public function get_link($link_id, $default = '') { + if (isset($this->keyword_links[$link_id])) + return $this->keyword_links[$link_id]; + return $default; + } + + public function set_link($link_id, $link) { + if (empty($link)) + unset($this->keyword_links[$link_id]); + else + $this->keyword_links[$link_id] = $link; + return update_option('mainwp_kwl_keyword_links', $this->keyword_links); + } + + + // This function is to generate links for keywords in post content + public function filter_content($content) { + global $post, $wpdb; + if ($this->get_option('mainwp_kwl_do_not_link_site_blocked', false)) + return $content; + + // get allow post typies, if it isn't belong that => avoid + $allow_post_type = (array) $this->get_option('enable_post_type'); + if (!in_array($post->post_type, $allow_post_type)) + return $content; + + + if ($post) { + // Check if this post was disabled with this function, come back + $disable = get_post_meta($post->ID, '_mainwp_kl_disable', true); + if ($disable == 1) + return $content; + + $paths_blocked = $this->get_option('mainwp_kwl_do_not_link_paths_blocked', array()); + if (is_array($paths_blocked)) { + $permalink = get_permalink($post->ID); + $url_paths = str_replace($this->siteurl,'', $permalink); + $url_paths = trim($url_paths, '/'); + + // check full path blocked + if (in_array($url_paths, $paths_blocked)) + return $content; + + $url_paths = explode('/', $url_paths); + foreach($url_paths as $path) { + // check partial paths blocked + if (!empty($path) && in_array($path, $paths_blocked)) { + return $content; + } + } + } + } + + // save specific link + if ($post) { + $specific_link = get_post_meta($post->ID, '_mainwp_kwl_specific_link', true); + $specific_link = unserialize($specific_link); + if (is_array($specific_link) && count($specific_link) > 0) { + $specific_link = current($specific_link); + $specific_link->post_id = $post->ID; + //update_post_meta($post->ID, '_mainwp_kwl_specific_link_save', array($specific_link->id => $specific_link)); + update_post_meta($post->ID, '_mainwp_kwl_specific_link_id', $specific_link->id); + if ($this->set_link($specific_link->id, $specific_link)) + delete_post_meta($post->ID, '_mainwp_kwl_specific_link'); // delete the source meta + } + } + + if ($post && $post->ID) + $links = $this->get_available_links($post->ID); + else + $links = $this->get_available_links(); + + // print_r($this->keyword_links); + // echo "======"; + // print_r($links); + + if (empty($links)) + return $content; + + $replace_max = intval($this->get_option('replace_max', -1)); + $replace_max_keyword = intval($this->get_option('replace_max_keyword', -1)); + // start create links for keywords (terms) in post content + $this->link_count_temp = $replace_max; + $not_allow_keywords = get_post_meta($post->ID, 'mainwp_kl_not_allowed_keywords_on_this_post', true); + $not_allow_keywords = unserialize($not_allow_keywords); + foreach ($links as $link) { + if (!$link) + continue; + + global $current_user; + + $this->link_temp = $link; + $this->link_count_each_temp = $replace_max_keyword; + //$keywords = explode(',', $link->keyword); + $keywords = $this->explode_multi($link->keyword); + usort($keywords, create_function('$a,$b', 'return strlen($a) $keyword, "link" => $link->destination_url), (array) $not_allow_keywords)) { + continue; + } + $keyword = preg_replace('/([$^\/?+.*\]\[)(}{])/is', '\\\\\1', $keyword); + + if (strpos($content, $keyword) !== false) { + //Replace keyword in H tag + if ($this->get_option('replace_keyword_in_h_tag')) { + //$content = preg_replace_callback('/(]*>.*?'.$keyword.'.*?<\/a>|<[^>]*'.$keyword.'[^>]*>|\{[^}]*'.$keyword.'[^}]*\}|\w*('.$keyword.')\w*)/is', array(&$this, 'keyword_mark'), $content); + $content = preg_replace_callback("/(]*>[^<]*?" . $keyword . "[^<]*?<\/a>|<[^>]*" . $keyword . "[^>]*>|\{[^\}]*" . $keyword . "[^\}]*\}|\w*(" . $keyword . ")\w*)/is", array(&$this, 'keyword_mark'), $content); + } else { + //$content = preg_replace_callback('/(]*>.*?'.$keyword.'.*?<\/h[123456]>|]*>.*?'.$keyword.'.*?<\/a>|<[^>]*'.$keyword.'[^>]*>|\{[^}]*'.$keyword.'[^}]*\}|\w*('.$keyword.')\w*)/is', array(&$this, 'keyword_mark'), $content); + $content = preg_replace_callback("/(]*>[^<]*?" . $keyword . "[^<]*?<\/h[123456]>|]*>[^<]*?" . $keyword . "[^<]*?<\/a>|<[^>]*" . $keyword . "[^>]*>|\{[^\}]*" . $keyword . "[^\}]*\}|\w*(" . $keyword . ")\w*)/is", array(&$this, 'keyword_mark'), $content); + } + } + } + } + $content = preg_replace_callback('/\{MAINWP_LINK +HREF="(.*?)" +TARGET="(.*?)" +REL="(.*?)" +LINK-ID="(.*?)" +CLASS="(.*?)" +TEXT="(.*?)" *\}/is', array(&$this, 'keyword_replace'), $content); + return $content; + } + + public function keyword_mark($matches) { + + if (preg_match('/^[<{].*?[>}]$/is', $matches[1])) + return $matches[1]; + + if ($this->link_count_temp === 0 || $this->link_count_each_temp === 0) + return $matches[1]; + + if ($matches[1] != $matches[2]) + return $matches[1]; + + if ($this->link_count_temp != -1) + $this->link_count_temp--; + + if ($this->link_count_temp != -1) + $this->link_count_each_temp--; + +// if (isset($this->link_temp->type) && $this->link_temp->type == 'post_type') { +//// $post = get_post($this->link_temp->id); +//// if ($post) { +//// $disable_linking = $this->get_option('disable_linking_automatically', array()); +//// if (in_array($post->post_name, $disable_linking[$post->post_type])) +//// return $matches[1]; // do not link to this post +//// } +// $link_target = get_post_meta($this->link_temp->id, '_mainwp_kl_link_newtab', true); +// $this->link_temp->link_target = ( $link_target != -1 && $link_target == 1 ? '_blank' : '' ); +// $link_rel = get_post_meta($this->link_temp->id, '_mainwp_kl_link_nofollow', true); +// $this->link_temp->link_rel = ( $link_rel != -1 && $link_rel == 1 ? 'nofollow' : '' ); +// $this->link_temp->link_class = get_post_meta($this->link_temp->id, '_mainwp_kl_link_class', true); +// } + if ($this->link_temp->link_target != '-1') { + $target = $this->link_temp->link_target; + } else + $target = $this->get_option('default_link_newtab') ? '_blank' : ''; + + + if ($this->link_temp->link_rel != '-1') + $rel = $this->link_temp->link_rel; + else + $rel = $this->get_option('default_link_nofollow') ? 'nofollow' : ''; + if ($this->link_temp->link_class != '') + $class = $this->link_temp->link_class; + else + $class = $this->get_option('default_link_class'); + $redirection_folder = $this->get_option('redirection_folder', 'goto'); + if (empty($redirection_folder)) + $redirection_folder = "goto"; + if (!empty($redirection_folder)) + $redirection_folder = "/" . $redirection_folder; + +// if (empty($redirection_folder)) +// $redirection_folder = 'goto'; + + $regular_link = false; + if (empty($this->link_temp->cloak_path)) { + $regular_link = true; + $class .= " kwl-regular-link"; + } + + return '{MAINWP_LINK HREF="' . ( $this->link_temp->cloak_path ? $this->siteurl . $redirection_folder . '/' . $this->link_temp->cloak_path : $this->link_temp->destination_url) . '" TARGET="' . $target . '" REL="' . $rel . '" LINK-ID="' . $this->link_temp->id . '" CLASS="' . $class . '" TEXT="' . $matches[1] . '"}'; + } + + public function keyword_replace( $matches ) + { + $a = ''; + return $a; + } + + public function get_available_links($post_id = null) { + global $post, $wpdb; + if ($post_id !== null) + $post = get_post($post_id); + $links = array(); + // $disable_add_links = $this->get_option('disable_add_links_automatically'); + // // if disabled add links automatically in this post, avoid + // if (in_array($post->post_name, (array) $disable_add_links[$post->post_type])) { + // return $links; + // } + + // Check if this post was disabled with this function, come back +// $disable = get_post_meta($post->ID, '_mainwp_kl_disable', true); +// if ($disable == 1) +// return $links; + // count replace max and max keyword allowed. + $replace_max = intval($this->get_option('replace_max')); + $replace_max_keyword = intval($this->get_option('replace_max_keyword')); + if ($replace_max === 0 || $replace_max_keyword === 0) + return $links; + // Post types enabled to create links + $post_types = (array) $this->get_option('enable_post_type_link'); + foreach ($post_types as $post_type) { + if ($post_type == $post->post_type) { + $categories = get_the_terms($post->ID, 'category'); + $cats = array(); + if (is_array($categories)) { + foreach ($categories as $category) + $cats[] = $category->term_id; + } + $links_post_type = (array) $this->get_post_keywords($post_type, $cats); + } else { + $links_post_type = (array) $this->get_post_keywords($post_type); + } + //print_r($links_post_type); + if (count($links_post_type) > 0) + $links = array_merge($links, $links_post_type); + } + + if ($post && $post->ID > 0) + $spec_link_id = get_post_meta($post->ID, '_mainwp_kwl_specific_link_id', true); + + foreach($this->keyword_links as $link) { + if ($link->type == 1 || $link->type == 3) + $links[] = $link; + else if ($spec_link_id && $spec_link_id == $link->id){ + $links[] = $link; + } + } + return $links; + } + + + public function get_post_keywords($post_type, $cats = null) { + global $wpdb, $post; + $join = ''; + $where = ''; + if (is_array($cats) && count($cats) > 0) { + $join = "JOIN $wpdb->term_relationships tr ON tr.object_id = p.ID"; + $where = " AND (tr.term_taxonomy_id = '" . implode("' OR tr.term_taxonomy_id = '", $cats) . "')"; + } + //$results = $wpdb->get_results(sprintf("SELECT * FROM $wpdb->posts as p LEFT JOIN $wpdb->postmeta as pm ON p.ID=pm.post_id $join WHERE p.post_status='publish' AND p.post_type='%s' AND pm.meta_key='_mainwp_kl_post_keyword' $where", $post_type)); + $results = $wpdb->get_results(sprintf("SELECT * FROM $wpdb->posts as p $join WHERE p.post_status='publish' AND p.post_type='%s' $where", $post_type)); + $links = array(); + if (!is_array($results)) + return array(); + $paths_blocked = $this->get_option('mainwp_kwl_do_not_link_paths_blocked', array()); + foreach ($results as $result) { + if ($result->ID == $post->ID) + continue; // do not link to myself + if (in_array($result->post_name, (array) $paths_blocked)) + continue; + $link = new stdClass; + // This is on-fly link so have not ID + //$link->id = $result->ID; + $link->name = $result->post_title; + //if ($result->post_type == 'page') + // $link->destination_url = get_permalink($result->ID); + //else + // $link->destination_url = $result->guid; + $link->destination_url = get_permalink($result->ID); + $link->cloak_path = ''; + $link->keyword = ( $this->get_option('post_match_title') == 1 ? $result->post_title . ',' : '' ) . $result->meta_value; + $link->link_target = ''; + $link->link_rel = ''; + $link->link_class = ''; + $link->type = 1; + $links[] = $link; + } + return $links; + } + + public function explode_multi($str) { + $delimiters = array(",", ";", "|"); + $str = str_replace($delimiters, ",", $str); + return explode(',', $str); + } + + public function redirect_cloak() { + global $wpdb; + + if ($this->get_option('mainwp_kwl_do_not_link_site_blocked', false)) + return; + + $request = $_SERVER['REQUEST_URI']; + // Check if the request is correct + if (!preg_match('|^[a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]+$|i', $request)) + return; + // Check to see if Wordpress is installed in sub folder + $siteurl = parse_url($this->siteurl); + $sitepath = ( isset($siteurl['path']) ) ? $siteurl['path'] : ''; + $filter_request = preg_replace('|^' . $sitepath . '/?|i', '', $request); + $filter_request = preg_replace('|/?$|i', '', $filter_request); + + $redirection_folder = $this->get_option('redirection_folder', 'goto'); + $redirection_folder = empty($redirection_folder) ? "goto" : $redirection_folder; + + //user use redirection_folder (or not set it - we use by default) + if ($redirection_folder != '') { + //if the request doesn't' containt the redirection folder we will return immediately + if (strpos($filter_request, $redirection_folder . '/') === false) { + return; + } + $filter_request = str_replace($redirection_folder . '/', '', $filter_request); + } + + if (empty($filter_request)) + return; + + if (substr($filter_request, -1) == "/") { + $filter_request = substr($filter_request, 0, -1); + } + + $link_id = 0; + foreach($this->keyword_links as $link) { + if ($link->cloak_path == $filter_request) { + $destination_url = $link->destination_url; + $link_id = $link->id; + break; + } + } + + if (!empty($destination_url)){ + if (get_option('mainwp_kwl_enable_statistic')) + $this->add_statistic($link_id, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_REFERER']); + wp_redirect($destination_url); + die(); + } + } + + public function add_statistic($link_id, $addr, $referer, $type = 'click') { + if ($link_id > 0) { + $storeData = get_option('mainwp_kwl_click_statistic_data'); + if ( ! is_array($storeData) ) + $storeData = array(); + $storeData[] = array( + 'timestamp' => time(), + 'link_id' => $link_id, + 'ip' => $addr, + 'referer' => $referer + ); + update_option('mainwp_kwl_click_statistic_data', $storeData); + // Customize when we need to send the data + $this->sendClick(); + } + } + +// public function get_statistic() { +// global $wpdb; +// $link_id = $_POST['link_id']; +// if ($link_id) { +// $stat_data = get_option('mainwp_kwl_statistic_data_' . $link_id, array()); +// if ($stat_data) { +// $return['stat_data'] = $stat_data; +// //$wpdb->query("UPDATE {$wpdb->prefix}options SET option_name = 'mainwp_kwl_statistic_data_done_" . $link_id . "' WHERE option_name = 'mainwp_kwl_statistic_data_" . $link_id . "'"); +// update_option('mainwp_kwl_statistic_data_' . $link_id, ''); +// } else +// $return['stat_data'] = 'EMPTY'; +// $return['status'] = 'SUCCESS'; +// } +// return $return; +// } + + public function action() { + $result = array(); + switch ($_POST['action']) { + case 'enable_stats': + $result = $this->enable_stats(); + break; + case 'refresh_data': + $result = $this->refresh_data(); + break; + case 'import_link': + case 'add_link': + $result = $this->edit_link(); + break; + case 'delete_link': + $result = $this->delete_link(); + break; + case 'clear_link': + $result = $this->clear_link(); + break; + case 'update_config': + $result = $this->update_config(); + break; + case 'donotlink_site_blocks': + $result = $this->donotlink_site_blocks(); + break; + case 'donotlink_path_blocks': + $result = $this->donotlink_path_blocks(); + break; + case 'donotlink_clear': + $result = $this->donotlink_clear(); + break; + } + MainWPHelper::write($result); + } + + public function enable_stats() + { + $result = array(); + $enable_stats = intval($_POST['enablestats']); + if (update_option('mainwp_kwl_enable_statistic', $enable_stats)) + $return['status'] = 'SUCCESS'; + return $return; + } + + public function refresh_data() + { + $result = array(); + if (isset($_POST['clear_all'])) { + $cleared1 = update_option('mainwp_kwl_keyword_links', ''); + $cleared2 = update_option('mainwp_kwl_options', ''); + if ($cleared1 || $cleared2) + $return['status'] = 'SUCCESS'; + } + return $return; + } + + public function delete_link() { + $result = array(); + if (!empty($_POST['link_id'])) { + $del_link = $this->get_link($_POST['link_id'], false); + if ($del_link) { + if ($del_link->type == 2 || $del_link->type == 3) + $deleted = delete_post_meta($del_link->post_id, '_mainwp_kwl_specific_link_id'); + if ($this->set_link($del_link->id, '')) + $return['status'] = 'SUCCESS'; + } + else + $return['status'] = 'SUCCESS'; + } + return $return; + } + + public function clear_link() { + $return = array(); + $cleared = false; + if (!empty($_POST['link_id'])) { + $clear_link = $this->get_link($_POST['link_id'], false); + if ($clear_link) { + if ($clear_link->type == 3) { + $clear_link->type = 2; + $cleared = $this->set_link($clear_link->id, $clear_link); + } else if ($clear_link->type == 1) { + $cleared = $this->set_link($clear_link->id, ''); // delete link + } + } + else + $cleared = true; + } + + if ($cleared) + $return['status'] = 'SUCCESS'; + return $return; + } + + + public function edit_link() { + $return = array(); + $link_id = $_POST['id']; + if (!empty($link_id)) { + $old = $this->get_link($link_id); + $link = new stdClass; + $link->id = intval($link_id); + $link->name = sanitize_text_field($_POST['name']); + $link->destination_url = sanitize_text_field($_POST['destination_url']); + $link->cloak_path = sanitize_text_field($_POST['cloak_path']); + $link->keyword = sanitize_text_field($_POST['keyword']); + $link->link_target = $_POST['link_target']; // number or text + $link->link_rel = $_POST['link_rel']; // number or text + $link->link_class = sanitize_text_field($_POST['link_class']); + $link->type = intval($_POST['type']); + + if ($link->type == 2 || $link->type == 3) { + if (intval($_POST['post_id'])) { + $link->post_id = intval($_POST['post_id']); + } else if ($old && $old->post_id) { + $link->post_id = $old->post_id; + } + if ($link->post_id) { + update_post_meta($link->post_id, '_mainwp_kwl_specific_link_id', $link_id); + } + } + + if ($this->set_link($link->id, $link)) + $return['status'] = 'SUCCESS'; + } + update_option('mainwpKeywordLinks', 1); // enable extension functions + return $return; + } + + public function update_config() { + $return = array(); + $this->config = array( + 'replace_max' => intval($_POST['replace_max']), + 'replace_max_keyword' => intval($_POST['replace_max_keyword']), + 'default_link_nofollow' => intval($_POST['default_link_nofollow']), + 'default_link_newtab' => intval($_POST['default_link_newtab']), + 'replace_keyword_in_h_tag' => intval($_POST['replace_keyword_in_h_tag']), + 'default_link_class' => sanitize_text_field($_POST['default_link_class']), + 'post_match_title' => intval($_POST['post_match_title']), + 'redirection_folder' => sanitize_text_field($_POST['redirection_folder']), + 'enable_post_type' => $_POST['enable_post_type'], + 'enable_post_type_link' => $_POST['enable_post_type_link'] + ); + update_option('mainwpKeywordLinks', 1); // enable extension functions + if (update_option('mainwp_kwl_options', $this->config)) { + $return['status'] = 'SUCCESS'; + } + + // force update + $this->update_htaccess(true); + return $return; + } + + public function donotlink_site_blocks() + { + $return = array(); + if ($this->set_option('mainwp_kwl_do_not_link_site_blocked', true)) + $return['status'] = 'SUCCESS'; + return $return; + } + + public function donotlink_path_blocks() + { + $return = array(); + if ($path = $_POST['path']) { + $paths = $this->get_option('mainwp_kwl_do_not_link_paths_blocked', array()); + $paths[] = $path; + if ($this->set_option('mainwp_kwl_do_not_link_paths_blocked', $paths)) + $return['status'] = 'SUCCESS'; + } + return $return; + } + + public function donotlink_clear() + { + $return = array(); + if ($this->set_option('mainwp_kwl_do_not_link_site_blocked', '')) + $return['status'] = 'SUCCESS'; + if ($this->set_option('mainwp_kwl_do_not_link_paths_blocked', '')) + $return['status'] = 'SUCCESS'; + return $return; + } + +} + diff --git a/class/MainWPSecurity.class.php b/class/MainWPSecurity.class.php new file mode 100644 index 00000000..2aa6ac47 --- /dev/null +++ b/class/MainWPSecurity.class.php @@ -0,0 +1,375 @@ +'); + fclose($h); + } + } + } + + //Removed wp-version + public static function remove_wp_version_ok() + { + return !(has_action('wp_head', 'wp_generator') || has_filter('wp_head', 'wp_generator')); + } + + public static function remove_wp_version() + { + if (get_option('mainwp_child_remove_wp_version') == 'T') + { + remove_action('wp_head', 'wp_generator'); + remove_filter('wp_head', 'wp_generator'); + } + } + + //Removed Really Simple Discovery meta tag + public static function remove_rsd_ok() + { + return (!has_action('wp_head', 'rsd_link')); + } + + public static function remove_rsd() + { + if (get_option('mainwp_child_remove_rsd') == 'T') + { + remove_action('wp_head', 'rsd_link'); + } + } + + //Removed Windows Live Writer meta tag + public static function remove_wlw_ok() + { + return (!has_action('wp_head', 'wlwmanifest_link')); + } + + public static function remove_wlw() + { + if (get_option('mainwp_child_remove_wlw') == 'T') + { + remove_action('wp_head', 'wlwmanifest_link'); + } + } + + //Removed core update information for non-admins +// public static function remove_core_update_ok() +// { +// return (get_option('mainwp_child_remove_core_updates') == 'T'); +// } + +// public static function remove_core_update() +// { +// if (get_option('mainwp_child_remove_core_updates') == 'T') +// { +// if (!current_user_can('update_plugins')) +// { +// add_action('admin_init', create_function('$a', "remove_action( 'admin_notices', 'maintenance_nag' );")); +// add_action('admin_init', create_function('$a', "remove_action( 'admin_notices', 'update_nag', 3 );")); +// add_action('admin_init', create_function('$a', "remove_action( 'admin_init', '_maybe_update_core' );")); +// add_action('init', create_function('$a', "remove_action( 'init', 'wp_version_check' );")); +// add_filter('pre_option_update_core', create_function('$a', "return null;")); +// remove_action('wp_version_check', 'wp_version_check'); +// remove_action('admin_init', '_maybe_update_core'); +// add_filter('pre_transient_update_core', create_function('$a', "return null;")); +// add_filter('pre_site_transient_update_core', create_function('$a', "return null;")); +// } +// } +// } + + //Removed plugin-update information for non-admins +// public static function remove_plugin_update_ok() +// { +// return (get_option('mainwp_child_remove_plugin_updates') == 'T'); +// } + +// public static function remove_plugin_update() +// { +// if (get_option('mainwp_child_remove_plugin_updates') == 'T') +// { +// if (!current_user_can('update_plugins')) +// { +// add_action('admin_init', create_function('$a', "remove_action( 'admin_init', 'wp_plugin_update_rows' );"), 2); +// add_action('admin_init', create_function('$a', "remove_action( 'admin_init', '_maybe_update_plugins' );"), 2); +// add_action('admin_menu', create_function('$a', "remove_action( 'load-plugins.php', 'wp_update_plugins' );")); +// add_action('admin_init', create_function('$a', "remove_action( 'admin_init', 'wp_update_plugins' );"), 2); +// add_action('init', create_function('$a', "remove_action( 'init', 'wp_update_plugins' );"), 2); +// add_filter('pre_option_update_plugins', create_function('$a', "return null;")); +// remove_action('load-plugins.php', 'wp_update_plugins'); +// remove_action('load-update.php', 'wp_update_plugins'); +// remove_action('admin_init', '_maybe_update_plugins'); +// remove_action('wp_update_plugins', 'wp_update_plugins'); +// remove_action('load-update-core.php', 'wp_update_plugins'); +// add_filter('pre_transient_update_plugins', create_function('$a', "return null;")); +// } +// } +// } + + //Removed theme-update information for non-admins +// public static function remove_theme_update_ok() +// { +// return (get_option('mainwp_child_remove_theme_updates') == 'T'); +// } + +// public static function remove_theme_update() +// { +// if (get_option('mainwp_child_remove_theme_updates') == 'T') +// { +// if (!current_user_can('edit_themes')) +// { +// remove_action('load-themes.php', 'wp_update_themes'); +// remove_action('load-update.php', 'wp_update_themes'); +// remove_action('admin_init', '_maybe_update_themes'); +// remove_action('wp_update_themes', 'wp_update_themes'); +// remove_action('load-update-core.php', 'wp_update_themes'); +// add_filter('pre_transient_update_themes', create_function('$a', "return null;")); +// } +// } +// } + + //File permissions not secure + private static $permission_checks = null; + + private static function init_permission_checks() + { + if (MainWPSecurity::$permission_checks == null) + { + MainWPSecurity::$permission_checks = array(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . '../' => '0755', + WP_CONTENT_DIR . DIRECTORY_SEPARATOR . '../wp-includes' => '0755', + WP_CONTENT_DIR . DIRECTORY_SEPARATOR . '../.htaccess' => '0644', + WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'index.php' => '0644', + WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'js/' => '0755', + WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'themes' => '0755', + WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'plugins' => '0755', + WP_CONTENT_DIR . DIRECTORY_SEPARATOR . '../wp-admin' => '0755', + WP_CONTENT_DIR => '0755'); + } + } + +// public static function fix_file_permissions_ok() +// { +// MainWPSecurity::init_permission_checks(); +// +// $perms_issues = 0; +// +// foreach (MainWPSecurity::$permission_checks as $dir => $needed_perms) +// { +// if (!file_exists($dir)) continue; +// +// $perms = substr(sprintf('%o', fileperms($dir)), -4); +// if ($perms != $needed_perms) +// { +// $perms_issues++; +// } +// } +// return ($perms_issues == 0); +// } + +// public static function fix_file_permissions() +// { +// MainWPSecurity::init_permission_checks(); +// $success = true; +// foreach (MainWPSecurity::$permission_checks as $dir => $needed_perms) +// { +// if (!file_exists($dir)) continue; +// $success == $success && chmod($dir, $needed_perms); +// } +// return $success; +// } + + //Database error reporting turned on/off + public static function remove_database_reporting_ok() + { + global $wpdb; + return ($wpdb->show_errors == false); + } + + public static function remove_database_reporting() + { + global $wpdb; + + $wpdb->hide_errors(); + $wpdb->suppress_errors(); + } + + //PHP error reporting turned on/off + public static function remove_php_reporting_ok() + { + return !(((ini_get('display_errors') != 0) && (ini_get('display_errors') != 'off')) || ((ini_get('display_startup_errors') != 0) && (ini_get('display_startup_errors') != 'off'))); + } + + public static function remove_php_reporting() + { + if (get_option('mainwp_child_remove_php_reporting') == 'T') + { + @error_reporting(0); + @ini_set('display_errors', 'off'); + @ini_set('display_startup_errors', 0); + } + } + + //Removed version information for scripts/stylesheets + public static function remove_scripts_version_ok() + { + return (get_option('mainwp_child_remove_scripts_version') == 'T'); + +// global $wp_scripts; +// if (!is_a($wp_scripts, 'WP_Scripts')) +// { +// return true; +// } +// foreach ($wp_scripts->registered as $handle => $script) +// { +// if ($wp_scripts->registered[$handle]->ver != null) +// { +// return false; +// } +// } +// return true; + } + + public static function remove_script_versions($src) + { + if (get_option('mainwp_child_remove_scripts_version') == 'T') + { + if (strpos($src, '?ver=')) + $src = remove_query_arg('ver', $src); + + return $src; + } + return $src; + } + + public static function remove_theme_versions($src) + { + if (get_option('mainwp_child_remove_styles_version') == 'T') + { + if (strpos($src, '?ver=')) + $src = remove_query_arg('ver', $src); + + return $src; + } + return $src; + } + + public static function remove_scripts_version() + { + if (get_option('mainwp_child_remove_scripts_version') == 'T') + { + global $wp_scripts; + if (!is_a($wp_scripts, 'WP_Scripts')) + return; + + foreach ($wp_scripts->registered as $handle => $script) + $wp_scripts->registered[$handle]->ver = null; + } + } + + public static function remove_readme() + { + if (get_option('mainwp_child_remove_readme') == 'T') + { + if (file_exists(ABSPATH . 'readme.html')) @unlink(ABSPATH . 'readme.html'); + } + } + + public static function remove_readme_ok() + { + return !file_exists(ABSPATH . 'readme.html'); + } + + public static function remove_styles_version_ok() + { + return (get_option('mainwp_child_remove_styles_version') == 'T'); + +// global $wp_styles; +// if (!is_a($wp_styles, 'WP_Styles')) +// { +// return true; +// } +// +// foreach ($wp_styles->registered as $handle => $style) +// { +// if ($wp_styles->registered[$handle]->ver != null) +// { +// return false; +// } +// } +// return true; + } + + public static function remove_styles_version() + { + if (get_option('mainwp_child_remove_styles_version') == 'T') + { + global $wp_styles; + if (!is_a($wp_styles, 'WP_Styles')) + return; + + foreach ($wp_styles->registered as $handle => $style) + $wp_styles->registered[$handle]->ver = null; + } + } + + //Admin user name is not admin + public static function admin_user_ok() + { + $user = get_user_by('login', 'admin'); + return !($user && ($user->wp_user_level == 10 || (isset($user->user_level) && $user->user_level == 10))); + } +} + +?> \ No newline at end of file diff --git a/class/index.html b/class/index.html new file mode 100644 index 00000000..e69de29b diff --git a/index.html b/index.html new file mode 100644 index 00000000..e69de29b diff --git a/js/heatmap.js b/js/heatmap.js new file mode 100644 index 00000000..b1502160 --- /dev/null +++ b/js/heatmap.js @@ -0,0 +1,362 @@ +/* + * heatmap.js 1.0 - JavaScript Heatmap Library + * + * Copyright (c) 2011, Patrick Wied (http://www.patrick-wied.at) + * Dual-licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and the Beerware (http://en.wikipedia.org/wiki/Beerware) license. + */ + +(function(w){ + // the heatmapFactory creates heatmap instances + var heatmapFactory = (function(){ + + // store object constructor + // a heatmap contains a store + // the store has to know about the heatmap in order to trigger heatmap updates when datapoints get added + function store(hmap){ + + var _ = { + // data is a two dimensional array + // a datapoint gets saved as data[point-x-value][point-y-value] + // the value at [point-x-value][point-y-value] is the occurrence of the datapoint + data: [], + // tight coupling of the heatmap object + heatmap: hmap + }; + // the max occurrence - the heatmaps radial gradient alpha transition is based on it + this.max = 0; + + this.get = function(key){ + return _[key]; + }, + this.set = function(key, value){ + _[key] = value; + }; + }; + + store.prototype = { + // function for adding datapoints to the store + // datapoints are usually defined by x and y but could also contain a third parameter which represents the occurrence + addDataPoint: function(x, y){ + if(x < 0 || y < 0) + return; + + var heatmap = this.get("heatmap"), + data = this.get("data"); + + if(!data[x]) data[x] = []; + if(!data[x][y]) data[x][y] = 1; + // if count parameter is set increment by count otherwise by 1 + data[x][y]+=(arguments.length<3)?1:arguments[2]; + + // do we have a new maximum? + if(this.max < data[x][y]){ + this.max = data[x][y]; + // max changed, we need to redraw all existing(lower) datapoints + heatmap.get("actx").clearRect(0,0,heatmap.get("width"),heatmap.get("height")); + for(var one in data) + for(var two in data[one]) + heatmap.drawAlpha(one, two, data[one][two]); + + // @TODO + // implement feature + // heatmap.drawLegend(); ? + return; + } + heatmap.drawAlpha(x, y, data[x][y]); + }, + setDataSet: function(obj){ + + this.max = obj.max; + var heatmap = this.get("heatmap"), + data = this.get("data"), + d = obj.data, + dlen = d.length; + // clear the heatmap before the data set gets drawn + heatmap.clear(); + + while(dlen--){ + var point = d[dlen]; + heatmap.drawAlpha(point.x, point.y, point.count); + if(!data[point.x]) data[point.x] = []; + if(!data[point.x][point.y]) data[point.x][point.y] = 1; + data[point.x][point.y]+=point.count; + } + // Add event after all done + // 10-22-2011 by Jeffri Hong + if ( typeof(obj.callback) == 'function' ) + obj.callback(); + }, + exportDataSet: function(){ + var data = this.get("data"); + var exportData = []; + for(var one in data){ + // jump over undefined indexes + if(one === undefined) + continue; + for(var two in data[one]){ + if(two === undefined) + continue; + // if both indexes are defined, push the values into the array + exportData.push({x: parseInt(one, 10), y: parseInt(two, 10), count: data[one][two]}); + } + } + + return exportData; + }, + generateRandomDataSet: function(points){ + var heatmap = this.get("heatmap"), + w = heatmap.get("width"), + h = heatmap.get("height"); + var randomset = {}, + max = Math.floor(Math.random()*1000+1); + randomset.max = max; + var data = []; + while(points--){ + data.push({x: Math.floor(Math.random()*w+1), y: Math.floor(Math.random()*h+1), count: Math.floor(Math.random()*max+1)}); + } + randomset.data = data; + this.setDataSet(randomset); + } + }; + + + // heatmap object constructor + function heatmap(config){ + // private variables + var _ = { + radiusIn : 20, + radiusOut : 40, + element : {}, + canvas : {}, + acanvas: {}, + ctx : {}, + actx : {}, + visible : true, + width : 0, + height : 0, + max : false, + gradient : false, + opacity: 180 + }; + // heatmap store containing the datapoints and information about the maximum + // accessible via instance.store + this.store = new store(this); + + this.get = function(key){ + return _[key]; + }, + this.set = function(key, value){ + _[key] = value; + }; + // configure the heatmap when an instance gets created + this.configure(config); + // and initialize it + this.init(); + }; + + // public functions + heatmap.prototype = { + configure: function(config){ + if(config.radius){ + var rout = config.radius, + rin = parseInt(rout/2); + } + this.set("radiusIn", rin || 15), + this.set("radiusOut", rout || 40), + this.set("element", (config.element instanceof Object)?config.element:document.getElementById(config.element)); + this.set("visible", config.visible); + this.set("max", config.max || false); + this.set("gradient", config.gradient || { 0.45: "rgb(0,0,255)", 0.55: "rgb(0,255,255)", 0.65: "rgb(0,255,0)", 0.95: "yellow", 1.0: "rgb(255,0,0)"}); // default is the common blue to red gradient + this.set("opacity", parseInt(255/(100/config.opacity), 10) || 180); + this.set("width", config.width || 0); + this.set("height", config.height || 0); + }, + init: function(){ + this.initColorPalette(); + var canvas = document.createElement("canvas"), + acanvas = document.createElement("canvas"), + element = this.get("element"); + this.set("canvas", canvas); + this.set("acanvas", acanvas); + canvas.width = acanvas.width = element.style.width.replace(/px/,"") || this.getWidth(element); + this.set("width", canvas.width); + canvas.height = acanvas.height = element.style.height.replace(/px/,"") || this.getHeight(element); + this.set("height", canvas.height); + canvas.style.position = acanvas.style.position = "absolute"; + canvas.style.top = acanvas.style.top = "0"; + canvas.style.left = acanvas.style.left = "0"; + canvas.style.zIndex = 1000000; + if(!this.get("visible")) + canvas.style.display = "none"; + + this.get("element").appendChild(canvas); + this.set("ctx", canvas.getContext("2d")); + this.set("actx", acanvas.getContext("2d")); + }, + initColorPalette: function(){ + + var canvas = document.createElement("canvas"); + canvas.width = "1"; + canvas.height = "256"; + var ctx = canvas.getContext("2d"); + var grad = ctx.createLinearGradient(0,0,1,256), + gradient = this.get("gradient"); + for(var x in gradient){ + grad.addColorStop(x, gradient[x]); + } + + ctx.fillStyle = grad; + ctx.fillRect(0,0,1,256); + + this.set("gradient", ctx.getImageData(0,0,1,256).data); + delete canvas; + delete grad; + delete ctx; + }, + getWidth: function(element){ + var width = element.offsetWidth; + if(element.style.paddingLeft) + width+=element.style.paddingLeft; + if(element.style.paddingRight) + width+=element.style.paddingRight; + + return width; + }, + getHeight: function(element){ + var height = element.offsetHeight; + if(element.style.paddingTop) + height+=element.style.paddingTop; + if(element.style.paddingBottom) + height+=element.style.paddingBottom; + + return height; + }, + colorize: function(x, y){ + // get the private variables + var width = this.get("width"), + radiusOut = this.get("radiusOut"), + height = this.get("height"), + actx = this.get("actx"), + ctx = this.get("ctx"); + + var x2 = radiusOut*2; + + if(x+x2>width) + x=width-x2; + if(x<0) + x=0; + if(y<0) + y=0; + if(y+x2>height) + y=height-x2; + // get the image data for the mouse movement area + var image = actx.getImageData(x,y,x2,x2), + // some performance tweaks + imageData = image.data, + length = imageData.length, + palette = this.get("gradient"), + opacity = this.get("opacity"); + // loop thru the area + for(var i=3; i < length; i+=4){ + + // [0] -> r, [1] -> g, [2] -> b, [3] -> alpha + var alpha = imageData[i], + offset = alpha*4; + + if(!offset) + continue; + + // we ve started with i=3 + // set the new r, g and b values + imageData[i-3]=palette[offset]; + imageData[i-2]=palette[offset+1]; + imageData[i-1]=palette[offset+2]; + // we want the heatmap to have a gradient from transparent to the colors + // as long as alpha is lower than the defined opacity (maximum), we'll use the alpha value + imageData[i] = (alpha < opacity)?alpha:opacity; + } + // the rgb data manipulation didn't affect the ImageData object(defined on the top) + // after the manipulation process we have to set the manipulated data to the ImageData object + image.data = imageData; + ctx.putImageData(image,x,y); + }, + drawAlpha: function(x, y, count){ + // storing the variables because they will be often used + var r1 = this.get("radiusIn"), + r2 = this.get("radiusOut"), + ctx = this.get("actx"), + max = this.get("max"), + // create a radial gradient with the defined parameters. we want to draw an alphamap + rgr = ctx.createRadialGradient(x,y,r1,x,y,r2), + xb = x-r2, yb = y-r2, mul = 2*r2; + // the center of the radial gradient has .1 alpha value + rgr.addColorStop(0, 'rgba(0,0,0,'+((count)?(count/this.store.max):'0.1')+')'); + // and it fades out to 0 + rgr.addColorStop(1, 'rgba(0,0,0,0)'); + // drawing the gradient + ctx.fillStyle = rgr; + ctx.fillRect(xb,yb,mul,mul); + // finally colorize the area + this.colorize(xb,yb); + + }, + toggleDisplay: function(){ + var visible = this.get("visible"), + canvas = this.get("canvas"); + + if(!visible) + canvas.style.display = "block"; + else + canvas.style.display = "none"; + + this.set("visible", !visible); + }, + // dataURL export + getImageData: function(){ + return this.get("canvas").toDataURL(); + }, + clear: function(){ + var w = this.get("width"), + h = this.get("height"); + this.store.set("data",[]); + // @TODO: reset stores max to 1 + //this.store.max = 1; + this.get("ctx").clearRect(0,0,w,h); + this.get("actx").clearRect(0,0,w,h); + } + }; + + return { + create: function(config){ + return new heatmap(config); + }, + util: { + mousePosition: function(ev){ + // this doesn't work right + // rather use + /* + // this = element to observe + var x = ev.pageX - this.offsetLeft; + var y = ev.pageY - this.offsetTop; + + */ + var x, y; + + if (ev.layerX) { // Firefox + x = ev.layerX; + y = ev.layerY; + } else if (ev.offsetX) { // Opera + x = ev.offsetX; + y = ev.offsetY; + } + if(typeof(x)=='undefined') + return; + + return [x,y]; + } + } + }; + })(); + w.h337 = w.heatmapFactory = heatmapFactory; +})(window); diff --git a/js/heatmapinit.js b/js/heatmapinit.js new file mode 100644 index 00000000..84cb9c18 --- /dev/null +++ b/js/heatmapinit.js @@ -0,0 +1,41 @@ +/** + * Initiate heatmap object + */ + + + +jQuery(window).load(function(){ + if ( heatmapError == 0 ) + { + jQuery('body').append( '
Loading...
' ); + setTimeout(generate_heatmap, 1000); + } + else + { + jQuery('body').append( '
An error occured.
' ); + } +}); + + +function generate_heatmap() +{ + var hmap = h337.create({"element":document.body, "radius":15, "visible":true}); + var width = jQuery(document).width(); + var data = []; + for ( i in heatmapClick ) + { + data.push({ + x: ( heatmapClick[i].w-width > 0 ? heatmapClick[i].x - ( Math.floor(heatmapClick[i].w-width)/2 ) : heatmapClick[i].x ), + y: heatmapClick[i].y, + count: 1 + }); + } + var max = Math.floor(data.length/10); + hmap.store.setDataSet({ + max: ( max > 5 ? Math.floor(data.length/max) : 5 ), + data: data, + callback: function(){ + jQuery('#hmap_loading').fadeOut(500); + } + }); +} diff --git a/js/index.html b/js/index.html new file mode 100644 index 00000000..e69de29b diff --git a/js/keywordlinks.js b/js/keywordlinks.js new file mode 100644 index 00000000..c5c3af6b --- /dev/null +++ b/js/keywordlinks.js @@ -0,0 +1,22 @@ +/** + * Mouse click tracking + */ +jQuery(document).ready(function($){ + $('.kwl-regular-link').click(function(){ + var link_id = $(this).attr('link-id'); + if (link_id) { + $.ajax({ + data : { + link_id: link_id, + ip: kwlIp, + referer: kwlReferer, + action: 'keywordLinksSaveClick', + nonce: kwlNonce + }, + type: 'POST', + url: kwlAjaxUrl + }); + } + }); +}); + diff --git a/js/tracker.js b/js/tracker.js new file mode 100644 index 00000000..8d01f6e5 --- /dev/null +++ b/js/tracker.js @@ -0,0 +1,62 @@ +/** + * Mouse click tracking + */ + +var trackerData = []; + +jQuery(document).ready(function($){ + + + $(document).click(function(e){ + var element = $(e.target).parents().map(getSelector).get().reverse().join(">"); + element += '>'+$(e.target).map(getSelector).get(); + var url = ( $(e.target).attr('href') ) ? $(e.target).attr('href') : $(e.target).attr('src'); + var title = $(e.target).attr('title'); + var alt = $(e.target).attr('alt'); + var text = ( $(e.target).text().length == $(e.target).html().length ) ? $(e.target).text().substring(0, 511) : ''; + trackerData.push({ + coord: e.pageX+','+e.pageY, + type: 'left', + viewport: $(window).width()+','+$(window).height(), + element: element, + url: url, + title: title, + alt: alt, + text: text + }); + }); + + $(window).unload(function(){ + sendTrackData(true); // Make sure to send track data before going off from page, set it synchronious + }); + + function getSelector() + { + var el_class = $(this).attr('class'); + var el_id = $(this).attr('id'); + var el_index = $(this).index(); + return this.tagName + ( el_id ? '#'+el_id : '' ) + + ( el_class ? '.'+el_class.match(/^\S+/) : '' ) + + ( el_index > 0 ? ':eq('+(el_index)+')' : '' ); + } + + function sendTrackData( sync ) + { + if ( trackerData.length < 1 ) + return; + $.ajax({ + data : { + data: trackerData, + action: 'heatmapSaveClick', + nonce: trackerNonce + }, + complete: function(){ + trackerData = []; + }, + async: ( sync ) ? false : true, + type: 'POST', + url: trackerAjaxUrl + }); + } + setInterval(function(){ sendTrackData(false); }, 10000); +}); diff --git a/languages/mainwp-child-bs_BA.mo b/languages/mainwp-child-bs_BA.mo new file mode 100644 index 0000000000000000000000000000000000000000..28ca35c551bdcb55fdedccbc6b3f8eee1ff8f8ca GIT binary patch literal 8334 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 RTy5>^F6qSET1l!?{{aL$!-N0; literal 0 HcmV?d00001 diff --git a/languages/mainwp-child-bs_BA.po b/languages/mainwp-child-bs_BA.po new file mode 100644 index 00000000..d3a36091 --- /dev/null +++ b/languages/mainwp-child-bs_BA.po @@ -0,0 +1,411 @@ +msgid "" +msgstr "" +"Project-Id-Version: MainWP Child v0.11\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2013-11-15 14:06:16+0000\n" +"Last-Translator: admin \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: CSL v1.x\n" +"X-Poedit-Language: Bosnian\n" +"X-Poedit-Country: BOSNIA AND HERZEGOWINA\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n" +"X-Poedit-Basepath: ../\n" +"X-Poedit-Bookmarks: \n" +"X-Poedit-SearchPath-0: .\n" +"X-Textdomain-Support: yes" + +#: class/MainWPChild.class.php:132 +#: class/MainWPChild.class.php:154 +#@ mainwp-child +msgid "MainWP Settings" +msgstr "MainWP Podešavanje" + +#: class/MainWPChild.class.php:158 +#@ mainwp-child +msgid "Connection Settings" +msgstr "Podešavanje konekcije" + +#: class/MainWPChild.class.php:166 +#@ mainwp-child +msgid "Require Unique Security ID" +msgstr "Zahtev za jedinstveni sigurnosni ključ" + +#: class/MainWPChild.class.php:169 +#@ mainwp-child +msgid "Your Unique Security ID is:" +msgstr "Vaš jedinstveni sigurnosni ključ je:" + +#: class/MainWPChild.class.php:173 +#@ mainwp-child +msgid "The Unique Security ID adds additional protection between the Child plugin and your
Main Dashboard. The Unique Security ID will need to match when being added to
the Main Dashboard. This is additional security and should not be needed in most situations." +msgstr "Jedinstveni sigurnosni ključ obezbeđuje dodatnu zaštitu između sajta i kontrolne table.
Jedinstveni sigurnosni ključ se mora poklapati prilikom dodavanja sajta u kontrolnu tablu.
Ova dodatna sigrnosna opcija, u većini slučajeva nije potrebna." + +#: class/MainWPChild.class.php:179 +#@ mainwp-child +msgid "Save Changes" +msgstr "Sačuvaj Promene" + +#: class/MainWPChild.class.php:424 +#@ mainwp-child +msgid "Authentication failed. Reinstall MainWP plugin please" +msgstr "Autentifikacija neuspešna. Molimo, reinstalirajte MainWP." + +#: class/MainWPChild.class.php:433 +#: class/MainWPChild.class.php:787 +#@ mainwp-child +msgid "No such user" +msgstr "Nepostojeći korisnik" + +#: class/MainWPChild.class.php:438 +#: class/MainWPChild.class.php:791 +#@ mainwp-child +msgid "User is not an administrator" +msgstr "Korisnik nema administratorske privilegije." + +#: class/MainWPChild.class.php:528 +#@ mainwp-child +msgid "Bad request." +msgstr "Loš zahtev." + +#: class/MainWPChild.class.php:699 +#: class/MainWPChild.class.php:704 +#: class/MainWPChild.class.php:736 +#: class/MainWPChild.class.php:741 +#: class/MainWPChild.class.php:746 +#@ mainwp-child +msgid "Bad request" +msgstr "Loš zahtev." + +#: class/MainWPChild.class.php:761 +#@ mainwp-child +msgid "Invalid request" +msgstr "Nevažeći zahtev." + +#: class/MainWPChild.class.php:767 +#@ mainwp-child +msgid "Public key already set, reset the MainWP plugin on your site and try again." +msgstr "Javni ključ je već podešen, resetujte MainWP na sajtu i pokušajte ponovo." + +#: class/MainWPChild.class.php:774 +#@ mainwp-child +msgid "This Child Site is set to require a Unique Security ID - Please Enter It before connection can be established." +msgstr "Jedinstveni sigurnosni ključ je potreban za ovaj sajt - Molimo, unesite ključ kako bi konekcija mogla biti uspostavljena." + +#: class/MainWPChild.class.php:778 +#@ mainwp-child +msgid "The Unique Security ID you have entered does not match Child Security ID - Please Correct It before connection can be established." +msgstr "Jedinstveni sigurnosni ključ koji ste uneli se ne poklapa sa ključem na sajtu - Molimo, ispravite ključ kako bi konekcija mogla biti uspostavljena." + +#: class/MainWPChild.class.php:1036 +#@ mainwp-child +msgid "Could not change the admin password." +msgstr "Administratorska šifra nije mogla biti promenjena." + +#: class/MainWPChild.class.php:1058 +#@ mainwp-child +msgid "Undefined error" +msgstr "Nedefinisana greška" + +#: class/MainWPChild.class.php:1072 +#, php-format +#@ default +msgid "Username: %s" +msgstr "Korisnično ime: %s" + +#: class/MainWPChild.class.php:1073 +#, php-format +#@ default +msgid "Password: %s" +msgstr "Lozinka: %s" + +#: class/MainWPChild.class.php:1076 +#, php-format +#@ default +msgid "[%s] Your username and password" +msgstr "[%s] Vaše korisničko ime i lozinka" + +#: class/MainWPChild.class.php:2326 +#@ mainwp-child +msgid "This site already contains a link - please disable and enable the MainWP plugin." +msgstr "Saj već poseduje link - Molimo, deaktivirajte, pa ponovo aktivirajte MainWP" + +#: class/MainWPChild.class.php:2433 +#@ mainwp-child +msgid "Wordpress Filesystem error: " +msgstr "WordPress sistemska greška: " + +#: class/MainWPClone.class.php:70 +#@ mainwp-child +msgid "File could not be uploaded." +msgstr "Datoteka nije mogla biti uploadovana." + +#: class/MainWPClone.class.php:75 +#@ mainwp-child +msgid "File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini." +msgstr "Datoteka je prazna. Molimo, uplodujte validnu datoteku. Do ove greške moglo je doći ako je upload zabranjen u Vašoj php.ini datoteci ili ako je post_max_size definisan kao manji od upload_max_filesize u php.ini datoteci." + +#: class/MainWPClone.class.php:84 +#@ mainwp-child +msgid "Clone or Restore" +msgstr "Kloniranje ili Vratite prethodno stanje" + +#: class/MainWPClone.class.php:88 +#@ mainwp-child +msgid "Cloning is currently off - To turn on return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Kloniranje je trenutno isključeno - da biste omogućili kloniranje, vratite se na Kontrolni sajt i uključite kloniranje na stranici Kloniranje." + +#: class/MainWPClone.class.php:94 +#@ mainwp-child +msgid "Your content directory is not writable. Please set 0755 permission to " +msgstr "Direktorium u kome se nalazi Vaš sadržaj nije upisiv. Molimo, podesite ovlašćenja na 0755. " + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid "Cloning process completed successfully! You will now need to click " +msgstr "Proces kloniranja uspešno završen! Potrebno je da kliknete " + +#: class/MainWPClone.class.php:98 +#: class/MainWPClone.class.php:956 +#@ mainwp-child +msgid "here" +msgstr "ovde" + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid " to re-login to the admin and re-save permalinks." +msgstr "da biste se logovali i opet podesili linkove." + +#: class/MainWPClone.class.php:103 +#@ mainwp-child +msgid "Upload successful." +msgstr "Upload uspešan." + +#: class/MainWPClone.class.php:103 +#: class/MainWPClone.class.php:153 +#@ mainwp-child +msgid "Clone/Restore Website" +msgstr "Klonira/Vrati Sajt" + +#: class/MainWPClone.class.php:114 +#@ mainwp-child +msgid "Cloning is currently on but no sites have been allowed, to allow sites return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Kloniranje je trenutno uključeno, ali nema sajtova sa ovlašćenjem za kloniranje. Da biste omogućili sajtu da bude kloniran, vratite se na Kontrolni sajt i odaberite selktujte sajtove na stranici Kloniranje." + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Display by:" +msgstr "Prikaži po:" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Site Name" +msgstr "Naziv Sajta" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "URL" +msgstr "URL" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Clone Options" +msgstr "Opcije za kloniranje" + +#: class/MainWPClone.class.php:139 +#@ mainwp-child +msgid "Clone Website" +msgstr "Kloniraj sajt" + +#: class/MainWPClone.class.php:148 +#@ mainwp-child +msgid "Restore/Clone From Backup" +msgstr "Vrati/Kloniraj sa Backup datotekom" + +#: class/MainWPClone.class.php:150 +#@ mainwp-child +msgid "Upload backup in .zip format (Maximum filesize for your server settings: " +msgstr "Uploadujte backup datoteku u .zip formatu. (Maksimalna veličina datoteke za Vaš server je: " + +#: class/MainWPClone.class.php:151 +#@ mainwp-child +msgid "If you have a FULL backup created by your Network dashboard you may restore it by uploading here." +msgstr "Ako image Kompletan Backup kreiran uz pomoć MainWP plugina, možete ga uploadovati ovde." + +#: class/MainWPClone.class.php:152 +#@ mainwp-child +msgid "A database only backup will not work." +msgstr "Backup samo baze podataka neće raditi." + +#: class/MainWPClone.class.php:662 +#: class/MainWPClone.class.php:699 +#@ mainwp-child +msgid "No site given" +msgstr "Nema datog sajta" + +#: class/MainWPClone.class.php:667 +#: class/MainWPClone.class.php:704 +#@ mainwp-child +msgid "Site not found" +msgstr "Sajt nije pronađen" + +#: class/MainWPClone.class.php:679 +#@ mainwp-child +msgid "Could not create backupfile on child" +msgstr "Kreiranje backup datoteke na sajtu neuspešan" + +#: class/MainWPClone.class.php:715 +#@ mainwp-child +msgid "Invalid response" +msgstr "Nevažeći odgovor" + +#: class/MainWPClone.class.php:731 +#@ mainwp-child +msgid "No download link given" +msgstr "Link za preuzimanje nije dat" + +#: class/MainWPClone.class.php:803 +#: class/MainWPClone.class.php:832 +#@ mainwp-child +msgid "No download file found" +msgstr "Datoteka za preuzimanje nije pronađena" + +#: class/MainWPClone.class.php:838 +#@ mainwp-child +msgid "Backup file not found" +msgstr "Backup datoteka nije pronađena" + +#: class/MainWPClone.class.php:956 +#@ mainwp-child +msgid "Cloning process completed successfully! Check and re-save permalinks " +msgstr "Process kloniranja uspešno završen! Proverite i ponovo sačuvajte perma-linkove " + +#: class/MainWPCloneInstall.class.php:79 +#: class/MainWPCloneInstall.class.php:80 +#@ mainwp-child +msgid "Not a full backup." +msgstr "Nije kompletan backup." + +#: class/MainWPCloneInstall.class.php:81 +#@ mainwp-child +msgid "Database backup not found." +msgstr "Backup baze podataka nije pronađen." + +#: class/MainWPCloneInstall.class.php:118 +#@ mainwp-child +msgid "Cant read configuration file from backup" +msgstr "Nije moguće prošitati konfiguracionu datoteku iz backup-a" + +#: class/MainWPCloneInstall.class.php:130 +#@ mainwp-child +msgid "Invalid database host or user/password." +msgstr "Nevažeći host baze podataka ili korisničko ime i lozinka." + +#: class/MainWPCloneInstall.class.php:133 +#@ mainwp-child +msgid "Invalid database name" +msgstr "Pogrešan naziv baze podataka" + +#: class/MainWPCloneInstall.class.php:239 +#@ mainwp-child +msgid "Error importing database" +msgstr "Greška pri unosu baze podataka" + +#: class/MainWPCloneInstall.class.php:244 +#@ mainwp-child +msgid "Error: unexpected end of file for database" +msgstr "Greška: neočekivan kraj baze podataka" + +#: class/MainWPHeatmapTracker.class.php:68 +#@ default +msgid "Home Page" +msgstr "Glavna strana" + +#: class/MainWPHeatmapTracker.class.php:111 +#@ default +msgid "Archive" +msgstr "Arhiva" + +#: class/MainWPHeatmapTracker.class.php:135 +#@ default +msgid "Search" +msgstr "Pretraži" + +#: class/MainWPHeatmapTracker.class.php:144 +#@ default +msgid "Blog Home Page" +msgstr "Glavan strana bloga" + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid "Unable to create directory " +msgstr "Kreiranje direktorijuma nemoguće " + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid " Is its parent directory writable by the server?" +msgstr "Da li je direktorijum upisiv od strane servera?" + +#: class/MainWPHelper.class.php:376 +#@ mainwp-child +msgid "Something went wrong while contacting the child site. Please check if there is an error on the child site. This error could also be caused by trying to clone or restore a site to large for your server settings." +msgstr "Nešto nije u redu u komunikaciji za sajtom. Molimo proverite da li ima grešaka na sajtu. Do ove greške moglo je doći ako ste pokušali klonirati sajt veći nego što je dozvoljeno u podešavanjima servera." + +#: class/MainWPHelper.class.php:380 +#@ mainwp-child +msgid "Child plugin is disabled or the security key is incorrect. Please resync with your main installation." +msgstr "Child Plugin je isključen ili je sigurnosni ključ pogrešan. Molimo, sinhronizujte sa Vašnom glavnom instalacijom." + +#: class/MainWPClone.class.php:15 +#@ mainwp-child +msgid "MainWP Clone" +msgstr "MainWP Kloniranje" + +#: class/MainWPClone.class.php:221 +#, php-format +#@ mainwp-child +msgid "This is a large site (%dMB), the clone process will more than likely fail." +msgstr "Ovo je veliki sajt (%dMB), kloniranje verovatno neće uspeti." + +#: class/MainWPClone.class.php:222 +#@ mainwp-child +msgid "Continue Anyway?" +msgstr "Nastavi u svakom slučaju?" + +#: class/MainWPClone.class.php:223 +#, php-format +#@ mainwp-child +msgid "Creating backup on %s expected size: %dMB (estimated time: %d seconds)" +msgstr "Kreiranje backupa na %s očekivana veličina %dMB (očekivano vreme trajanja %d sekundi)" + +#: class/MainWPClone.class.php:224 +#, php-format +#@ mainwp-child +msgid "Backup created on %s total size to download: %dMB" +msgstr "Backup kreiran na %s puna veličina za download: %dMB" + +#: class/MainWPClone.class.php:225 +#@ mainwp-child +msgid "Downloading backup" +msgstr "Preuzimanje backupa" + +#: class/MainWPClone.class.php:226 +#@ mainwp-child +msgid "Backup downloaded" +msgstr "Backup preuzet" + +#: class/MainWPClone.class.php:227 +#@ mainwp-child +msgid "Extracting backup and updating your database, this might take a while. Please be patient." +msgstr "Raspakivanje backupa i ažuriranje baze podataka u toku, ovo može potrajati. Molimo, budite strpljivi." + +#: class/MainWPClone.class.php:228 +#@ mainwp-child +msgid "Cloning process completed successfully!" +msgstr "Kloniranje uspešno završeno!" + diff --git a/languages/mainwp-child-de_DE.mo b/languages/mainwp-child-de_DE.mo new file mode 100644 index 0000000000000000000000000000000000000000..4a092d4d0a8b7c115b3a6fdb2aabda03b4cf1ecc GIT binary patch literal 9288 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\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: CSL v1.x\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n" +"X-Poedit-Basepath: ../\n" +"X-Poedit-Bookmarks: \n" +"X-Poedit-SearchPath-0: .\n" +"X-Textdomain-Support: yes" + +#: class/MainWPChild.class.php:137 +#: class/MainWPChild.class.php:163 +#@ mainwp-child +msgid "MainWP Settings" +msgstr "MainWP Einstellungen" + +#: class/MainWPChild.class.php:167 +#@ mainwp-child +msgid "Connection Settings" +msgstr "Verbindungseinstellungen" + +#: class/MainWPChild.class.php:175 +#@ mainwp-child +msgid "Require Unique Security ID" +msgstr "Eine eindeutige Sicherheits-ID" + +#: class/MainWPChild.class.php:178 +#@ mainwp-child +msgid "Your Unique Security ID is:" +msgstr "Ihre eindeutige Sicherheits-ID ist:" + +#: class/MainWPChild.class.php:182 +#@ mainwp-child +msgid "The Unique Security ID adds additional protection between the Child plugin and your
Main Dashboard. The Unique Security ID will need to match when being added to
the Main Dashboard. This is additional security and should not be needed in most situations." +msgstr "Die eindeutige Sicherheits-ID bringt zusätzlichen Schutz zwischen dem Client und Ihrem
MainWP Dashboard. Die eindeutige Sicherheits-ID muß übereinstimmen, wenn sie im MainWP Dashboard aufgenommen wird.
Dies ist eine zusätzliche Sicherheit und ist in den meisten Fällen nicht erforderlich." + +#: class/MainWPChild.class.php:188 +#@ mainwp-child +msgid "Save Changes" +msgstr "Änderungen speichern" + +#: class/MainWPChild.class.php:446 +#@ mainwp-child +msgid "Authentication failed. Reinstall MainWP plugin please" +msgstr "Authentifizierung fehlgeschlagen. Installieren Sie bitte das MainWP Plugin erneut." + +#: class/MainWPChild.class.php:455 +#: class/MainWPChild.class.php:846 +#@ mainwp-child +msgid "No such user" +msgstr "Keine solche Benutzer" + +#: class/MainWPChild.class.php:460 +#: class/MainWPChild.class.php:850 +#@ mainwp-child +msgid "User is not an administrator" +msgstr "Benutzer ist kein Administrator" + +#: class/MainWPChild.class.php:550 +#@ mainwp-child +msgid "Bad request." +msgstr "Fehlerhafte Anforderung." + +#: class/MainWPChild.class.php:757 +#: class/MainWPChild.class.php:762 +#: class/MainWPChild.class.php:795 +#: class/MainWPChild.class.php:800 +#: class/MainWPChild.class.php:805 +#@ mainwp-child +msgid "Bad request" +msgstr "Fehlerhafte Anforderung" + +#: class/MainWPChild.class.php:820 +#@ mainwp-child +msgid "Invalid request" +msgstr "Ungültige Anforderung" + +#: class/MainWPChild.class.php:826 +#@ mainwp-child +msgid "Public key already set, reset the MainWP plugin on your site and try again." +msgstr "Öffentlicher Schlüssel bereits festgelegt, setzen Sie die MainWP Plugin auf Ihrer Website erneut auf und versuchen Sie es noch einmal" + +#: class/MainWPChild.class.php:833 +#@ mainwp-child +msgid "This Child Site is set to require a Unique Security ID - Please Enter It before connection can be established." +msgstr "Dieser Client erfordert eine eindeutige Sicherheits-ID. Bitte geben Sie diese ein bevor eine Verbindung hergestellt werden kann." + +#: class/MainWPChild.class.php:837 +#@ mainwp-child +msgid "The Unique Security ID you have entered does not match Child Security ID - Please Correct It before connection can be established." +msgstr "Die eindeutige Sicherheits-ID die Sie eingegeben haben, entspricht nicht der Client Security ID. Bitte verbessern Sie dies bevor eine Verbindung hergestellt werden kann." + +#: class/MainWPChild.class.php:1102 +#@ mainwp-child +msgid "Could not change the admin password." +msgstr "Das Admin-Passwort kann nicht geändern werden." + +#: class/MainWPChild.class.php:1124 +#@ mainwp-child +msgid "Undefined error" +msgstr "Undefinierter Fehler" + +#: class/MainWPChild.class.php:1138 +#, php-format +#@ default +msgid "Username: %s" +msgstr "" + +#: class/MainWPChild.class.php:1139 +#, php-format +#@ default +msgid "Password: %s" +msgstr "" + +#: class/MainWPChild.class.php:1142 +#, php-format +#@ default +msgid "[%s] Your username and password" +msgstr "" + +#: class/MainWPChild.class.php:2446 +#@ mainwp-child +msgid "This site already contains a link - please disable and enable the MainWP plugin." +msgstr "Diese Website enthält bereits diesen Link" + +#: class/MainWPChild.class.php:2557 +#@ mainwp-child +msgid "Wordpress Filesystem error: " +msgstr "Wordpress-Dateisystem-Fehler:" + +#: class/MainWPChildServerInformation.class.php:12 +#@ mainwp +msgid "Server Configuration" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:13 +#@ mainwp +msgid "Suggested Value" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:14 +#: class/MainWPChildServerInformation.class.php:56 +#@ mainwp +msgid "Value" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:15 +#: class/MainWPChildServerInformation.class.php:41 +#@ mainwp +msgid "Status" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:37 +#@ mainwp +msgid "Directory name" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:38 +#@ mainwp +msgid "Path" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:39 +#@ mainwp +msgid "Check" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:40 +#@ mainwp +msgid "Result" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:55 +#@ mainwp +msgid "Server Info" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:60 +#@ mainwp +msgid "WordPress Root Directory" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:61 +#@ mainwp +msgid "Server Name" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:62 +#@ mainwp +msgid "Server Sofware" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:63 +#@ mainwp +msgid "Operating System" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:64 +#@ mainwp +msgid "Architecture" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:65 +#@ mainwp +msgid "Server IP" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:66 +#@ mainwp +msgid "Server Protocol" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:67 +#@ mainwp +msgid "HTTP Host" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:68 +#@ mainwp +msgid "Server Admin" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:69 +#@ mainwp +msgid "Server Port" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:70 +#@ mainwp +msgid "Getaway Interface" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:71 +#@ mainwp +msgid "Memory Usage" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:72 +#@ mainwp +msgid "HTTPS" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:73 +#@ mainwp +msgid "User Agent" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:74 +#@ mainwp +msgid "Complete URL" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:75 +#@ mainwp +msgid "Request Method" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:76 +#@ mainwp +msgid "Request Time" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:77 +#@ mainwp +msgid "Query String" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:78 +#@ mainwp +msgid "Accept Content" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:79 +#@ mainwp +msgid "Accept-Charset Content" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:80 +#@ mainwp +msgid "Currently Executing Script Pathname" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:81 +#@ mainwp +msgid "Server Signature" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:82 +#@ mainwp +msgid "Currently Executing Script" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:83 +#@ mainwp +msgid "Path Translated" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:84 +#@ mainwp +msgid "Current Script Path" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:85 +#@ mainwp +msgid "Current Page URI" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:86 +#@ mainwp +msgid "Remote Address" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:87 +#@ mainwp +msgid "Remote Host" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:88 +#@ mainwp +msgid "Remote Port" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:89 +#@ mainwp +msgid "PHP Safe Mode" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:90 +#@ mainwp +msgid "PHP Allow URL fopen" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:91 +#@ mainwp +msgid "PHP Exif Support" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:92 +#@ mainwp +msgid "PHP IPTC Support" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:93 +#@ mainwp +msgid "PHP XML Support" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:94 +#@ mainwp +msgid "SQL Mode" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:109 +#@ mainwp +msgid "Next due" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:110 +#@ mainwp +msgid "Schedule" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:111 +#@ mainwp +msgid "Hook" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:245 +#@ default +msgid " MB" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:246 +#: class/MainWPChildServerInformation.class.php:336 +#: class/MainWPChildServerInformation.class.php:371 +#: class/MainWPChildServerInformation.class.php:400 +#@ default +#@ mainwp +msgid "N/A" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:255 +#: class/MainWPChildServerInformation.class.php:269 +#: class/MainWPChildServerInformation.class.php:358 +#@ default +#@ mainwp +msgid "ON" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:256 +#: class/MainWPChildServerInformation.class.php:270 +#: class/MainWPChildServerInformation.class.php:361 +#@ default +#@ mainwp +msgid "OFF" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:264 +#@ default +msgid "NOT SET" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:275 +#: class/MainWPChildServerInformation.class.php:281 +#: class/MainWPChildServerInformation.class.php:287 +#@ default +msgid "YES" +msgstr "" + +#: class/MainWPChildServerInformation.class.php:276 +#: class/MainWPChildServerInformation.class.php:282 +#: class/MainWPChildServerInformation.class.php:288 +#@ default +msgid "NO" +msgstr "" + +#: class/MainWPClone.class.php:15 +#@ mainwp-child +msgid "MainWP Clone" +msgstr "MainWP Klon" + +#: class/MainWPClone.class.php:70 +#@ mainwp-child +msgid "File could not be uploaded." +msgstr "Datei konnte nicht hochgeladen werden." + +#: class/MainWPClone.class.php:75 +#@ mainwp-child +msgid "File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini." +msgstr "Die Datei ist leer. Bitte laden Sie etwas mit Inhalt. Dieser Upload-Fehler könnte auch verursacht werden durhc eine Einstellung in der php.ini oder durch einstellung von post_max_size als kleiner als upload_max_filesize in der php.ini." + +#: class/MainWPClone.class.php:84 +#@ mainwp-child +msgid "Clone or Restore" +msgstr "Klonen oder wiederherstellen" + +#: class/MainWPClone.class.php:88 +#@ mainwp-child +msgid "Cloning is currently off - To turn on return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Klonen ist derzeit aus - Zum aktivieren des Klones, auf der MainWP Dashboards auf Klonen gehen" + +#: class/MainWPClone.class.php:94 +#@ mainwp-child +msgid "Your content directory is not writable. Please set 0755 permission to " +msgstr "Das Inhalte Verzeichnis ist nicht beschreibbar. Bitte die Berechtigung setzen auf 0755." + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid "Cloning process completed successfully! You will now need to click " +msgstr "Klonen erfolgreich abgeschlossen! Sie müssen nun Klicken" + +#: class/MainWPClone.class.php:98 +#: class/MainWPClone.class.php:1069 +#: class/MainWPClone.class.php:1098 +#@ mainwp-child +msgid "here" +msgstr "hier" + +#: class/MainWPClone.class.php:98 +#: class/MainWPClone.class.php:1098 +#@ mainwp-child +msgid " to re-login to the admin and re-save permalinks." +msgstr "sich erneut anmelden, um den Admin und erneut speichern des Permalinks." + +#: class/MainWPClone.class.php:103 +#@ mainwp-child +msgid "Upload successful." +msgstr "Hochladen erfolgreich." + +#: class/MainWPClone.class.php:103 +#: class/MainWPClone.class.php:153 +#@ mainwp-child +msgid "Clone/Restore Website" +msgstr "Klonen / Wiederherstellen Webseite" + +#: class/MainWPClone.class.php:114 +#@ mainwp-child +msgid "Cloning is currently on but no sites have been allowed, to allow sites return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Klonen ist derzeit erlaubt, aber keine Seite hat es erlaubt. " + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Display by:" +msgstr "Anzeige von:" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Site Name" +msgstr "Seitenname" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "URL" +msgstr "URL" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Clone Options" +msgstr "Einstellung Klonen" + +#: class/MainWPClone.class.php:139 +#@ mainwp-child +msgid "Clone Website" +msgstr "Webseite Klonen" + +#: class/MainWPClone.class.php:148 +#@ mainwp-child +msgid "Restore/Clone From Backup" +msgstr "Wiederherstellen/Klonen von Datensicherung" + +#: class/MainWPClone.class.php:150 +#@ mainwp-child +msgid "Upload backup in .zip format (Maximum filesize for your server settings: " +msgstr "Hochladen der Datensicherungsdatei im .zip Format (Maximale Dateigröße Server-Einstellungen:" + +#: class/MainWPClone.class.php:151 +#@ mainwp-child +msgid "If you have a FULL backup created by your Network dashboard you may restore it by uploading here." +msgstr "Wenn Sie eine vollständige Sicherung von Ihrem Netzwerk-Dashboard erstellt haben, können Sie es von hier Hochladen um es wiederherzustellen." + +#: class/MainWPClone.class.php:152 +#@ mainwp-child +msgid "A database only backup will not work." +msgstr "Eine einziges Datenbank-Backup wird nicht funktionieren." + +#: class/MainWPClone.class.php:229 +#, php-format +#@ mainwp-child +msgid "This is a large site (%dMB), the clone process will more than likely fail." +msgstr "Dies ist eine große Seite (%dMB), der Klon-Prozess wird mehr als wahrscheinlich scheitern." + +#: class/MainWPClone.class.php:230 +#@ mainwp-child +msgid "Continue Anyway?" +msgstr "Trotzdem fortfahren?" + +#: class/MainWPClone.class.php:231 +#, php-format +#@ mainwp-child +msgid "Creating backup on %s expected size: %dMB (estimated time: %d seconds)" +msgstr "Erstellen von Backup auf %s erwarteten Größe: %dMB (geschätzte Zeit: %d in Sekunden)" + +#: class/MainWPClone.class.php:232 +#, php-format +#@ mainwp-child +msgid "Backup created on %s total size to download: %dMB" +msgstr "Backup erstellt auf %s Gesamtgröße zum Download: %dMB" + +#: class/MainWPClone.class.php:233 +#@ mainwp-child +msgid "Downloading backup" +msgstr "Herunterladen der Datensicherung" + +#: class/MainWPClone.class.php:234 +#@ mainwp-child +msgid "Backup downloaded" +msgstr "Datensicherung heruntergeladen" + +#: class/MainWPClone.class.php:235 +#@ mainwp-child +msgid "Extracting backup and updating your database, this might take a while. Please be patient." +msgstr "Auspacken der Datensicherung und Aktualisierung Ihre Datenbank. Dies könnte eine Weile dauern. Bitte haben Sie Geduld." + +#: class/MainWPClone.class.php:236 +#@ mainwp-child +msgid "Cloning process completed successfully!" +msgstr "Klonen erfolgreich abgeschlossen!" + +#: class/MainWPClone.class.php:755 +#: class/MainWPClone.class.php:792 +#@ mainwp-child +msgid "No site given" +msgstr "Kein Seite angegeben" + +#: class/MainWPClone.class.php:760 +#: class/MainWPClone.class.php:797 +#@ mainwp-child +msgid "Site not found" +msgstr "Seite nicht gefunden" + +#: class/MainWPClone.class.php:772 +#@ mainwp-child +msgid "Could not create backupfile on child" +msgstr "Konnte Datensicherungsdatei nicht auf dem Client erstellen" + +#: class/MainWPClone.class.php:808 +#@ mainwp-child +msgid "Invalid response" +msgstr "Ungültige Antwort" + +#: class/MainWPClone.class.php:824 +#@ mainwp-child +msgid "No download link given" +msgstr "Keinen Download-Link angegeben" + +#: class/MainWPClone.class.php:899 +#: class/MainWPClone.class.php:925 +#@ mainwp-child +msgid "No download file found" +msgstr "Keine Download-Datei gefunden" + +#: class/MainWPClone.class.php:931 +#@ mainwp-child +msgid "Backup file not found" +msgstr "Datensicherungsdatei nicht gefunden" + +#: class/MainWPClone.class.php:1069 +#@ mainwp-child +msgid "Restore process completed successfully! Check and re-save permalinks " +msgstr "Wiederherstellungs-Vorgang erfolgreich abgeschlossen! Überprüfen und Permalinks erneut speichern" + +#: class/MainWPClone.class.php:1069 +#@ mainwp-child +msgid "Cloning process completed successfully! Check and re-save permalinks " +msgstr "Klonen erfolgreich abgeschlossen! Überprüfen und Permalinks erneut speichern" + +#: class/MainWPClone.class.php:1093 +#@ mainwp-child +msgid "Restore" +msgstr "Wiederherstellen" + +#: class/MainWPClone.class.php:1095 +#@ mainwp-child +msgid "Be sure to use a FULL backup created by your Network dashboard, if critical folders are excluded it may result in a not working installation." +msgstr "Achten Sie darauf, eine vollständige Sicherung von Ihrem MainWP Dashboard zu erstellen." + +#: class/MainWPClone.class.php:1096 +#@ mainwp-child +msgid "Start Restore" +msgstr "Wiederherstellung starten" + +#: class/MainWPClone.class.php:1096 +#@ mainwp-child +msgid "CAUTION: this will overwrite your existing site." +msgstr "ACHTUNG: dies wird Ihre bestehende Seite überschreiben." + +#: class/MainWPClone.class.php:1098 +#@ mainwp-child +msgid "Restore process completed successfully! You will now need to click " +msgstr "Wiederherstellungsvorgang erfolgreich abgeschlossen! Sie müssen nun klicken" + +#: class/MainWPClone.class.php:1102 +#@ mainwp-child +msgid "Restore process completed successfully!" +msgstr "Wiederherstellungsvorgang erfolgreich abgeschlossen!" + +#: class/MainWPCloneInstall.class.php:79 +#: class/MainWPCloneInstall.class.php:80 +#@ mainwp-child +msgid "Not a full backup." +msgstr "Keine gesamte Datensicherung." + +#: class/MainWPCloneInstall.class.php:81 +#@ mainwp-child +msgid "Database backup not found." +msgstr "Datenbank-Sicherung nicht gefunden." + +#: class/MainWPCloneInstall.class.php:118 +#@ mainwp-child +msgid "Cant read configuration file from backup" +msgstr "Kann Konfigurationsdatei nicht lesen aus der Datensicherung" + +#: class/MainWPCloneInstall.class.php:133 +#@ mainwp-child +msgid "Invalid database host or user/password." +msgstr "Ungültige Datenbank-Host oder Benutzer / Passwort." + +#: class/MainWPCloneInstall.class.php:136 +#@ mainwp-child +msgid "Invalid database name" +msgstr "Ungültiger Datenbanknamen" + +#: class/MainWPCloneInstall.class.php:271 +#: class/MainWPCloneInstall.class.php:370 +#@ mainwp-child +msgid "Error: unexpected end of file for database" +msgstr "Fehler: unerwartetes Ende der Datei für die Datenbank" + +#: class/MainWPCloneInstall.class.php:365 +#@ mainwp-child +msgid "Error importing database" +msgstr "Fehler beim Importieren der Datenbank" + +#: class/MainWPHeatmapTracker.class.php:68 +#@ default +msgid "Home Page" +msgstr "" + +#: class/MainWPHeatmapTracker.class.php:111 +#@ default +msgid "Archive" +msgstr "" + +#: class/MainWPHeatmapTracker.class.php:135 +#@ default +msgid "Search" +msgstr "" + +#: class/MainWPHeatmapTracker.class.php:144 +#@ default +msgid "Blog Home Page" +msgstr "" + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid "Unable to create directory " +msgstr "Verzeichnis kann nicht erstellt" + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid " Is its parent directory writable by the server?" +msgstr "Ist das übergeordnete Verzeichnis durch den Server beschreibbar?" + +#: class/MainWPHelper.class.php:380 +#@ mainwp-child +msgid "Something went wrong while contacting the child site. Please check if there is an error on the child site. This error could also be caused by trying to clone or restore a site to large for your server settings." +msgstr "Etwas ist schiefgelaufen, während der Verbindung zum Client. Bitte überprüfen Sie, ob es einen Fehler von der Client Webseite ist." + +#: class/MainWPHelper.class.php:384 +#@ mainwp-child +msgid "Child plugin is disabled or the security key is incorrect. Please resync with your main installation." +msgstr "MainWP Clhild Plugin ist deaktiviert oder der Sicherheitsschlüssel ist falsch." + diff --git a/languages/mainwp-child-hr_HR.mo b/languages/mainwp-child-hr_HR.mo new file mode 100644 index 0000000000000000000000000000000000000000..6f34b67ade21f332b4232477f585255b5fdd1360 GIT binary patch literal 8378 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 IlIqm|0F`Ua&j0`b literal 0 HcmV?d00001 diff --git a/languages/mainwp-child-hr_HR.po b/languages/mainwp-child-hr_HR.po new file mode 100644 index 00000000..a7f7a993 --- /dev/null +++ b/languages/mainwp-child-hr_HR.po @@ -0,0 +1,411 @@ +msgid "" +msgstr "" +"Project-Id-Version: MainWP Child v0.11\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2013-11-15 14:04:59+0000\n" +"Last-Translator: admin \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%100/10==1 ? 2 : n%10==1 ? 0 : (n+9)%10>3 ? 2 : 1;\n" +"X-Generator: CSL v1.x\n" +"X-Poedit-Language: Croatian\n" +"X-Poedit-Country: CROATIA\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n" +"X-Poedit-Basepath: ../\n" +"X-Poedit-Bookmarks: \n" +"X-Poedit-SearchPath-0: .\n" +"X-Textdomain-Support: yes" + +#: class/MainWPChild.class.php:132 +#: class/MainWPChild.class.php:154 +#@ mainwp-child +msgid "MainWP Settings" +msgstr "MainWP Podešavanje" + +#: class/MainWPChild.class.php:158 +#@ mainwp-child +msgid "Connection Settings" +msgstr "Podešavanje konekcije" + +#: class/MainWPChild.class.php:166 +#@ mainwp-child +msgid "Require Unique Security ID" +msgstr "Zahtev za jedinstveni sigurnosni ključ" + +#: class/MainWPChild.class.php:169 +#@ mainwp-child +msgid "Your Unique Security ID is:" +msgstr "Vaš jedinstveni sigurnosni ključ je:" + +#: class/MainWPChild.class.php:173 +#@ mainwp-child +msgid "The Unique Security ID adds additional protection between the Child plugin and your
Main Dashboard. The Unique Security ID will need to match when being added to
the Main Dashboard. This is additional security and should not be needed in most situations." +msgstr "Jedinstveni sigurnosni ključ obezbeđuje dodatnu zaštitu između sajta i kontrolne table.
Jedinstveni sigurnosni ključ se mora poklapati prilikom dodavanja sajta u kontrolnu tablu.
Ova dodatna sigrnosna opcija, u većini slučajeva nije potrebna." + +#: class/MainWPChild.class.php:179 +#@ mainwp-child +msgid "Save Changes" +msgstr "Sačuvaj Promene" + +#: class/MainWPChild.class.php:424 +#@ mainwp-child +msgid "Authentication failed. Reinstall MainWP plugin please" +msgstr "Autentifikacija neuspešna. Molimo, reinstalirajte MainWP." + +#: class/MainWPChild.class.php:433 +#: class/MainWPChild.class.php:787 +#@ mainwp-child +msgid "No such user" +msgstr "Nepostojeći korisnik" + +#: class/MainWPChild.class.php:438 +#: class/MainWPChild.class.php:791 +#@ mainwp-child +msgid "User is not an administrator" +msgstr "Korisnik nema administratorske privilegije." + +#: class/MainWPChild.class.php:528 +#@ mainwp-child +msgid "Bad request." +msgstr "Loš zahtev." + +#: class/MainWPChild.class.php:699 +#: class/MainWPChild.class.php:704 +#: class/MainWPChild.class.php:736 +#: class/MainWPChild.class.php:741 +#: class/MainWPChild.class.php:746 +#@ mainwp-child +msgid "Bad request" +msgstr "Loš zahtev." + +#: class/MainWPChild.class.php:761 +#@ mainwp-child +msgid "Invalid request" +msgstr "Nevažeći zahtev." + +#: class/MainWPChild.class.php:767 +#@ mainwp-child +msgid "Public key already set, reset the MainWP plugin on your site and try again." +msgstr "Javni ključ je već podešen, resetujte MainWP na sajtu i pokušajte ponovo." + +#: class/MainWPChild.class.php:774 +#@ mainwp-child +msgid "This Child Site is set to require a Unique Security ID - Please Enter It before connection can be established." +msgstr "Jedinstveni sigurnosni ključ je potreban za ovaj sajt - Molimo, unesite ključ kako bi konekcija mogla biti uspostavljena." + +#: class/MainWPChild.class.php:778 +#@ mainwp-child +msgid "The Unique Security ID you have entered does not match Child Security ID - Please Correct It before connection can be established." +msgstr "Jedinstveni sigurnosni ključ koji ste uneli se ne poklapa sa ključem na sajtu - Molimo, ispravite ključ kako bi konekcija mogla biti uspostavljena." + +#: class/MainWPChild.class.php:1036 +#@ mainwp-child +msgid "Could not change the admin password." +msgstr "Administratorska šifra nije mogla biti promenjena." + +#: class/MainWPChild.class.php:1058 +#@ mainwp-child +msgid "Undefined error" +msgstr "Nedefinisana greška" + +#: class/MainWPChild.class.php:1072 +#, php-format +#@ default +msgid "Username: %s" +msgstr "Korisnično ime: %s" + +#: class/MainWPChild.class.php:1073 +#, php-format +#@ default +msgid "Password: %s" +msgstr "Lozinka: %s" + +#: class/MainWPChild.class.php:1076 +#, php-format +#@ default +msgid "[%s] Your username and password" +msgstr "[%s] Vaše korisničko ime i lozinka" + +#: class/MainWPChild.class.php:2326 +#@ mainwp-child +msgid "This site already contains a link - please disable and enable the MainWP plugin." +msgstr "Saj već poseduje link - Molimo, deaktivirajte, pa ponovo aktivirajte MainWP" + +#: class/MainWPChild.class.php:2433 +#@ mainwp-child +msgid "Wordpress Filesystem error: " +msgstr "WordPress sistemska greška: " + +#: class/MainWPClone.class.php:70 +#@ mainwp-child +msgid "File could not be uploaded." +msgstr "Datoteka nije mogla biti uploadovana." + +#: class/MainWPClone.class.php:75 +#@ mainwp-child +msgid "File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini." +msgstr "Datoteka je prazna. Molimo, uplodujte validnu datoteku. Do ove greške moglo je doći ako je upload zabranjen u Vašoj php.ini datoteci ili ako je post_max_size definisan kao manji od upload_max_filesize u php.ini datoteci." + +#: class/MainWPClone.class.php:84 +#@ mainwp-child +msgid "Clone or Restore" +msgstr "Kloniranje ili Vratite prethodno stanje" + +#: class/MainWPClone.class.php:88 +#@ mainwp-child +msgid "Cloning is currently off - To turn on return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Kloniranje je trenutno isključeno - da biste omogućili kloniranje, vratite se na Kontrolni sajt i uključite kloniranje na stranici Kloniranje." + +#: class/MainWPClone.class.php:94 +#@ mainwp-child +msgid "Your content directory is not writable. Please set 0755 permission to " +msgstr "Direktorium u kome se nalazi Vaš sadržaj nije upisiv. Molimo, podesite ovlašćenja na 0755. " + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid "Cloning process completed successfully! You will now need to click " +msgstr "Proces kloniranja uspešno završen! Potrebno je da kliknete " + +#: class/MainWPClone.class.php:98 +#: class/MainWPClone.class.php:956 +#@ mainwp-child +msgid "here" +msgstr "ovde" + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid " to re-login to the admin and re-save permalinks." +msgstr "da biste se logovali i opet podesili linkove." + +#: class/MainWPClone.class.php:103 +#@ mainwp-child +msgid "Upload successful." +msgstr "Upload uspešan." + +#: class/MainWPClone.class.php:103 +#: class/MainWPClone.class.php:153 +#@ mainwp-child +msgid "Clone/Restore Website" +msgstr "Klonira/Vrati Sajt" + +#: class/MainWPClone.class.php:114 +#@ mainwp-child +msgid "Cloning is currently on but no sites have been allowed, to allow sites return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Kloniranje je trenutno uključeno, ali nema sajtova sa ovlašćenjem za kloniranje. Da biste omogućili sajtu da bude kloniran, vratite se na Kontrolni sajt i odaberite selktujte sajtove na stranici Kloniranje." + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Display by:" +msgstr "Prikaži po:" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Site Name" +msgstr "Naziv Sajta" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "URL" +msgstr "URL" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Clone Options" +msgstr "Opcije za kloniranje" + +#: class/MainWPClone.class.php:139 +#@ mainwp-child +msgid "Clone Website" +msgstr "Kloniraj sajt" + +#: class/MainWPClone.class.php:148 +#@ mainwp-child +msgid "Restore/Clone From Backup" +msgstr "Vrati/Kloniraj sa Backup datotekom" + +#: class/MainWPClone.class.php:150 +#@ mainwp-child +msgid "Upload backup in .zip format (Maximum filesize for your server settings: " +msgstr "Uploadujte backup datoteku u .zip formatu. (Maksimalna veličina datoteke za Vaš server je: " + +#: class/MainWPClone.class.php:151 +#@ mainwp-child +msgid "If you have a FULL backup created by your Network dashboard you may restore it by uploading here." +msgstr "Ako image Kompletan Backup kreiran uz pomoć MainWP plugina, možete ga uploadovati ovde." + +#: class/MainWPClone.class.php:152 +#@ mainwp-child +msgid "A database only backup will not work." +msgstr "Backup samo baze podataka neće raditi." + +#: class/MainWPClone.class.php:662 +#: class/MainWPClone.class.php:699 +#@ mainwp-child +msgid "No site given" +msgstr "Nema datog sajta" + +#: class/MainWPClone.class.php:667 +#: class/MainWPClone.class.php:704 +#@ mainwp-child +msgid "Site not found" +msgstr "Sajt nije pronađen" + +#: class/MainWPClone.class.php:679 +#@ mainwp-child +msgid "Could not create backupfile on child" +msgstr "Kreiranje backup datoteke na sajtu neuspešan" + +#: class/MainWPClone.class.php:715 +#@ mainwp-child +msgid "Invalid response" +msgstr "Nevažeći odgovor" + +#: class/MainWPClone.class.php:731 +#@ mainwp-child +msgid "No download link given" +msgstr "Link za preuzimanje nije dat" + +#: class/MainWPClone.class.php:803 +#: class/MainWPClone.class.php:832 +#@ mainwp-child +msgid "No download file found" +msgstr "Datoteka za preuzimanje nije pronađena" + +#: class/MainWPClone.class.php:838 +#@ mainwp-child +msgid "Backup file not found" +msgstr "Backup datoteka nije pronađena" + +#: class/MainWPClone.class.php:956 +#@ mainwp-child +msgid "Cloning process completed successfully! Check and re-save permalinks " +msgstr "Process kloniranja uspešno završen! Proverite i ponovo sačuvajte perma-linkove " + +#: class/MainWPCloneInstall.class.php:79 +#: class/MainWPCloneInstall.class.php:80 +#@ mainwp-child +msgid "Not a full backup." +msgstr "Nije kompletan backup." + +#: class/MainWPCloneInstall.class.php:81 +#@ mainwp-child +msgid "Database backup not found." +msgstr "Backup baze podataka nije pronađen." + +#: class/MainWPCloneInstall.class.php:118 +#@ mainwp-child +msgid "Cant read configuration file from backup" +msgstr "Nije moguće prošitati konfiguracionu datoteku iz backup-a" + +#: class/MainWPCloneInstall.class.php:130 +#@ mainwp-child +msgid "Invalid database host or user/password." +msgstr "Nevažeći host baze podataka ili korisničko ime i lozinka." + +#: class/MainWPCloneInstall.class.php:133 +#@ mainwp-child +msgid "Invalid database name" +msgstr "Pogrešan naziv baze podataka" + +#: class/MainWPCloneInstall.class.php:239 +#@ mainwp-child +msgid "Error importing database" +msgstr "Greška pri unosu baze podataka" + +#: class/MainWPCloneInstall.class.php:244 +#@ mainwp-child +msgid "Error: unexpected end of file for database" +msgstr "Greška: neočekivan kraj baze podataka" + +#: class/MainWPHeatmapTracker.class.php:68 +#@ default +msgid "Home Page" +msgstr "Glavna strana" + +#: class/MainWPHeatmapTracker.class.php:111 +#@ default +msgid "Archive" +msgstr "Arhiva" + +#: class/MainWPHeatmapTracker.class.php:135 +#@ default +msgid "Search" +msgstr "Pretraži" + +#: class/MainWPHeatmapTracker.class.php:144 +#@ default +msgid "Blog Home Page" +msgstr "Glavan strana bloga" + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid "Unable to create directory " +msgstr "Kreiranje direktorijuma nemoguće " + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid " Is its parent directory writable by the server?" +msgstr "Da li je direktorijum upisiv od strane servera?" + +#: class/MainWPHelper.class.php:376 +#@ mainwp-child +msgid "Something went wrong while contacting the child site. Please check if there is an error on the child site. This error could also be caused by trying to clone or restore a site to large for your server settings." +msgstr "Nešto nije u redu u komunikaciji za sajtom. Molimo proverite da li ima grešaka na sajtu. Do ove greške moglo je doći ako ste pokušali klonirati sajt veći nego što je dozvoljeno u podešavanjima servera." + +#: class/MainWPHelper.class.php:380 +#@ mainwp-child +msgid "Child plugin is disabled or the security key is incorrect. Please resync with your main installation." +msgstr "Child Plugin je isključen ili je sigurnosni ključ pogrešan. Molimo, sinhronizujte sa Vašnom glavnom instalacijom." + +#: class/MainWPClone.class.php:15 +#@ mainwp-child +msgid "MainWP Clone" +msgstr "MainWP Kloniranje" + +#: class/MainWPClone.class.php:221 +#, php-format +#@ mainwp-child +msgid "This is a large site (%dMB), the clone process will more than likely fail." +msgstr "Ovo je veliki sajt (%dMB), kloniranje verovatno neće uspeti." + +#: class/MainWPClone.class.php:222 +#@ mainwp-child +msgid "Continue Anyway?" +msgstr "Nastavi u svakom slučaju?" + +#: class/MainWPClone.class.php:223 +#, php-format +#@ mainwp-child +msgid "Creating backup on %s expected size: %dMB (estimated time: %d seconds)" +msgstr "Kreiranje backupa na %s očekivana veličina %dMB (očekivano vreme trajanja %d sekundi)" + +#: class/MainWPClone.class.php:224 +#, php-format +#@ mainwp-child +msgid "Backup created on %s total size to download: %dMB" +msgstr "Backup kreiran na %s puna veličina za download: %dMB" + +#: class/MainWPClone.class.php:225 +#@ mainwp-child +msgid "Downloading backup" +msgstr "Preuzimanje backupa" + +#: class/MainWPClone.class.php:226 +#@ mainwp-child +msgid "Backup downloaded" +msgstr "Backup preuzet" + +#: class/MainWPClone.class.php:227 +#@ mainwp-child +msgid "Extracting backup and updating your database, this might take a while. Please be patient." +msgstr "Raspakivanje backupa i ažuriranje baze podataka u toku, ovo može potrajati. Molimo, budite strpljivi." + +#: class/MainWPClone.class.php:228 +#@ mainwp-child +msgid "Cloning process completed successfully!" +msgstr "Kloniranje uspešno završeno!" + diff --git a/languages/mainwp-child-sr_CS.mo b/languages/mainwp-child-sr_CS.mo new file mode 100644 index 0000000000000000000000000000000000000000..fe1bc526bd4e1fb759dca6c136c0302e4c50f836 GIT binary patch literal 8334 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\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: CSL v1.x\n" +"X-Poedit-Language: Serbian (Cyrillic)\n" +"X-Poedit-Country: SERBIA AND MONTENEGRO\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n" +"X-Poedit-Basepath: ../\n" +"X-Poedit-Bookmarks: \n" +"X-Poedit-SearchPath-0: .\n" +"X-Textdomain-Support: yes" + +#: class/MainWPChild.class.php:132 +#: class/MainWPChild.class.php:154 +#@ mainwp-child +msgid "MainWP Settings" +msgstr "MainWP Podešavanje" + +#: class/MainWPChild.class.php:158 +#@ mainwp-child +msgid "Connection Settings" +msgstr "Podešavanje konekcije" + +#: class/MainWPChild.class.php:166 +#@ mainwp-child +msgid "Require Unique Security ID" +msgstr "Zahtev za jedinstveni sigurnosni ključ" + +#: class/MainWPChild.class.php:169 +#@ mainwp-child +msgid "Your Unique Security ID is:" +msgstr "Vaš jedinstveni sigurnosni ključ je:" + +#: class/MainWPChild.class.php:173 +#@ mainwp-child +msgid "The Unique Security ID adds additional protection between the Child plugin and your
Main Dashboard. The Unique Security ID will need to match when being added to
the Main Dashboard. This is additional security and should not be needed in most situations." +msgstr "Jedinstveni sigurnosni ključ obezbeđuje dodatnu zaštitu između sajta i kontrolne table.
Jedinstveni sigurnosni ključ se mora poklapati prilikom dodavanja sajta u kontrolnu tablu.
Ova dodatna sigrnosna opcija, u većini slučajeva nije potrebna." + +#: class/MainWPChild.class.php:179 +#@ mainwp-child +msgid "Save Changes" +msgstr "Sačuvaj Promene" + +#: class/MainWPChild.class.php:424 +#@ mainwp-child +msgid "Authentication failed. Reinstall MainWP plugin please" +msgstr "Autentifikacija neuspešna. Molimo, reinstalirajte MainWP." + +#: class/MainWPChild.class.php:433 +#: class/MainWPChild.class.php:787 +#@ mainwp-child +msgid "No such user" +msgstr "Nepostojeći korisnik" + +#: class/MainWPChild.class.php:438 +#: class/MainWPChild.class.php:791 +#@ mainwp-child +msgid "User is not an administrator" +msgstr "Korisnik nema administratorske privilegije." + +#: class/MainWPChild.class.php:528 +#@ mainwp-child +msgid "Bad request." +msgstr "Loš zahtev." + +#: class/MainWPChild.class.php:699 +#: class/MainWPChild.class.php:704 +#: class/MainWPChild.class.php:736 +#: class/MainWPChild.class.php:741 +#: class/MainWPChild.class.php:746 +#@ mainwp-child +msgid "Bad request" +msgstr "Loš zahtev." + +#: class/MainWPChild.class.php:761 +#@ mainwp-child +msgid "Invalid request" +msgstr "Nevažeći zahtev." + +#: class/MainWPChild.class.php:767 +#@ mainwp-child +msgid "Public key already set, reset the MainWP plugin on your site and try again." +msgstr "Javni ključ je već podešen, resetujte MainWP na sajtu i pokušajte ponovo." + +#: class/MainWPChild.class.php:774 +#@ mainwp-child +msgid "This Child Site is set to require a Unique Security ID - Please Enter It before connection can be established." +msgstr "Jedinstveni sigurnosni ključ je potreban za ovaj sajt - Molimo, unesite ključ kako bi konekcija mogla biti uspostavljena." + +#: class/MainWPChild.class.php:778 +#@ mainwp-child +msgid "The Unique Security ID you have entered does not match Child Security ID - Please Correct It before connection can be established." +msgstr "Jedinstveni sigurnosni ključ koji ste uneli se ne poklapa sa ključem na sajtu - Molimo, ispravite ključ kako bi konekcija mogla biti uspostavljena." + +#: class/MainWPChild.class.php:1036 +#@ mainwp-child +msgid "Could not change the admin password." +msgstr "Administratorska šifra nije mogla biti promenjena." + +#: class/MainWPChild.class.php:1058 +#@ mainwp-child +msgid "Undefined error" +msgstr "Nedefinisana greška" + +#: class/MainWPChild.class.php:1072 +#, php-format +#@ default +msgid "Username: %s" +msgstr "Korisnično ime: %s" + +#: class/MainWPChild.class.php:1073 +#, php-format +#@ default +msgid "Password: %s" +msgstr "Lozinka: %s" + +#: class/MainWPChild.class.php:1076 +#, php-format +#@ default +msgid "[%s] Your username and password" +msgstr "[%s] Vaše korisničko ime i lozinka" + +#: class/MainWPChild.class.php:2326 +#@ mainwp-child +msgid "This site already contains a link - please disable and enable the MainWP plugin." +msgstr "Saj već poseduje link - Molimo, deaktivirajte, pa ponovo aktivirajte MainWP" + +#: class/MainWPChild.class.php:2433 +#@ mainwp-child +msgid "Wordpress Filesystem error: " +msgstr "WordPress sistemska greška: " + +#: class/MainWPClone.class.php:70 +#@ mainwp-child +msgid "File could not be uploaded." +msgstr "Datoteka nije mogla biti uploadovana." + +#: class/MainWPClone.class.php:75 +#@ mainwp-child +msgid "File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini." +msgstr "Datoteka je prazna. Molimo, uplodujte validnu datoteku. Do ove greške moglo je doći ako je upload zabranjen u Vašoj php.ini datoteci ili ako je post_max_size definisan kao manji od upload_max_filesize u php.ini datoteci." + +#: class/MainWPClone.class.php:84 +#@ mainwp-child +msgid "Clone or Restore" +msgstr "Kloniranje ili Vratite prethodno stanje" + +#: class/MainWPClone.class.php:88 +#@ mainwp-child +msgid "Cloning is currently off - To turn on return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Kloniranje je trenutno isključeno - da biste omogućili kloniranje, vratite se na Kontrolni sajt i uključite kloniranje na stranici Kloniranje." + +#: class/MainWPClone.class.php:94 +#@ mainwp-child +msgid "Your content directory is not writable. Please set 0755 permission to " +msgstr "Direktorium u kome se nalazi Vaš sadržaj nije upisiv. Molimo, podesite ovlašćenja na 0755. " + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid "Cloning process completed successfully! You will now need to click" +msgstr "Proces kloniranja uspešno završen! Potrebno je da kliknete" + +#: class/MainWPClone.class.php:98 +#: class/MainWPClone.class.php:956 +#@ mainwp-child +msgid "here" +msgstr "ovde" + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid " to re-login to the admin and re-save permalinks." +msgstr "da biste se logovali i opet podesili linkove." + +#: class/MainWPClone.class.php:103 +#@ mainwp-child +msgid "Upload successful." +msgstr "Upload uspešan." + +#: class/MainWPClone.class.php:103 +#: class/MainWPClone.class.php:153 +#@ mainwp-child +msgid "Clone/Restore Website" +msgstr "Klonira/Vrati Sajt" + +#: class/MainWPClone.class.php:114 +#@ mainwp-child +msgid "Cloning is currently on but no sites have been allowed, to allow sites return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Kloniranje je trenutno uključeno, ali nema sajtova sa ovlašćenjem za kloniranje. Da biste omogućili sajtu da bude kloniran, vratite se na Kontrolni sajt i odaberite selktujte sajtove na stranici Kloniranje." + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Display by:" +msgstr "Prikaži po:" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Site Name" +msgstr "Naziv Sajta" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "URL" +msgstr "URL" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Clone Options" +msgstr "Opcije za kloniranje" + +#: class/MainWPClone.class.php:139 +#@ mainwp-child +msgid "Clone Website" +msgstr "Kloniraj sajt" + +#: class/MainWPClone.class.php:148 +#@ mainwp-child +msgid "Restore/Clone From Backup" +msgstr "Vrati/Kloniraj sa Backup datotekom" + +#: class/MainWPClone.class.php:150 +#@ mainwp-child +msgid "Upload backup in .zip format (Maximum filesize for your server settings: " +msgstr "Uploadujte backup datoteku u .zip formatu. (Maksimalna veličina datoteke za Vaš server je: " + +#: class/MainWPClone.class.php:151 +#@ mainwp-child +msgid "If you have a FULL backup created by your Network dashboard you may restore it by uploading here." +msgstr "Ako image Kompletan Backup kreiran uz pomoć MainWP plugina, možete ga uploadovati ovde." + +#: class/MainWPClone.class.php:152 +#@ mainwp-child +msgid "A database only backup will not work." +msgstr "Backup samo baze podataka neće raditi." + +#: class/MainWPClone.class.php:662 +#: class/MainWPClone.class.php:699 +#@ mainwp-child +msgid "No site given" +msgstr "Nema datog sajta" + +#: class/MainWPClone.class.php:667 +#: class/MainWPClone.class.php:704 +#@ mainwp-child +msgid "Site not found" +msgstr "Sajt nije pronađen" + +#: class/MainWPClone.class.php:679 +#@ mainwp-child +msgid "Could not create backupfile on child" +msgstr "Kreiranje backup datoteke na sajtu neuspešan" + +#: class/MainWPClone.class.php:715 +#@ mainwp-child +msgid "Invalid response" +msgstr "Nevažeći odgovor" + +#: class/MainWPClone.class.php:731 +#@ mainwp-child +msgid "No download link given" +msgstr "Link za preuzimanje nije dat" + +#: class/MainWPClone.class.php:803 +#: class/MainWPClone.class.php:832 +#@ mainwp-child +msgid "No download file found" +msgstr "Datoteka za preuzimanje nije pronađena" + +#: class/MainWPClone.class.php:838 +#@ mainwp-child +msgid "Backup file not found" +msgstr "Backup datoteka nije pronađena" + +#: class/MainWPClone.class.php:956 +#@ mainwp-child +msgid "Cloning process completed successfully! Check and re-save permalinks " +msgstr "Process kloniranja uspešno završen! Proverite i ponovo sačuvajte perma-linkove " + +#: class/MainWPCloneInstall.class.php:79 +#: class/MainWPCloneInstall.class.php:80 +#@ mainwp-child +msgid "Not a full backup." +msgstr "Nije kompletan backup." + +#: class/MainWPCloneInstall.class.php:81 +#@ mainwp-child +msgid "Database backup not found." +msgstr "Backup baze podataka nije pronađen." + +#: class/MainWPCloneInstall.class.php:118 +#@ mainwp-child +msgid "Cant read configuration file from backup" +msgstr "Nije moguće prošitati konfiguracionu datoteku iz backup-a" + +#: class/MainWPCloneInstall.class.php:130 +#@ mainwp-child +msgid "Invalid database host or user/password." +msgstr "Nevažeći host baze podataka ili korisničko ime i lozinka." + +#: class/MainWPCloneInstall.class.php:133 +#@ mainwp-child +msgid "Invalid database name" +msgstr "Pogrešan naziv baze podataka" + +#: class/MainWPCloneInstall.class.php:239 +#@ mainwp-child +msgid "Error importing database" +msgstr "Greška pri unosu baze podataka" + +#: class/MainWPCloneInstall.class.php:244 +#@ mainwp-child +msgid "Error: unexpected end of file for database" +msgstr "Greška: neočekivan kraj baze podataka" + +#: class/MainWPHeatmapTracker.class.php:68 +#@ default +msgid "Home Page" +msgstr "Glavna strana" + +#: class/MainWPHeatmapTracker.class.php:111 +#@ default +msgid "Archive" +msgstr "Arhiva" + +#: class/MainWPHeatmapTracker.class.php:135 +#@ default +msgid "Search" +msgstr "Pretraži" + +#: class/MainWPHeatmapTracker.class.php:144 +#@ default +msgid "Blog Home Page" +msgstr "Glavan strana bloga" + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid "Unable to create directory " +msgstr "Kreiranje direktorijuma nemoguće " + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid " Is its parent directory writable by the server?" +msgstr "Da li je direktorijum upisiv od strane servera?" + +#: class/MainWPHelper.class.php:376 +#@ mainwp-child +msgid "Something went wrong while contacting the child site. Please check if there is an error on the child site. This error could also be caused by trying to clone or restore a site to large for your server settings." +msgstr "Nešto nije u redu u komunikaciji za sajtom. Molimo proverite da li ima grešaka na sajtu. Do ove greške moglo je doći ako ste pokušali klonirati sajt veći nego što je dozvoljeno u podešavanjima servera." + +#: class/MainWPHelper.class.php:380 +#@ mainwp-child +msgid "Child plugin is disabled or the security key is incorrect. Please resync with your main installation." +msgstr "Child Plugin je isključen ili je sigurnosni ključ pogrešan. Molimo, sinhronizujte sa Vašnom glavnom instalacijom." + +#: class/MainWPClone.class.php:15 +#@ mainwp-child +msgid "MainWP Clone" +msgstr "MainWP Kloniranje" + +#: class/MainWPClone.class.php:221 +#, php-format +#@ mainwp-child +msgid "This is a large site (%dMB), the clone process will more than likely fail." +msgstr "Ovo je veliki sajt (%dMB), kloniranje verovatno neće uspeti." + +#: class/MainWPClone.class.php:222 +#@ mainwp-child +msgid "Continue Anyway?" +msgstr "Nastavi u svakom slučaju?" + +#: class/MainWPClone.class.php:223 +#, php-format +#@ mainwp-child +msgid "Creating backup on %s expected size: %dMB (estimated time: %d seconds)" +msgstr "Kreiranje backupa na %s očekivana veličina %dMB (očekivano vreme trajanja %d sekundi)" + +#: class/MainWPClone.class.php:224 +#, php-format +#@ mainwp-child +msgid "Backup created on %s total size to download: %dMB" +msgstr "Backup kreiran na %s puna veličina za download: %dMB" + +#: class/MainWPClone.class.php:225 +#@ mainwp-child +msgid "Downloading backup" +msgstr "Preuzimanje backupa" + +#: class/MainWPClone.class.php:226 +#@ mainwp-child +msgid "Backup downloaded" +msgstr "Backup preuzet" + +#: class/MainWPClone.class.php:227 +#@ mainwp-child +msgid "Extracting backup and updating your database, this might take a while. Please be patient." +msgstr "Raspakivanje backupa i ažuriranje baze podataka u toku, ovo može potrajati. Molimo, budite strpljivi." + +#: class/MainWPClone.class.php:228 +#@ mainwp-child +msgid "Cloning process completed successfully!" +msgstr "Kloniranje uspešno završeno!" + diff --git a/languages/mainwp-child-sr_RS.mo b/languages/mainwp-child-sr_RS.mo new file mode 100644 index 0000000000000000000000000000000000000000..adcca0a61f10692107f83b77f702374495834b3f GIT binary patch literal 8334 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 RTy5>^F6qSET1l!?{{a(U!-W6< literal 0 HcmV?d00001 diff --git a/languages/mainwp-child-sr_RS.po b/languages/mainwp-child-sr_RS.po new file mode 100644 index 00000000..8f23e9ca --- /dev/null +++ b/languages/mainwp-child-sr_RS.po @@ -0,0 +1,411 @@ +msgid "" +msgstr "" +"Project-Id-Version: MainWP Child v0.11\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2013-11-15 14:00:59+0000\n" +"Last-Translator: admin \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: CSL v1.x\n" +"X-Poedit-Language: Serbian\n" +"X-Poedit-Country: SERBIA\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n" +"X-Poedit-Basepath: \n" +"X-Poedit-Bookmarks: \n" +"X-Poedit-SearchPath-0: .\n" +"X-Textdomain-Support: yes" + +#: class/MainWPChild.class.php:132 +#: class/MainWPChild.class.php:154 +#@ mainwp-child +msgid "MainWP Settings" +msgstr "MainWP Podešavanje" + +#: class/MainWPChild.class.php:158 +#@ mainwp-child +msgid "Connection Settings" +msgstr "Podešavanje konekcije" + +#: class/MainWPChild.class.php:166 +#@ mainwp-child +msgid "Require Unique Security ID" +msgstr "Zahtev za jedinstveni sigurnosni ključ" + +#: class/MainWPChild.class.php:169 +#@ mainwp-child +msgid "Your Unique Security ID is:" +msgstr "Vaš jedinstveni sigurnosni ključ je:" + +#: class/MainWPChild.class.php:173 +#@ mainwp-child +msgid "The Unique Security ID adds additional protection between the Child plugin and your
Main Dashboard. The Unique Security ID will need to match when being added to
the Main Dashboard. This is additional security and should not be needed in most situations." +msgstr "Jedinstveni sigurnosni ključ obezbeđuje dodatnu zaštitu između sajta i kontrolne table.
Jedinstveni sigurnosni ključ se mora poklapati prilikom dodavanja sajta u kontrolnu tablu.
Ova dodatna sigrnosna opcija, u većini slučajeva nije potrebna." + +#: class/MainWPChild.class.php:179 +#@ mainwp-child +msgid "Save Changes" +msgstr "Sačuvaj Promene" + +#: class/MainWPChild.class.php:424 +#@ mainwp-child +msgid "Authentication failed. Reinstall MainWP plugin please" +msgstr "Autentifikacija neuspešna. Molimo, reinstalirajte MainWP." + +#: class/MainWPChild.class.php:433 +#: class/MainWPChild.class.php:787 +#@ mainwp-child +msgid "No such user" +msgstr "Nepostojeći korisnik" + +#: class/MainWPChild.class.php:438 +#: class/MainWPChild.class.php:791 +#@ mainwp-child +msgid "User is not an administrator" +msgstr "Korisnik nema administratorske privilegije." + +#: class/MainWPChild.class.php:528 +#@ mainwp-child +msgid "Bad request." +msgstr "Loš zahtev." + +#: class/MainWPChild.class.php:699 +#: class/MainWPChild.class.php:704 +#: class/MainWPChild.class.php:736 +#: class/MainWPChild.class.php:741 +#: class/MainWPChild.class.php:746 +#@ mainwp-child +msgid "Bad request" +msgstr "Loš zahtev." + +#: class/MainWPChild.class.php:761 +#@ mainwp-child +msgid "Invalid request" +msgstr "Nevažeći zahtev." + +#: class/MainWPChild.class.php:767 +#@ mainwp-child +msgid "Public key already set, reset the MainWP plugin on your site and try again." +msgstr "Javni ključ je već podešen, resetujte MainWP na sajtu i pokušajte ponovo." + +#: class/MainWPChild.class.php:774 +#@ mainwp-child +msgid "This Child Site is set to require a Unique Security ID - Please Enter It before connection can be established." +msgstr "Jedinstveni sigurnosni ključ je potreban za ovaj sajt - Molimo, unesite ključ kako bi konekcija mogla biti uspostavljena." + +#: class/MainWPChild.class.php:778 +#@ mainwp-child +msgid "The Unique Security ID you have entered does not match Child Security ID - Please Correct It before connection can be established." +msgstr "Jedinstveni sigurnosni ključ koji ste uneli se ne poklapa sa ključem na sajtu - Molimo, ispravite ključ kako bi konekcija mogla biti uspostavljena." + +#: class/MainWPChild.class.php:1036 +#@ mainwp-child +msgid "Could not change the admin password." +msgstr "Administratorska šifra nije mogla biti promenjena." + +#: class/MainWPChild.class.php:1058 +#@ mainwp-child +msgid "Undefined error" +msgstr "Nedefinisana greška" + +#: class/MainWPChild.class.php:1072 +#, php-format +#@ default +msgid "Username: %s" +msgstr "Korisnično ime: %s" + +#: class/MainWPChild.class.php:1073 +#, php-format +#@ default +msgid "Password: %s" +msgstr "Lozinka: %s" + +#: class/MainWPChild.class.php:1076 +#, php-format +#@ default +msgid "[%s] Your username and password" +msgstr "[%s] Vaše korisničko ime i lozinka" + +#: class/MainWPChild.class.php:2326 +#@ mainwp-child +msgid "This site already contains a link - please disable and enable the MainWP plugin." +msgstr "Saj već poseduje link - Molimo, deaktivirajte, pa ponovo aktivirajte MainWP" + +#: class/MainWPChild.class.php:2433 +#@ mainwp-child +msgid "Wordpress Filesystem error: " +msgstr "WordPress sistemska greška: " + +#: class/MainWPClone.class.php:70 +#@ mainwp-child +msgid "File could not be uploaded." +msgstr "Datoteka nije mogla biti uploadovana." + +#: class/MainWPClone.class.php:75 +#@ mainwp-child +msgid "File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini." +msgstr "Datoteka je prazna. Molimo, uplodujte validnu datoteku. Do ove greške moglo je doći ako je upload zabranjen u Vašoj php.ini datoteci ili ako je post_max_size definisan kao manji od upload_max_filesize u php.ini datoteci." + +#: class/MainWPClone.class.php:84 +#@ mainwp-child +msgid "Clone or Restore" +msgstr "Kloniranje ili Vratite prethodno stanje" + +#: class/MainWPClone.class.php:88 +#@ mainwp-child +msgid "Cloning is currently off - To turn on return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Kloniranje je trenutno isključeno - da biste omogućili kloniranje, vratite se na Kontrolni sajt i uključite kloniranje na stranici Kloniranje." + +#: class/MainWPClone.class.php:94 +#@ mainwp-child +msgid "Your content directory is not writable. Please set 0755 permission to " +msgstr "Direktorium u kome se nalazi Vaš sadržaj nije upisiv. Molimo, podesite ovlašćenja na 0755. " + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid "Cloning process completed successfully! You will now need to click " +msgstr "Proces kloniranja uspešno završen! Potrebno je da kliknete " + +#: class/MainWPClone.class.php:98 +#: class/MainWPClone.class.php:956 +#@ mainwp-child +msgid "here" +msgstr "ovde" + +#: class/MainWPClone.class.php:98 +#@ mainwp-child +msgid " to re-login to the admin and re-save permalinks." +msgstr "da biste se logovali i opet podesili linkove." + +#: class/MainWPClone.class.php:103 +#@ mainwp-child +msgid "Upload successful." +msgstr "Upload uspešan." + +#: class/MainWPClone.class.php:103 +#: class/MainWPClone.class.php:153 +#@ mainwp-child +msgid "Clone/Restore Website" +msgstr "Klonira/Vrati Sajt" + +#: class/MainWPClone.class.php:114 +#@ mainwp-child +msgid "Cloning is currently on but no sites have been allowed, to allow sites return to your main dashboard and turn cloning on on the Migrate/Clone page." +msgstr "Kloniranje je trenutno uključeno, ali nema sajtova sa ovlašćenjem za kloniranje. Da biste omogućili sajtu da bude kloniran, vratite se na Kontrolni sajt i odaberite selktujte sajtove na stranici Kloniranje." + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Display by:" +msgstr "Prikaži po:" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Site Name" +msgstr "Naziv Sajta" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "URL" +msgstr "URL" + +#: class/MainWPClone.class.php:122 +#@ mainwp-child +msgid "Clone Options" +msgstr "Opcije za kloniranje" + +#: class/MainWPClone.class.php:139 +#@ mainwp-child +msgid "Clone Website" +msgstr "Kloniraj sajt" + +#: class/MainWPClone.class.php:148 +#@ mainwp-child +msgid "Restore/Clone From Backup" +msgstr "Vrati/Kloniraj sa Backup datotekom" + +#: class/MainWPClone.class.php:150 +#@ mainwp-child +msgid "Upload backup in .zip format (Maximum filesize for your server settings: " +msgstr "Uploadujte backup datoteku u .zip formatu. (Maksimalna veličina datoteke za Vaš server je: " + +#: class/MainWPClone.class.php:151 +#@ mainwp-child +msgid "If you have a FULL backup created by your Network dashboard you may restore it by uploading here." +msgstr "Ako image Kompletan Backup kreiran uz pomoć MainWP plugina, možete ga uploadovati ovde." + +#: class/MainWPClone.class.php:152 +#@ mainwp-child +msgid "A database only backup will not work." +msgstr "Backup samo baze podataka neće raditi." + +#: class/MainWPClone.class.php:662 +#: class/MainWPClone.class.php:699 +#@ mainwp-child +msgid "No site given" +msgstr "Nema datog sajta" + +#: class/MainWPClone.class.php:667 +#: class/MainWPClone.class.php:704 +#@ mainwp-child +msgid "Site not found" +msgstr "Sajt nije pronađen" + +#: class/MainWPClone.class.php:679 +#@ mainwp-child +msgid "Could not create backupfile on child" +msgstr "Kreiranje backup datoteke na sajtu neuspešan" + +#: class/MainWPClone.class.php:715 +#@ mainwp-child +msgid "Invalid response" +msgstr "Nevažeći odgovor" + +#: class/MainWPClone.class.php:731 +#@ mainwp-child +msgid "No download link given" +msgstr "Link za preuzimanje nije dat" + +#: class/MainWPClone.class.php:803 +#: class/MainWPClone.class.php:832 +#@ mainwp-child +msgid "No download file found" +msgstr "Datoteka za preuzimanje nije pronađena" + +#: class/MainWPClone.class.php:838 +#@ mainwp-child +msgid "Backup file not found" +msgstr "Backup datoteka nije pronađena" + +#: class/MainWPClone.class.php:956 +#@ mainwp-child +msgid "Cloning process completed successfully! Check and re-save permalinks " +msgstr "Process kloniranja uspešno završen! Proverite i ponovo sačuvajte perma-linkove " + +#: class/MainWPCloneInstall.class.php:79 +#: class/MainWPCloneInstall.class.php:80 +#@ mainwp-child +msgid "Not a full backup." +msgstr "Nije kompletan backup." + +#: class/MainWPCloneInstall.class.php:81 +#@ mainwp-child +msgid "Database backup not found." +msgstr "Backup baze podataka nije pronađen." + +#: class/MainWPCloneInstall.class.php:118 +#@ mainwp-child +msgid "Cant read configuration file from backup" +msgstr "Nije moguće prošitati konfiguracionu datoteku iz backup-a" + +#: class/MainWPCloneInstall.class.php:130 +#@ mainwp-child +msgid "Invalid database host or user/password." +msgstr "Nevažeći host baze podataka ili korisničko ime i lozinka." + +#: class/MainWPCloneInstall.class.php:133 +#@ mainwp-child +msgid "Invalid database name" +msgstr "Pogrešan naziv baze podataka" + +#: class/MainWPCloneInstall.class.php:239 +#@ mainwp-child +msgid "Error importing database" +msgstr "Greška pri unosu baze podataka" + +#: class/MainWPCloneInstall.class.php:244 +#@ mainwp-child +msgid "Error: unexpected end of file for database" +msgstr "Greška: neočekivan kraj baze podataka" + +#: class/MainWPHeatmapTracker.class.php:68 +#@ default +msgid "Home Page" +msgstr "Glavna strana" + +#: class/MainWPHeatmapTracker.class.php:111 +#@ default +msgid "Archive" +msgstr "Arhiva" + +#: class/MainWPHeatmapTracker.class.php:135 +#@ default +msgid "Search" +msgstr "Pretraži" + +#: class/MainWPHeatmapTracker.class.php:144 +#@ default +msgid "Blog Home Page" +msgstr "Glavan strana bloga" + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid "Unable to create directory " +msgstr "Kreiranje direktorijuma nemoguće " + +#: class/MainWPHelper.class.php:233 +#@ mainwp-child +msgid " Is its parent directory writable by the server?" +msgstr "Da li je direktorijum upisiv od strane servera?" + +#: class/MainWPHelper.class.php:376 +#@ mainwp-child +msgid "Something went wrong while contacting the child site. Please check if there is an error on the child site. This error could also be caused by trying to clone or restore a site to large for your server settings." +msgstr "Nešto nije u redu u komunikaciji za sajtom. Molimo proverite da li ima grešaka na sajtu. Do ove greške moglo je doći ako ste pokušali klonirati sajt veći nego što je dozvoljeno u podešavanjima servera." + +#: class/MainWPHelper.class.php:380 +#@ mainwp-child +msgid "Child plugin is disabled or the security key is incorrect. Please resync with your main installation." +msgstr "Child Plugin je isključen ili je sigurnosni ključ pogrešan. Molimo, sinhronizujte sa Vašnom glavnom instalacijom." + +#: class/MainWPClone.class.php:15 +#@ mainwp-child +msgid "MainWP Clone" +msgstr "MainWP Kloniranje" + +#: class/MainWPClone.class.php:221 +#, php-format +#@ mainwp-child +msgid "This is a large site (%dMB), the clone process will more than likely fail." +msgstr "Ovo je veliki sajt (%dMB), kloniranje verovatno neće uspeti." + +#: class/MainWPClone.class.php:222 +#@ mainwp-child +msgid "Continue Anyway?" +msgstr "Nastavi u svakom slučaju?" + +#: class/MainWPClone.class.php:223 +#, php-format +#@ mainwp-child +msgid "Creating backup on %s expected size: %dMB (estimated time: %d seconds)" +msgstr "Kreiranje backupa na %s očekivana veličina %dMB (očekivano vreme trajanja %d sekundi)" + +#: class/MainWPClone.class.php:224 +#, php-format +#@ mainwp-child +msgid "Backup created on %s total size to download: %dMB" +msgstr "Backup kreiran na %s puna veličina za download: %dMB" + +#: class/MainWPClone.class.php:225 +#@ mainwp-child +msgid "Downloading backup" +msgstr "Preuzimanje backupa" + +#: class/MainWPClone.class.php:226 +#@ mainwp-child +msgid "Backup downloaded" +msgstr "Backup preuzet" + +#: class/MainWPClone.class.php:227 +#@ mainwp-child +msgid "Extracting backup and updating your database, this might take a while. Please be patient." +msgstr "Raspakivanje backupa i ažuriranje baze podataka u toku, ovo može potrajati. Molimo, budite strpljivi." + +#: class/MainWPClone.class.php:228 +#@ mainwp-child +msgid "Cloning process completed successfully!" +msgstr "Kloniranje uspešno završeno!" + diff --git a/mainwp-child.php b/mainwp-child.php new file mode 100644 index 00000000..db073192 --- /dev/null +++ b/mainwp-child.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/readme.txt b/readme.txt new file mode 100644 index 00000000..887c4843 --- /dev/null +++ b/readme.txt @@ -0,0 +1,157 @@ +=== MainWP Child === +Contributors: MainWP +Donate link: +Tags: WordPress Management, WordPress Controller +Author URI: http://mainwp.com +Plugin URI: http://mainwp.com +Requires at least: 3.6 +Tested up to: 3.8 +Stable tag: 0.26 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Allows you to manage multiple blogs from one dashboard by providing a secure connection between your child site and your MainWP dashboard. + +== Description == + +[MainWP](http://mainwp.com) is a self-hosted WordPress management system that allows you to manage an endless amount of WordPress blogs from one dashboard on your server. + +The MainWP Child plugin is used so the installed blog can be securely managed remotely by your Network. + +**Features include:** + +* Connect and control all your WordPress installs even those on different hosts! +* Update all WordPress installs, Plugins and Themes from one location +* Manage and Add all your Posts from one location +* Manage and Add all your Pages from one location +* Run everything from 1 Dashboard that you host! + + +== Installation == + +1. Upload the MainWP Child folder to the /wp-content/plugins/ directory +2. Activate the MainWP Child plugin through the 'Plugins' menu in WordPress + +== Frequently Asked Questions == + += What is the purpose of this plugin? = + +It allows the connection between the MainWP main dashboard plugin and the site it is installed on. + +To see full documentation and FAQs please visit [MainWP Documentation](http://docs.mainwp.com/) + +== Screenshots == + +1. The Dashboard Screen +2. The Posts Screen +3. The Comments Screen +4. The Sites Screen +5. The Plugins Screen +6. The Themes Screen +7. The Groups Screen +8. The Offline Checks Screen +9. The Clone Screen +10. The Extension Screen + +== Changelog == + += 0.27 = +* Wordpress 3.9 changes + += 0.26 = +* Minor fix for heatmap extension + += 0.25 = +* Fix for premium plugins + += 0.24 = +* Added support for premium plugins +* Fixed the restore functionality disappearing without Clone Extension +* Fixed some deprecated calls + += 0.23 = +* Fixed some deprecated warnings +* Fixed issues with Keyword Links extension + += 0.22 = +* Added extra functionality for keyword link extension + += 0.21 = +* Fixed clone issue for some hosts with FTP settings +* German translations added +* Support for 1.0.0 major version of main dashboard + += 0.20 = +* Fixed BPS-conflict where plugins were not upgrading + += 0.19 = +* Fixed issue for upgrading core/themes/plugins without FTP credentials + += 0.18 = +* Fixed issue for sending correct roles to the main dashboard +* Added htaccess file backup (backed up as mainwp-htaccess to prevent restore conflicts) + += 0.17 = +* Tuned for faster backup +* Added extension support for Maintenance extension + += 0.16 = +* Fixed some plugin conflicts preventing updates to themes/plugins/core + += 0.15 = +* Fixed issue with mismatching locale on core update + += 0.14 = +* Fixed redirection issue with wrongly encoded HTTP request + += 0.13 = +* Added restore function + += 0.12 = +* Fixed conflict with main dashboard on same site + += 0.11 = +* Plugin localisation +* Extra check for readme.html file +* Added child server information +* Fixed restore issue: not all previous plugins/themes were removed +* Fixed backup issue: not all files are being backed up + += 0.10 = +* Fixed plugin conflict +* Fixed backup issue with database names with dashes +* Fixed date formatting +* Tags are now being saved to new posts +* Fixed issue when posting an image with a link + += 0.9 = +* Fixed delete permanently bug +* Fixed plugin conflict + += 0.8 = +* Fixed issue with Content Extension +* Added feature to add sticky posts + += 0.7 = +* Fixed the message "This site already contains a link" even after reactivating the plugin + += 0.6 = +* Fixed plugin conflict with WooCommerce plugin for cloning +* Fixed backups having double the size + += 0.5 = +* Fixed issue with importing database with custom foreign key references +* Fixed issue with disabled functions from te "suhosin" extension +* Fixed issue with click-heatmap + += 0.4 = +Fixed cloning issue with custom prefix + += 0.3 = +* Fixed issues with cloning (not cloning the correct source if the source was cloned) + += 0.2 = +* Added unfix option for security issues + += 0.1 = +* Initial version \ No newline at end of file