Guest User

Untitled

a guest
Jan 8th, 2016
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.43 KB | None | 0 0
  1. <?php
  2. if (!defined('ABSPATH')) exit(__("The exchange using direct URL is not supported anymore. Please change your exchange URL to http://example.com/?wc1c=exchange.", 'woocommerce-1c'));
  3.  
  4. if (!defined('WC1C_SUPPRESS_NOTICES')) define('WC1C_SUPPRESS_NOTICES', false);
  5. if (!defined('WC1C_ZIP')) define('WC1C_ZIP', null);
  6. if (!defined('WC1C_FILE_LIMIT')) define('WC1C_FILE_LIMIT', null);
  7. if (!defined('WC1C_XML_CHARSET')) define('WC1C_XML_CHARSET', 'UTF-8');
  8. if (!defined('WC1C_DISABLE_VARIATIONS')) define('WC1C_DISABLE_VARIATIONS', false);
  9. define('WC1C_TIMESTAMP', time());
  10.  
  11. function wc1c_query_vars($query_vars) {
  12. $query_vars[] = 'wc1c';
  13.  
  14. return $query_vars;
  15. }
  16. add_filter('query_vars', 'wc1c_query_vars');
  17.  
  18. function wc1c_exchange_init() {
  19. add_rewrite_rule("wc1c/exchange", "index.php?wc1c=exchange", 'top');
  20. add_rewrite_rule("wc1c/clean", "index.php?wc1c=clean");
  21. flush_rewrite_rules();
  22. }
  23. add_action('init', 'wc1c_exchange_init', 1000);
  24.  
  25. function wc1c_is_debug() {
  26. return defined('WP_DEBUG') && WP_DEBUG || defined('WC1C_DEBUG') && WC1C_DEBUG;
  27. }
  28.  
  29. function wc1c_wpdb_end($is_commit = false, $no_check = false) {
  30. global $wpdb, $wc1c_is_transaction;
  31.  
  32. if (empty($wc1c_is_transaction)) return;
  33.  
  34. $wc1c_is_transaction = false;
  35.  
  36. $sql_query = !$is_commit ? "ROLLBACK" : "COMMIT";
  37. $wpdb->query($sql_query);
  38. if (!$no_check) wc1c_check_wpdb_error();
  39.  
  40. if (wc1c_is_debug()) echo "\n" . strtolower($sql_query);
  41. }
  42.  
  43. function wc1c_full_request_uri() {
  44. $uri = 'http';
  45. if (@$_SERVER['HTTPS'] == 'on') $uri .= 's';
  46. $uri .= "://{$_SERVER['SERVER_NAME']}";
  47. if ($_SERVER['SERVER_PORT'] != 80) $uri .= ":{$_SERVER['SERVER_PORT']}";
  48. if (isset($_SERVER['REQUEST_URI'])) $uri .= $_SERVER['REQUEST_URI'];
  49.  
  50. return $uri;
  51. }
  52.  
  53. function wc1c_error($message, $type = "Error", $no_exit = false) {
  54. global $wc1c_is_error;
  55.  
  56. $wc1c_is_error = true;
  57.  
  58. $message = "$type: $message";
  59. $last_char = substr($message, -1);
  60. if (!in_array($last_char, array('.', '!', '?'))) $message .= '.';
  61.  
  62. error_log($message);
  63. echo "$message\n";
  64.  
  65. if (wc1c_is_debug()) {
  66. echo "\n";
  67. debug_print_backtrace();
  68.  
  69. $info = array(
  70. "Request URI" => wc1c_full_request_uri(),
  71. "Server API" => PHP_SAPI,
  72. "Memory limit" => ini_get('memory_limit'),
  73. "Maximum POST size" => ini_get('post_max_size'),
  74. "PHP version" => PHP_VERSION,
  75. "WordPress version" => get_bloginfo('version'),
  76. "Plugin version" => WC1C_VERSION,
  77. );
  78. echo "\n";
  79. foreach ($info as $info_name => $info_value) {
  80. echo "$info_name: $info_value\n";
  81. }
  82. }
  83.  
  84. if (!$no_exit) {
  85. wc1c_wpdb_end();
  86.  
  87. exit;
  88. }
  89. }
  90.  
  91. function wc1c_set_strict_mode() {
  92. // $error_reporting_level = !WC1C_SUPPRESS_NOTICES ? -1 : E_ALL & ~E_NOTICE;
  93. // error_reporting($error_reporting_level);
  94. set_error_handler('wc1c_strict_error_handler');
  95. set_exception_handler('wc1c_strict_exception_handler');
  96. }
  97.  
  98. function wc1c_output_callback($buffer) {
  99. global $wc1c_is_error;
  100.  
  101. if (!headers_sent()) {
  102. $is_xml = @$_GET['mode'] == 'query';
  103. $content_type = !$is_xml || $wc1c_is_error ? 'text/plain' : 'text/xml';
  104. header("Content-Type: $content_type; charset=" . WC1C_XML_CHARSET);
  105. }
  106.  
  107. if (WC1C_XML_CHARSET == 'UTF-8') {
  108. $buffer = "\xEF\xBB\xBF$buffer";
  109. }
  110. else {
  111. $buffer = mb_convert_encoding($buffer, WC1C_XML_CHARSET, 'UTF-8');
  112. }
  113.  
  114. return $buffer;
  115. }
  116.  
  117. function wc1c_set_output_callback() {
  118. ob_start('wc1c_output_callback');
  119. }
  120.  
  121. function wc1c_strict_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
  122. if (error_reporting() === 0) return false;
  123.  
  124. switch ($errno) {
  125. // case E_NOTICE:
  126. // case E_USER_NOTICE:
  127. // $type = "Notice";
  128. // break;
  129. // case E_WARNING:
  130. // case E_USER_WARNING:
  131. // $type = "Warning";
  132. // break;
  133. case E_ERROR:
  134. case E_USER_ERROR:
  135. $type = "Fatal Error";
  136. break;
  137. default:
  138. $type = "Unknown Error";
  139. }
  140. if (!isset($type)) return false;
  141.  
  142. $message = sprintf("%s in %s on line %d", $errstr, $errfile, $errline);
  143. wc1c_error($message, "PHP $type");
  144. }
  145.  
  146. function wc1c_strict_exception_handler($exception) {
  147. $message = sprintf("%s in %s on line %d", $exception->getMessage(), $exception->getFile(), $exception->getLine());
  148. wc1c_error($message, "Exception");
  149. }
  150.  
  151. function wc1c_fix_fastcgi_get() {
  152. if (!$_GET && isset($_SERVER['REQUEST_URI'])) {
  153. $query = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
  154. parse_str($query, $_GET);
  155. }
  156. }
  157.  
  158. function wc1c_check_permissions($user) {
  159. if (!user_can($user, 'shop_manager') && !user_can($user, 'administrator')) wc1c_error("No permissions");
  160. }
  161.  
  162. function wc1c_wp_error($wp_error, $only_error_code = null) {
  163. $messages = array();
  164. foreach ($wp_error->get_error_codes() as $error_code) {
  165. if ($only_error_code && $error_code != $only_error_code) continue;
  166.  
  167. $wp_error_messages = implode(", ", $wp_error->get_error_messages($error_code));
  168. $wp_error_messages = strip_tags($wp_error_messages);
  169. $messages[] = sprintf("%s: %s", $error_code, $wp_error_messages);
  170. }
  171.  
  172. wc1c_error(implode("; ", $messages), "WP Error");
  173. }
  174.  
  175. function wc1c_check_wp_error($wp_error) {
  176. if (is_wp_error($wp_error)) wc1c_wp_error($wp_error);
  177. }
  178.  
  179. function wc1c_mode_checkauth() {
  180. foreach (array('HTTP_AUTHORIZATION', 'REDIRECT_HTTP_AUTHORIZATION') as $server_key) {
  181. if (!isset($_SERVER[$server_key])) continue;
  182.  
  183. list(, $auth_value) = explode(' ', $_SERVER[$server_key], 2);
  184. $auth_value = base64_decode($auth_value);
  185. list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', $auth_value);
  186.  
  187. break;
  188. }
  189.  
  190. if (!isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) wc1c_error("No authentication credentials");
  191.  
  192. $user = wp_authenticate($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
  193. wc1c_check_wp_error($user);
  194. wc1c_check_permissions($user);
  195.  
  196. $expiration = time() + apply_filters('auth_cookie_expiration', DAY_IN_SECONDS, $user->ID, false);
  197. $auth_cookie = wp_generate_auth_cookie($user->ID, $expiration);
  198.  
  199. exit("success\nwc1c-auth\n$auth_cookie");
  200. }
  201.  
  202. function wc1c_check_auth() {
  203. if (preg_match("/ Development Server$/", $_SERVER['SERVER_SOFTWARE'])) return;
  204.  
  205. if (!empty($_COOKIE['wc1c-auth'])) {
  206. $user = wp_validate_auth_cookie($_COOKIE['wc1c-auth'], 'auth');
  207. if (!$user) wc1c_error("Invalid cookie");
  208. }
  209. else {
  210. $user = wp_get_current_user();
  211. if (!$user->ID) wc1c_error("Not logged in");
  212. }
  213.  
  214. wc1c_check_permissions($user);
  215. }
  216.  
  217. function wc1c_filesize_to_bytes($filesize) {
  218. switch (substr($filesize, -1)) {
  219. case 'G':
  220. case 'g':
  221. return (int) $filesize * 1000000000;
  222. case 'M':
  223. case 'm':
  224. return (int) $filesize * 1000000;
  225. case 'K':
  226. case 'k':
  227. return (int) $filesize * 1000;
  228. default:
  229. return $filesize;
  230. }
  231. }
  232.  
  233. function wc1c_mode_init($type) {
  234. // wc1c_clean_data_dir($type);
  235.  
  236. if (is_null(WC1C_ZIP)) {
  237. @exec("which unzip", $_, $status);
  238. $is_zip = @$status === 0 || class_exists('ZipArchive');
  239. }
  240. else {
  241. $is_zip = WC1C_ZIP;
  242. }
  243. $zip = $is_zip ? 'yes' : 'no';
  244.  
  245. $file_limits = array(
  246. wc1c_filesize_to_bytes('10M'),
  247. wc1c_filesize_to_bytes(ini_get('post_max_size')),
  248. wc1c_filesize_to_bytes(ini_get('memory_limit')),
  249. );
  250. @exec("grep ^MemFree: /proc/meminfo", $output, $status);
  251. if (@$status === 0 && $output) {
  252. $output = preg_split("/\s+/", $output[0]);
  253. $file_limits[] = intval($output[1] * 1000 * 0.7);
  254. }
  255. if (WC1C_FILE_LIMIT) $file_limits[] = wc1c_filesize_to_bytes(WC1C_FILE_LIMIT);
  256. $file_limit = min($file_limits);
  257.  
  258. exit("zip=$zip\nfile_limit=$file_limit");
  259. }
  260.  
  261. function wc1c_mode_file($type, $filename) {
  262. if ($filename) {
  263. $path = WC1C_DATA_DIR . "$type/" . ltrim($filename, "./\\");
  264. $path_dir = dirname($path);
  265. if (!is_dir($path_dir)) mkdir($path_dir, 0777, true) or wc1c_error(sprintf("Failed to create directories for file %s", $filename));
  266.  
  267. $dest_fp = fopen($path, 'a') or wc1c_error(sprintf("Failed to open file %s", $filename));
  268. flock($dest_fp, LOCK_EX) or wc1c_error(sprintf("Failed to lock file %s", $filename));
  269.  
  270. $source_fp = fopen("php://input", 'r') or wc1c_error("Failed to open input file");
  271.  
  272. while (!feof($source_fp)) {
  273. if (($data = fread($source_fp, 8192)) === false) wc1c_error("Failed to read from input file");
  274. if (fwrite($dest_fp, $data) === false) wc1c_error(sprintf("Failed to write to file %s", $filename));
  275. }
  276.  
  277. fflush($dest_fp) or wc1c_error(sprintf("Failed to flush file %s", $filename));
  278. flock($dest_fp, LOCK_UN) or wc1c_error(sprintf("Failed to unlock file %s", $filename));
  279.  
  280. fclose($source_fp) or wc1c_error("Failed to close input file");
  281. fclose($dest_fp) or wc1c_error(sprintf("Failed to close file %s", $filename));
  282. }
  283.  
  284. if ($type == 'catalog') {
  285. exit("success");
  286. }
  287. elseif ($type == 'sale') {
  288. wc1c_unpack_files($type);
  289.  
  290. $data_dir = WC1C_DATA_DIR . $type;
  291. foreach (glob("$data_dir/*.xml") as $path) {
  292. $filename = basename($path);
  293. wc1c_mode_import($type, $filename, 'orders');
  294. }
  295. }
  296. }
  297.  
  298. function wc1c_check_wpdb_error() {
  299. global $wpdb;
  300.  
  301. if (!$wpdb->last_error) return;
  302.  
  303. wc1c_error(sprintf("%s for query \"%s\"", $wpdb->last_error, $wpdb->last_query), "DB Error", true);
  304.  
  305. wc1c_wpdb_end(false, true);
  306.  
  307. exit;
  308. }
  309.  
  310. function wc1c_disable_time_limit() {
  311. $disabled_functions = explode(',', ini_get('disable_functions'));
  312. if (!in_array('set_time_limit', $disabled_functions)) set_time_limit(0);
  313. }
  314.  
  315. function wc1c_set_transaction_mode() {
  316. global $wpdb, $wc1c_is_transaction;
  317.  
  318. wc1c_disable_time_limit();
  319.  
  320. register_shutdown_function('wc1c_transaction_shutdown_function');
  321.  
  322. $wpdb->show_errors(false);
  323.  
  324. $wc1c_is_transaction = true;
  325. $wpdb->query("START TRANSACTION");
  326. wc1c_check_wpdb_error();
  327. }
  328.  
  329. function wc1c_transaction_shutdown_function() {
  330. $error = error_get_last();
  331. $is_commit = $error['type'] > E_PARSE;
  332.  
  333. wc1c_wpdb_end($is_commit);
  334. }
  335.  
  336. function wc1c_unpack_files($type) {
  337. $data_dir = WC1C_DATA_DIR . $type;
  338. $zip_paths = glob("$data_dir/*.zip");
  339. if (!$zip_paths) return;
  340.  
  341. $command = sprintf("unzip -qqo -x %s -d %s", implode(' ', array_map('escapeshellarg', $zip_paths)), escapeshellarg($data_dir));
  342. @exec($command, $_, $status);
  343.  
  344. if (@$status !== 0) {
  345. foreach ($zip_paths as $zip_path) {
  346. $zip = new ZipArchive();
  347. $result = $zip->open($zip_path);
  348. if ($result !== true) wc1c_error(sprintf("Failed open archive %s with error code %d", $zip_path, $result));
  349.  
  350. $zip->extractTo($data_dir) or wc1c_error(sprintf("Failed to extract from archive %s", $zip_path));
  351. $zip->close() or wc1c_error(sprintf("Failed to close archive %s", $zip_path));
  352. }
  353. }
  354.  
  355. foreach ($zip_paths as $zip_path) {
  356. unlink($zip_path) or wc1c_error(sprintf("Failed to unlink file %s", $zip_path));
  357. }
  358.  
  359. if ($type == 'catalog') exit("progress");
  360. }
  361.  
  362. function wc1c_xml_start_element_handler($parser, $name, $attrs) {
  363. global $wc1c_namespace, $wc1c_is_full, $wc1c_names, $wc1c_depth;
  364.  
  365. $wc1c_names[] = $name;
  366. $wc1c_depth++;
  367.  
  368. call_user_func("wc1c_{$wc1c_namespace}_start_element_handler", $wc1c_is_full, $wc1c_names, $wc1c_depth, $name, $attrs);
  369. }
  370.  
  371. function wc1c_xml_character_data_handler($parser, $data) {
  372. global $wc1c_namespace, $wc1c_is_full, $wc1c_names, $wc1c_depth;
  373.  
  374. $name = $wc1c_names[$wc1c_depth];
  375.  
  376. call_user_func("wc1c_{$wc1c_namespace}_character_data_handler", $wc1c_is_full, $wc1c_names, $wc1c_depth, $name, $data);
  377. }
  378.  
  379. function wc1c_xml_end_element_handler($parser, $name) {
  380. global $wc1c_namespace, $wc1c_is_full, $wc1c_names, $wc1c_depth;
  381.  
  382. call_user_func("wc1c_{$wc1c_namespace}_end_element_handler", $wc1c_is_full, $wc1c_names, $wc1c_depth, $name);
  383.  
  384. array_pop($wc1c_names);
  385. $wc1c_depth--;
  386. }
  387.  
  388. function wc1c_xml_parse($fp) {
  389. $parser = xml_parser_create();
  390.  
  391. xml_set_element_handler($parser, 'wc1c_xml_start_element_handler', 'wc1c_xml_end_element_handler');
  392. xml_set_character_data_handler($parser, 'wc1c_xml_character_data_handler');
  393.  
  394. $meta_data = stream_get_meta_data($fp);
  395. $filename = basename($meta_data['uri']);
  396.  
  397. while (!($is_final = feof($fp))) {
  398. if (($data = fread($fp, 4096)) === false) wc1c_error(sprintf("Failed to read from file %s", $filename));
  399. if (!xml_parse($parser, $data, $is_final)) {
  400. $message = sprintf("%s in %s on line %d", xml_error_string(xml_get_error_code($parser)), $filename, xml_get_current_line_number($parser));
  401. wc1c_error($message, "XML Error");
  402. }
  403. }
  404.  
  405. xml_parser_free($parser);
  406. }
  407.  
  408. function wc1c_xml_is_full($fp) {
  409. $is_full = null;
  410. while (($buffer = fgets($fp)) !== false) {
  411. if (strpos($buffer, " СодержитТолькоИзменения=") === false && strpos($buffer, "<СодержитТолькоИзменения>") === false) continue;
  412.  
  413. $is_full = strpos($buffer, " СодержитТолькоИзменения=\"false\"") !== false || strpos($buffer, "<СодержитТолькоИзменения>false<") !== false;
  414. break;
  415. }
  416.  
  417. $meta_data = stream_get_meta_data($fp);
  418. $filename = basename($meta_data['uri']);
  419.  
  420. rewind($fp) or wc1c_error(sprintf("Failed to rewind on file %s", $filename));
  421.  
  422. return $is_full;
  423. }
  424.  
  425. function wc1c_mode_import($type, $filename, $namespace = null) {
  426. global $wc1c_namespace, $wc1c_is_full, $wc1c_names, $wc1c_depth;
  427.  
  428. if ($type == 'catalog') wc1c_unpack_files($type);
  429.  
  430. $path = WC1C_DATA_DIR . "$type/$filename";
  431. $fp = fopen($path, 'r') or wc1c_error(sprintf("Failed to open file %s", $filename));
  432. flock($fp, LOCK_EX) or wc1c_error(sprintf("Failed to lock file %s", $filename));
  433.  
  434. wc1c_set_transaction_mode();
  435.  
  436. if (!$namespace) $namespace = preg_replace("/^([a-zA-Z]+).+/", '$1', $filename);
  437. if (!in_array($namespace, array('import', 'offers', 'orders'))) wc1c_error(sprintf("Unknown import file type: %s", $namespace));
  438.  
  439. $wc1c_namespace = $namespace;
  440. $wc1c_is_full = wc1c_xml_is_full($fp);
  441. $wc1c_names = array();
  442. $wc1c_depth = -1;
  443.  
  444. require_once sprintf(WC1C_PLUGIN_DIR . "exchange/%s.php", $namespace);
  445.  
  446. wc1c_xml_parse($fp);
  447.  
  448. flock($fp, LOCK_UN) or wc1c_error(sprintf("Failed to unlock file %s", $filename));
  449. fclose($fp) or wc1c_error(sprintf("Failed to close file %s", $filename));
  450.  
  451. exit("success");
  452. }
  453.  
  454. function wc1c_post_id_by_meta($key, $value) {
  455. global $wpdb;
  456.  
  457. if ($value === null) return;
  458.  
  459. $cache_key = "wc1c_post_id_by_meta-$key-$value";
  460. $post_id = wp_cache_get($cache_key);
  461. if ($post_id === false) {
  462. $post_id = $wpdb->get_var($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta JOIN $wpdb->posts ON post_id = ID WHERE meta_key = %s AND meta_value = %s", $key, $value));
  463. wc1c_check_wpdb_error();
  464.  
  465. if ($post_id) wp_cache_set($cache_key, $post_id);
  466. }
  467.  
  468. return $post_id;
  469. }
  470.  
  471. function wc1c_mode_query($type) {
  472. include WC1C_PLUGIN_DIR . "exchange/query.php";
  473.  
  474. exit;
  475. }
  476.  
  477. function wc1c_mode_success($type) {
  478. include WC1C_PLUGIN_DIR . "exchange/success.php";
  479.  
  480. exit("success");
  481. }
  482.  
  483. function wc1c_exchange() {
  484. wc1c_set_strict_mode();
  485. wc1c_set_output_callback();
  486. wc1c_fix_fastcgi_get();
  487.  
  488. if (empty($_GET['type'])) wc1c_error("No type");
  489. if (empty($_GET['mode'])) wc1c_error("No mode");
  490.  
  491. if ($_GET['mode'] == 'checkauth') {
  492. wc1c_mode_checkauth();
  493. }
  494.  
  495. wc1c_check_auth();
  496.  
  497. define('WC1C_DEBUG', true);
  498.  
  499. if ($_GET['mode'] == 'init') {
  500. wc1c_mode_init($_GET['type']);
  501. }
  502. elseif ($_GET['mode'] == 'file') {
  503. wc1c_mode_file($_GET['type'], $_GET['filename']);
  504. }
  505. elseif ($_GET['mode'] == 'import') {
  506. wc1c_mode_import($_GET['type'], $_GET['filename']);
  507. }
  508. elseif ($_GET['mode'] == 'query') {
  509. wc1c_mode_query($_GET['type']);
  510. }
  511. elseif ($_GET['mode'] == 'success') {
  512. wc1c_mode_success($_GET['type']);
  513. }
  514. else {
  515. wc1c_error("Unknown mode");
  516. }
  517. }
  518.  
  519. function wc1c_template_redirect() {
  520. $value = get_query_var('wc1c');
  521. if (empty($value)) return;
  522.  
  523. if (strpos($value, '?') !== false) {
  524. list($value, $query) = explode('?', $value, 2);
  525. parse_str($query, $query);
  526. $_GET = array_merge($_GET, $query);
  527. }
  528. $_GET['wc1c'] = $value;
  529.  
  530. if ($value == 'exchange') {
  531. wc1c_exchange();
  532. }
  533. elseif ($value == 'clean') {
  534. require_once WC1C_PLUGIN_DIR . "clean.php";
  535. exit;
  536. }
  537. }
  538. add_action('template_redirect', 'wc1c_template_redirect', -10);
Add Comment
Please, Sign In to add comment