site_oueb_2/DBSR-master/src/DBSR_GUI.php

830 lines
33 KiB
PHP
Executable File

<?php
/**
* DBSR_GUI provides functionality for the GUI interface for the DBSR class.
*/
class DBSR_GUI
{
// Constants
/**
* Formatting option: formats as a plain, HTML-safe, string.
*/
const FORMAT_STRING_PLAINHTML = 0;
/**
* Formatting option: formats as a PHP escaped string.
*/
const FORMAT_STRING_PHPESCAPE = 1;
/**
* Formatting option: formats as a hex editor.
*/
const FORMAT_STRING_HEXEDITOR = 2;
// Properties
/**
* Options set during for this DBSR_GUI instance.
* @var array
*/
protected $options = array();
/**
* The maximum step completed succesfully.
* @var integer
*/
protected $maxStep = 0;
// Static methods
/**
* Formats a string according to the given formatting style.
*
* @param string $string The string to be formatted.
* @param int $format One of the DBSR_GUI::FORMAT_STRING_* constants.
* @return string The formatted string.
*/
public static function formatString($string, $format = self::FORMAT_STRING_PLAINHTML)
{
// Check input
if (!is_string($string)) {
return false;
}
// Result string
$result = '';
// Switch format
switch ($format) {
case static::FORMAT_STRING_PHPESCAPE:
$result .= '"';
for ($i = 0; $i < strlen($string); $i++) {
switch ($string[$i]) {
case "\n":
$result .= '\\n';
break;
case "\r":
$result .= '\\r';
break;
case "\t":
$result .= '\\t';
break;
case "\x0B":
$result .= '\\v';
break;
case "\x1B":
$result .= '\\e';
break;
case "\x0C":
$result .= '\\f';
break;
case '\\':
$result .= '\\\\';
break;
case "\"":
$result .= '\\"';
break;
default:
$ord = ord($string[$i]);
if ($ord >= 32 && $ord < 127) {
$result .= htmlspecialchars($string[$i]);
} else {
$result .= '\\x' . str_pad(strtoupper(dechex($ord)), 2, '0', STR_PAD_LEFT);
}
break;
}
}
$result .= '"';
break;
case static::FORMAT_STRING_HEXEDITOR:
// Padding for non-visible characters
static $pad = '.';
// Calculate strst padding string
static $from = '';
static $to = '';
if ($from === '') {
for ($i = 0; $i <= 0xFF; $i++) {
$from .= chr($i);
$to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
}
}
// Number of bytes per line
$width = max(min(strlen($string), strlen($string) > 48 ? 16 : 8), 1);
$hex = str_split(bin2hex($string), $width * 2);
$chars = str_split(strtr($string, $from, $to), $width);
$offset = 0;
$leftpad = strlen((string) strlen($string));
foreach ($hex as $i => $line) {
$result .= '<b>';
$result .= str_pad($offset, $leftpad, ' ', STR_PAD_LEFT);
$result .= '</b> : ';
$result .= str_pad(implode(' ', str_split($line, 2)), 3 * $width, ' ', STR_PAD_RIGHT);
$result .= ' [<i>';
$result .= htmlspecialchars(str_pad($chars[$i], $width, ' ', STR_PAD_RIGHT));
$result .= '</i>]<br />' . "\n";
$offset += $width;
}
break;
case static::FORMAT_STRING_PLAINHTML:
default:
$result = htmlspecialchars($string);
break;
}
// Return the result
return $result;
}
/**
* Returns the levenshtein distance between two strings.
*
* Though having the same complexity (O(n*m)) as the
* build-in PHP function it's implemented a lot more
* efficiently. The build-in version of PHP uses a m*n
* matrix to calculate the distance, resulting in a huge
* memory hog (which is why the maximum string length is
* limited to 255 chars). This version uses a bottom-up
* dynamic programming approach which limits the matrix
* size to 2*n, speeding up the memory allocation and
* allowing for longer input strings.
*
* @param string $str1 The first string to be compared.
* @param string $str2 The seconds string to be compared.
* @return integer The levenshtein distance between the two strings.
*/
public static function levenshtein($str1, $str2)
{
// Save string lengths
$len1 = strlen($str1);
$len2 = strlen($str2);
// Strip common prefix
$i = 0;
do {
if (substr($str1, $i, 1) != substr($str2, $i, 1)) {
break;
}
$i++;
$len1--;
$len2--;
} while ($len1 > 0 && $len2 > 0);
if ($i > 0) {
$str1 = substr($str1, $i);
$str2 = substr($str2, $i);
}
// Strip common suffix
$i = 0;
do {
if (substr($str1, $len1 - 1, 1) != substr($str2, $len2-1, 1)) {
break;
}
$i++;
$len1--;
$len2--;
} while ($len1 > 0 && $len2 > 0);
if ($i > 0) {
$str1 = substr($str1, 0, $len1);
$str2 = substr($str2, 0, $len2);
}
// If either of the strings has length 0; return the length of the other string
if ($len1 == 0) {
return $len2;
}
if ($len2 == 0) {
return $len1;
}
// Create the arrays
$v0 = range(0, $len1);
$v1 = array();
// The actual algorithm
for ($i = 1; $i <= $len2; $i++) {
$v1[0] = $i;
$str2j = substr($str2, $i - 1, 1);
for ($j = 1; $j <= $len1; $j++) {
$cost = (substr($str1, $j - 1, 1) == $str2j) ? 0 : 1;
$m_min = $v0[$j] + 1;
$b = $v1[$j - 1] + 1;
$c = $v0[$j - 1] + $cost;
if ($b < $m_min) {
$m_min = $b;
}
if ($c < $m_min) {
$m_min = $c;
}
$v1[$j] = $m_min;
}
$vTmp = $v0;
$v0 = $v1;
$v1 = $vTmp;
}
return $v0[$len1];
}
/**
* Get the resource file content.
* @param string $resource The filename of the resource.
* @return mixed The content of the file as string, or FALSE if unsuccessful.
*/
public static function getResource($resource)
{
// Check if a compiled version is available
if (class_exists('DBSR_GUI_Resources', false)) {
return DBSR_GUI_Resources::getResource($resource);
}
// No directory traversing
if (preg_match('/\\.\\.[\\/\\\\]/', $resource)) {
return false;
}
// Correct resource path separators
$resource = str_replace('/', \DIRECTORY_SEPARATOR, $resource);
// Add path to filename
$resource = __DIR__ . \DIRECTORY_SEPARATOR . 'DBSR_GUI_Resources' . \DIRECTORY_SEPARATOR . $resource;
// Does the file exists
if (!is_readable($resource) || !is_file($resource)) {
return false;
}
// Return the content
return @file_get_contents($resource);
}
/**
* Returns a MySQL PDO instance according to the given parameters.
*
* @param string $db_host
* @param integer $db_port
* @param string $db_user
* @param string $db_pass
* @param string $db_name
* @param sttring $db_char
*
* @throws PDOException
*/
public static function getPDO($db_host = null, $db_port = null, $db_user = null, $db_pass = null, $db_name = null, $db_char = null)
{
// Prepare the DSN and PDO options array
$pdo_options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
$dsn = 'mysql:';
if (!empty($db_host)) {
$dsn .= 'host=' . $db_host;
if (!empty($db_port)) {
$dsn .= ':' . $db_port;
}
$dsn .= ';';
}
if (!empty($db_name)) {
$dsn .= 'dbname=' . $db_name . ';';
}
if (!empty($db_char)) {
$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $db_char;
$dsn .= 'charset=' . $db_char . ';';
}
// Try connecting
return new PDO($dsn, $db_user, $db_pass, $pdo_options);
}
/**
* Searches available configuration files for database configuration.
*
* @return array All values detected from configuration files.
*/
public static function detectConfig()
{
// Variables to retrieve
$variables = array(
'db_host' => 'DB_HOST',
'db_user' => 'DB_USER',
'db_pass' => 'DB_PASSWORD',
'db_name' => 'DB_NAME',
'db_char' => 'DB_CHARSET',
'wp_prefix' => '$table_prefix',
);
// Configfiles, will be seached in order
$configfiles = array(
'database.conf.php',
'wp-config.php',
'..' . \DIRECTORY_SEPARATOR . 'database.conf.php',
'..' . \DIRECTORY_SEPARATOR . 'wp-config.php',
);
// Result array
$detected = array();
// For each configfile
foreach ($configfiles as $configfile) {
if (count($variables) > 0) {
// Load it
if (file_exists($configfile) && ($config = file_get_contents($configfile))) {
// By default, the entire file is the block
$config_blocks = array($config);
// Try to determine if a specific block contains our needs
$regex_block = '/(?:[iI][fF]\s*\(\s*[sS][tT][rR][iI]?(?:[sS][tT][rR]|[pP][oO][sS])\s*\(\s*\$_SERVER\s*\[\s*[\'"]SERVER_NAME[\'"]\s*\]\s*,\s*[\'"]((?:[^\'"]|\\\\\'|\\\\")*)[\'"]\s*\)[^\)]*\)|[eE][lL][sS][eE])\s*(\{(?:[^\{\}]*|\2)*\})/ms';
if (preg_match_all($regex_block, $config, $matches, PREG_SET_ORDER)) {
// For each subset
foreach ($matches as &$match) {
// Discard the complete match
array_shift($match);
// Check if the detected name matches agains the current server name
if ($match[0] == '' || stripos($_SERVER['SERVER_NAME'], $match[0]) !== false) {
// Add this block as prefered block
array_unshift($config_blocks, $match[1]);
break;
}
}
}
// Loop through each block
foreach ($config_blocks as $config_block) {
if (count($variables) > 0) {
// Search for each variable and unset it if found
foreach ($variables as $varname => $variable) {
if (count($variables) > 0) {
// Is this a define or a simple variable?
if ($variable[0] == '$') {
$regex_variable = '/' . preg_quote($variable) . '\s*=\s*[\'"](([^\'"]|\\\\\'|\\\\")*)[\'"]\s*;/';
} else {
$regex_variable = '/[dD][eE][fF][iI][nN][eE]\s*\(\s*[\'"]' . preg_quote($variable) . '[\'"]\s*,\s*[\'"](([^\'"]|\\\\\'|\\\\")*)[\'"]\s*\)\s*;/';
}
// Find the variable
if (preg_match($regex_variable, $config_block, $matches)) {
$detected[$varname] = $matches[1];
unset($variables[$varname]);
}
}
}
}
}
}
}
}
// Special case: extract the port number from the hostname
if (isset($detected['db_host']) && preg_match('/^(.*):(\d+)$/', $detected['db_host'], $matches)) {
$detected['db_host'] = $matches[1];
$detected['db_port'] = $matches[2];
}
if (isset($detected['db_host']) && !isset($detected['db_port'])) {
$detected['db_port'] = null;
}
// Return the results
return $detected;
}
/**
* Provides auto-complete hints for a given field.
*
* @param string $id The id of the field.
* @param string $term The currently typed term.
* @param array $arguments Other arguments currently filled in the form.
* @return array The hints, in order of likelyhood.
*/
public static function autoComplete($id, $term, $arguments)
{
switch ($id) {
case 'db_name':
try {
// Check if we can connect to the database with the given arguments
$pdo = static::getPDO(@$arguments['db_host'], @$arguments['db_port'], @$arguments['db_user'], @$arguments['db_pass'], null, null);
// Fetch a list of databases
$result = $pdo->query('SHOW DATABASES;', PDO::FETCH_COLUMN, 0);
// Filter matching databases
$databases = array();
foreach ($result as $r) {
if (strtolower(substr($r, 0, strlen($term))) == strtolower($term)) {
$databases[] = $r;
}
}
// Return result
return $databases;
} catch (Exception $e) {
// Error: return nothing
return array();
}
break;
case 'db_char':
try {
// Check if we can connect to the database with the given arguments
$pdo = static::getPDO(@$arguments['db_host'], @$arguments['db_port'], @$arguments['db_user'], @$arguments['db_pass'], null, null);
// Fetch a list of databases
$result = $pdo->query('SHOW CHARACTER SET;', PDO::FETCH_COLUMN, 0);
// Filter matching databases
$charsets = array();
foreach ($result as $r) {
if (strtolower(substr($r, 0, strlen($term))) == strtolower($term)) {
$charsets[] = $r;
}
}
// Return result
return $charsets;
} catch (Exception $e) {
// Error: return nothing
return array();
}
break;
default:
// Unknown field, return nothing
return array();
}
}
// Methods
/**
* Constructor: resets the step for every new instance.
*/
public function __construct()
{
$this->resetStep();
}
/**
* Validates the AJAX requests and returns a response for the GUI.
*
* @param integer $step The step to validate.
* @param array $arguments The arguments for validating this step.
*
* @return array The response to send to the GUI.
*/
public function completeStep($step, $arguments)
{
if ($step > $this->maxStep + 1) {
return array(
'valid' => false,
'error' => 'First complete step ' . ($this->maxStep + 1) . '!'
);
}
switch ($step) {
case 1:
// Validate the database connection information
if (!isset($arguments['db_host']) || empty($arguments['db_host'])) {
return array(
'valid' => false,
'error' => 'Please enter a hostname!',
);
}
if (!isset($arguments['db_name']) || empty($arguments['db_name'])) {
return array(
'valid' => false,
'error' => 'Please enter a database name!',
);
}
if (!isset($arguments['db_char']) || empty($arguments['db_char'])) {
return array(
'valid' => false,
'error' => 'Please enter a character set!',
);
}
// Try to connect
try {
$pdo = static::getPDO(@$arguments['db_host'], @$arguments['db_port'], @$arguments['db_user'], @$arguments['db_pass'], @$arguments['db_name'], @$arguments['db_char']);
$pdo->query('SHOW TABLES;');
} catch (Exception $e) {
return array(
'valid' => false,
'error' => $e->getMessage(),
);
}
// Save maximum step
$this->maxStep = $step;
// Save options
$this->options['db_host'] = @$arguments['db_host'];
$this->options['db_port'] = @$arguments['db_port'];
$this->options['db_user'] = @$arguments['db_user'];
$this->options['db_pass'] = @$arguments['db_pass'];
$this->options['db_name'] = @$arguments['db_name'];
$this->options['db_char'] = @$arguments['db_char'];
// Return data for the GUI
return array(
'valid' => true,
'data' => array(
'db_host' => @$arguments['db_host'],
'db_port' => @$arguments['db_port'],
'db_user' => @$arguments['db_user'],
'db_pass' => @$arguments['db_pass'],
'db_name' => @$arguments['db_name'],
'db_char' => @$arguments['db_char'],
),
);
case 2:
// Check the search- and replace-values
if (!is_array(@$arguments['search']) || count(@$arguments['search']) == 0) {
return array(
'valid' => false,
'error' => 'Missing search values!',
);
}
if (!is_array(@$arguments['replace']) || count(@$arguments['replace']) == 0 || count(@$arguments['search']) != count(@$arguments['replace'])) {
return array(
'valid' => false,
'error' => 'Missing replace values!',
);
}
// Clean indices
$arguments['search'] = array_values(@$arguments['search']);
$arguments['replace'] = array_values(@$arguments['replace']);
// Parse escaped values
$escapedvalues = isset($arguments['escapedvalues']) && strtolower($arguments['escapedvalues']) == 'on';
if ($escapedvalues) {
for ($i = 0; $i < count($arguments['search']); $i++) {
$arguments['search'][$i] = stripcslashes($arguments['search'][$i]);
$arguments['replace'][$i] = stripcslashes($arguments['replace'][$i]);
}
}
// Remove all identical values
for ($i = 0; $i < count($arguments['search']); $i++) {
if (empty($arguments['search'][$i])) {
return array(
'valid' => false,
'error' => 'Search-value cannot be empty!',
);
}
if ($arguments['search'][$i] === $arguments['replace'][$i]) {
array_splice($arguments['search'], $i, 1);
array_splice($arguments['replace'], $i, 1);
$i--;
}
}
// Check the length again
if (count($arguments['search']) == 0) {
return array(
'valid' => false,
'error' => 'All given search- and replace-values are identical!',
);
}
// Save maximum step
$this->maxStep = $step;
// Save options
$this->options['search'] = $arguments['search'];
$this->options['replace'] = $arguments['replace'];
$this->options['escapedvalues'] = $escapedvalues;
$this->options['dbsr_caseinsensitive'] = isset($arguments['dbsr_caseinsensitive']) && strtolower($arguments['dbsr_caseinsensitive']) == 'on';
$this->options['dbsr_extensivesearch'] = isset($arguments['dbsr_extensivesearch']) && strtolower($arguments['dbsr_extensivesearch']) == 'on';
// Return data for the GUI
$values = array();
foreach (array(
'values_raw' => static::FORMAT_STRING_PLAINHTML,
'values_escaped' => static::FORMAT_STRING_PHPESCAPE,
'values_hex' => static::FORMAT_STRING_HEXEDITOR,
) as $name => $type) {
$values[$name] = '';
for ($i = 0; $i < count($arguments['search']); $i++) {
$values[$name] .= '<tr><td><code>';
$values[$name] .= static::formatString($arguments['search'][$i], $type);
$values[$name] .= '</code></td><td><code>';
$values[$name] .= static::formatString($arguments['replace'][$i], $type);
$values[$name] .= '</code></td></tr>';
}
}
// Determine suggestions
$suggestions = $this->getSuggestions();
if (count($suggestions) > 0) {
$values['suggestions'] = '<p>' . implode('</p><p>', $suggestions) . '</p>';
} else {
$values['suggestions'] = '';
}
return array(
'valid' => true,
'data' => array(
'escapedvalues' => $this->options['escapedvalues'],
'dbsr_caseinsensitive' => $this->options['dbsr_caseinsensitive'],
'dbsr_extensivesearch' => $this->options['dbsr_extensivesearch'],
),
'html' => $values,
);
case 3:
if (!isset($arguments['confirmed']) || strtolower($arguments['confirmed']) != 'on') {
return array(
'valid' => false,
'error' => 'Please confirm the data stated above is correct!',
);
}
// Run DBSR
try {
// Build a PDO instance
$pdo = static::getPDO($this->options['db_host'], $this->options['db_port'], $this->options['db_user'], $this->options['db_pass'], $this->options['db_name'], $this->options['db_char']);
// Build a DBSR instance
$dbsr = new DBSR($pdo);
// Set some DBSR options
$dbsr->setOption(DBSR::OPTION_CASE_INSENSITIVE, $this->options['dbsr_caseinsensitive']);
$dbsr->setOption(DBSR::OPTION_EXTENSIVE_SEARCH, $this->options['dbsr_extensivesearch']);
// Set the search- and replace-values
$dbsr->setValues($this->options['search'], $this->options['replace']);
// Reset the maximum step
$this->resetStep();
// Execute DBSR
$result = $dbsr->exec();
// Return the result
return array(
'valid' => true,
'data' => array(
'result' => $result,
),
);
} catch (Exception $e) {
// Return the error
return array(
'valid' => true,
'error' => $e->getMessage(),
'errorCode' => $e->getCode(),
'errorFile' => $e->getFile(),
'errorLine' => $e->getLine(),
'errorTrace' => $e->getTrace(),
);
}
default:
return array(
'valid' => false,
'error' => 'Unknown step!',
);
}
}
/**
* Resets the maximum step.
*/
public function resetStep()
{
$this->maxStep = 0;
}
/**
* Provides simple suggestions for common mistakes based on the search- and replace-values.
*/
protected function getSuggestions()
{
// Array with all our messages
$messages = array();
// Build a PDO instance
$pdo = static::getPDO($this->options['db_host'], $this->options['db_port'], $this->options['db_user'], $this->options['db_pass'], $this->options['db_name'], $this->options['db_char']);
// Try to determine the WP prefix
$config = static::detectConfig();
$wp_prefix = !empty($config['wp_prefix']) ? $config['wp_prefix'] : 'wp_';
// Define the regex for matching domain names
$domain_regex = '/^https?:\\/\\/([a-z0-9](?:[-a-z0-9]*[a-z0-9])?(?:\\.[a-z0-9](?:[-a-z0-9]*[a-z0-9])?)*)\\/?$/iS';
// Switches to prevent double messages
$domain = false;
$specialchars = false;
$newlines = false;
// Get some of the server info to use a spelling probes
$spelling_probes = array(
$_SERVER['SERVER_NAME'], // current server name
__DIR__, // current directory
);
// Find WP siteurl
try {
$result = $pdo->query('SELECT `option_value` FROM `' . $wp_prefix . 'options` WHERE `option_name` = \'siteurl\'', PDO::FETCH_COLUMN, 0)->fetch();
if (!empty($result)) {
// Save the domain name
$result = preg_replace($domain_regex, '$1', $result);
if (!in_array($result, $spelling_probes)) {
$spelling_probes[] = $result;
}
// WWW-less domain name
$result = preg_replace('/^www\\.(.+)$/i', '$1', $result);
if (!in_array($result, $spelling_probes)) {
$spelling_probes[] = $result;
}
}
} catch (PDOException $e) {
// Ignore exceptions when retrieving probes
}
// Find WP path
try {
$result = $pdo->query('SELECT `option_value` FROM `' . $wp_prefix . 'options` WHERE `option_name` = \'recently_edited\'', PDO::FETCH_COLUMN, 0)->fetch();
if (!empty($result)) {
$result = preg_replace('/^(\\/.*)\\/wp-content\\/.*$/i', '$1', preg_replace('/^.*s:\d+:"([^"]+)";.*$/i', '$1', $result));
if (strpos($result, '"') === false && !in_array($result, $spelling_probes)) {
$spelling_probes[] = $result;
}
}
} catch (PDOException $e) {
// Ignore exceptions when retrieving probes
}
// Loop over all values
for ($i = 0; $i < count($this->options['search']); $i++) {
if (!$domain && preg_match($domain_regex, $this->options['search'][$i]) && preg_match($domain_regex, $this->options['replace'][$i])) {
// Domain name
$domain = true;
$messages[] = 'It seems you\'re going to replace a domain name.<br />Be aware that it is recommended to omit any pre- and suffixes (such as <code>http://</code> or a trailing slash) to ensure <b>all</b> occurences of the domain name will be replaced.';
} else {
// Spelling
foreach ($spelling_probes as $probe) {
if ($this->options['dbsr_caseinsensitive']) {
if (strtolower($this->options['search'][$i]) != strtolower($probe) && static::levenshtein(strtolower($this->options['search'][$i]), strtolower($probe)) < 4) {
$messages[] = 'I suspect you might have made a typo in the ' . ($i + 1) . 'th search-value. Did you mean "<code>' . htmlspecialchars($probe) . '</code>"?';
}
if (strtolower($this->options['replace'][$i]) != strtolower($probe) && static::levenshtein(strtolower($this->options['replace'][$i]), strtolower($probe)) < 4) {
$messages[] = 'I suspect you might have made a typo in the ' . ($i + 1) . 'th replace-value. Did you mean "<code>' . htmlspecialchars($probe) . '</code>"?';
}
} else {
if ($this->options['search'][$i] != $probe && static::levenshtein($this->options['search'][$i], $probe) < 4) {
$messages[] = 'I suspect you might have made a typo in the ' . ($i + 1) . 'th search-value. Did you mean "<code>' . htmlspecialchars($probe) . '</code>"?';
}
if ($this->options['replace'][$i] != $probe && static::levenshtein($this->options['replace'][$i], $probe) < 4) {
$messages[] = 'I suspect you might have made a typo in the ' . ($i + 1) . 'th replace-value. Did you mean "<code>' . htmlspecialchars($probe) . '</code>"?';
}
}
}
}
// Non-ASCII characters
for ($j = 0; $j < strlen($this->options['search'][$i]) && !$specialchars; $j++) {
$ord = ord($this->options['search'][$i][$j]);
if ($ord < 9 || ($ord > 10 && $ord < 13) || ($ord > 13 && $ord < 32) || $ord >= 127) {
$messages[] = 'There are some non-ASCII characters in your search value(s).<br />Be aware that DBSR does not provide any transliteration support, thus leaving character encoding entirely up to your browser and the database. Be sure to set the correct charset, and optionally use the "extended search" option of DBSR.';
$specialchars = true;
}
}
for ($j = 0; $j < strlen($this->options['replace'][$i]) && !$specialchars; $j++) {
$ord = ord($this->options['replace'][$i][$j]);
if ($ord < 9 || ($ord > 10 && $ord < 13) || ($ord > 13 && $ord < 32) || $ord >= 127) {
$messages[] = 'There are some non-ASCII characters in your replace value(s).<br />Be aware that DBSR does not provide any transliteration support, thus leaving character encoding entirely up to your browser and the database. Be sure to set the correct charset, and optionally use the "extended search" option of DBSR.';
$specialchars = true;
}
}
// Newlines
if (!$newlines && !$this->options['escapedvalues']) {
if (strpos($this->options['search'][$i], "\n") !== false) {
$newlines = true;
$messages[] = 'You\'ve used ' . (strpos($_SESSION['search'][$i], "\r\n") !== false ? 'Windows-style ("<code>\r\n</code>")' : 'Unix-style ("<code>\n</code>")') . ' line endings. If this is not what you want, go back and change it.';
}
if (!$newlines && strpos($this->options['replace'][$i], "\n") !== false) {
$newlines = true;
$messages[] = 'You\'ve used ' . (strpos($_SESSION['replace'][$i], "\r\n") !== false ? 'Windows-style ("<code>\r\n</code>")' : 'Unix-style ("<code>\n</code>")') . ' line endings. If this is not what you want, go back and change it.';
}
}
}
// Return the messages
return $messages;
}
}