importError) { \lws_admin_delete_notice('lws_ap_page'); \lws_admin_add_notice_once('woorewards-lite'.'-error', __("Import Error", 'woorewards-lite') . '
' . $this->importError, array('level'=>'error')); } return $value; } function importFormAttributes($attrs) { $attrs['enctype']='multipart/form-data'; return $attrs; } /** @return $oldValue cause WP dont go further with that option. */ function import($value, $oldValue, $option) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified by WP settings API if( !(isset($_POST['lws_wre_points_action']) && 'import' == \sanitize_text_field(\wp_unslash($_POST['lws_wre_points_action']))) ) return $oldValue; // we only want a import button click, not a page save if( !\current_user_can('manage_options') ) { $this->importError = __("You are not allowed to do that", 'woorewards-lite'); return $oldValue; } $stack = isset($_REQUEST['woorewards-lite' . '_default_pool']) ? \sanitize_key(\wp_unslash($_REQUEST['woorewards-lite' . '_default_pool'])) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce verified by WP settings API if( $stack ) { if (\class_exists('\LWS\WOOREWARDS\PRO\Core\Pool')) { $pool = \LWS\WOOREWARDS\PRO\Core\Pool::getOrLoad($stack, false); } else { $pool = \apply_filters('lws_woorewards_get_pools_by_args', false, array( 'system' => $stack, 'force' => true, )); if ($pool) $pool = $pool->last(); } if ($pool) $stack = $pool->getStackId(); } else { $this->importError = __("Missing destination loyalty system.", 'woorewards-lite'); return $oldValue; } $replace = true; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified by WP settings API if (isset($_POST['woorewards-lite' . '_behavior']) && 'add' == \sanitize_text_field(\wp_unslash($_POST['woorewards-lite' . '_behavior']))) $replace = false; $key = 'woorewards-lite' . '_import_file'; if( isset($_FILES[$key]) && !empty($_FILES[$key]) && !empty($_FILES[$key]['tmp_name']) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified by WP settings API { $filename = \sanitize_file_name(\wp_unslash($_FILES[$key]['name'])); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.NonceVerification.Missing if( !empty($_FILES[$key]['error']) ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.NonceVerification.Missing { /* translators: %s: filename */ $this->importError = sprintf(__("Error during upload of file %s, perhaps the file is too big. You can try to split it up or increase max allowed file size on your server.", 'woorewards-lite'), $filename); } else { if( \sanitize_mime_type(\wp_unslash($_FILES[$key]['type'])) != 'application/json' ) // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated { $this->importError = __("Expects a JSON file.", 'woorewards-lite'); } else try { $reason = isset($_POST['woorewards-lite' . '_import_reason']) ? \sanitize_text_field(\wp_unslash($_POST['woorewards-lite' . '_import_reason'])) : false; // phpcs:ignore WordPress.Security.NonceVerification.Missing $filename_esc = \wp_unslash($_FILES[$key]['tmp_name']); $json = (array)@json_decode(@file_get_contents($filename_esc), true); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- reading uploaded tmp file $this->importJSON($json, $stack, $replace, $reason); } catch(\Exception $e) { $this->importError = __("The file cannot be read or format is invalid. Expects JSON content.", 'woorewards-lite'); } \wp_delete_file(\sanitize_file_name(\wp_unslash($_FILES[$key]['tmp_name']))); // phpcs:ignore WordPress.Security.NonceVerification.Missing } } else $this->importError = __("Please, select a file to import.", 'woorewards-lite'); return $oldValue; } /** @param $replace (bool) if false, points are added. */ protected function importJSON($json, $stack, $replace=true, $reason=false) { $affected = 0; $unknown = array(); $ignored = array(); global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- dynamic table name from wpdb property $table = $wpdb->get_var("SHOW TABLES LIKE '{$wpdb->lwsWooRewardsHistoric}'"); \set_time_limit(0); // phpcs:ignore Generic.PHP.ForbiddenFunctions.Found, Squiz.PHP.DiscouragedFunctions.Discouraged -- long import needs extended time if (!$reason) $reason = _x("Import", "History line", 'woorewards-lite'); $metakey = 'lws_wre_points_'.$stack; $blogId = \get_current_blog_id(); $multiply = floatval(str_replace(',', '.', \get_option('woorewards-lite'.'_multiply', 1))); if( !$multiply ) $multiply = 1; $round = \get_option('woorewards-lite'.'_rounding', 'floor'); foreach( $json as $row ) { if( isset($row['email']) && isset($row['points']) ) { $email = \trim($row['email']); if (!$email) continue; $points = floatval($row['points']) * $multiply; if( 'floor' == $round ) $points = floor($points); else if( 'ceil' == $round ) $points = ceil($points); else if( 'half_up' == $round ) $points = round($points, 0, PHP_ROUND_HALF_UP); else if( 'half_down' == $round ) $points = round($points, 0, PHP_ROUND_HALF_DOWN); if( $user = \get_user_by('email', $email) ) { $oldPts = 0; if ($replace) { \update_user_meta($user->ID, $metakey, $points); } else { $oldPts = \intval(\get_user_meta($user->ID, $metakey, true)); \update_user_meta($user->ID, $metakey, $points + $oldPts); } ++$affected; if( $table ) { $values = array( 'user_id' => $user->ID, 'stack' => $stack, 'new_total' => $points, 'commentar' => $reason, 'origin' => 'migration-tool', 'blog_id' => $blogId, ); $formats = array('%d', '%s', '%d', '%s', '%s'); if (!$replace) { $values['new_total'] += $oldPts; $values['points_moved'] = $points; $formats[] = '%d'; } $wpdb->insert($table, $values, $formats); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery } } else $unknown[$email] = $email; } else { $this->importError = __("Invalid data: ", 'woorewards-lite') . htmlentities(json_encode($row)); return false; } } /* translators: %d: number of items */ \lws_admin_add_notice_once('woorewards-lite'.'-notice', sprintf(__("Import done. %d items affected.", 'woorewards-lite'), $affected), array('level'=>'success')); if( !empty($unknown) ) { $warning = __("The following users cannot be found. Points ignored.", 'woorewards-lite'); $unknown = htmlentities(implode("\n", $unknown)); $warning .= ""; \lws_admin_add_notice_once('woorewards-lite'.'-warning', $warning, array('level'=>'warning')); } if( !empty($ignored) ) { $warning = __("The following point pools cannot be found. Points ignored.", 'woorewards-lite'); $ignored = htmlentities(implode("\n", $ignored)); $warning .= ""; \lws_admin_add_notice_once('woorewards-lite'.'-warning2', $warning, array('level'=>'warning')); } return true; } function exportWR() { if (!\wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['lws_btn_nonce'] ?? '')), 'woorewards-lite' . '-export-wr')) { \wp_die('forbidden', 403); } if( !\current_user_can('manage_options') ) \wp_die('forbidden', 403); $poolKey = 'woorewards-lite' . '_from_pool'; $poolName = isset($_REQUEST[$poolKey]) ? \sanitize_text_field(\wp_unslash($_REQUEST[$poolKey])) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if( $poolName ) { require_once LWS_WOOREWARDS_INCLUDES . '/pointsflow/exportmethod.php'; require_once LWS_WOOREWARDS_INCLUDES . '/pointsflow/methods/woorewards.php'; $method = new \LWS\WOOREWARDS\PointsFlow\Methods\WooRewards(); $this->sendJSONPoints($method, $poolName, $poolName); } \wp_die('Bad request', 400); } function exportPoints() { if (!\wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['lws_btn_nonce'] ?? '')), 'woorewards-lite' . '-export-points')) { \wp_die('forbidden', 403); } if( !\current_user_can('manage_options') ) \wp_die('forbidden', 403); $metaPost = 'woorewards-lite' . '_from_meta'; $metaKey = isset($_REQUEST[$metaPost]) ? \sanitize_text_field(\wp_unslash($_REQUEST[$metaPost])) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $argPost = 'woorewards-lite' . '_with_arg'; $argValue = isset($_REQUEST[$argPost]) ? \sanitize_text_field(\wp_unslash($_REQUEST[$argPost])) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if( !$metaKey || trim($metaKey) == '—' ) \wp_die('Bad request', 400); if( !$argValue || trim($argValue) == '—' ) $argValue = false; require_once LWS_WOOREWARDS_INCLUDES . '/pointsflow/exportmethods.php'; $method = \LWS\WOOREWARDS\PointsFlow\ExportMethods::get($metaKey); if( !$method ) \wp_die('Not Implemented', 501); if( !$method->instance->supportFreeArgs() && ($args = $method->instance->getArgs()) ) { if( !in_array($argValue, array_keys($args)) ) \wp_die('Invalid Export argument for ' . esc_html($method->instance->getTitle()), 418); } $this->sendJSONPoints($method->instance, $metaKey, $argValue); } private function sendJSONPoints($method, $value, $arg=false) { $json = $method->export($value, $arg); \array_walk($json, function(&$row){ if (null === $row->points || !\strlen($row->points)) $row->points = 0; }); $base = str_replace(' ', '-', \get_bloginfo('name')); $origin = \remove_accents(strtolower($method->getTitle())); $origin = preg_replace(array('/\s*-+\s*/', '/[\s_]+/'), array('-', '_'), $origin); $origin = \sanitize_key($origin); $date = \gmdate('Ymd'); $arg = \sanitize_key($arg); $filename = \esc_attr("{$base}-{$origin}-{$arg}-{$date}.json"); header("Content-disposition: attachment; filename=\"{$filename}\""); // force download \wp_send_json($json); } }