diff --git a/src/Forms/GridField/GridFieldLevelup.php b/src/Forms/GridField/GridFieldLevelup.php index d16d41a88..90a2f0003 100644 --- a/src/Forms/GridField/GridFieldLevelup.php +++ b/src/Forms/GridField/GridFieldLevelup.php @@ -86,9 +86,9 @@ class GridFieldLevelup implements GridField_HTMLProvider )); $template = SSViewer::get_templates_by_class($this, '', __CLASS__); - return array( + return [ 'before' => $forTemplate->renderWith($template), - ); + ]; } public function setAttributes($attrs) diff --git a/src/ORM/Connect/DBSchemaManager.php b/src/ORM/Connect/DBSchemaManager.php index 4a158dcdc..61d38ab30 100644 --- a/src/ORM/Connect/DBSchemaManager.php +++ b/src/ORM/Connect/DBSchemaManager.php @@ -2,12 +2,13 @@ namespace SilverStripe\ORM\Connect; +use Exception; use SilverStripe\Control\Director; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Injector\Injector; -use SilverStripe\ORM\FieldType\DBPrimaryKey; +use SilverStripe\ORM\DB; use SilverStripe\ORM\FieldType\DBField; -use Exception; +use SilverStripe\ORM\FieldType\DBPrimaryKey; /** * Represents and handles all schema management for a database @@ -710,33 +711,33 @@ MESSAGE } elseif ($fieldValue != $specValue) { // If enums/sets are being modified, then we need to fix existing data in the table. // Update any records where the enum is set to a legacy value to be set to the default. - foreach (array('enum', 'set') as $enumtype) { - if (preg_match("/^$enumtype/i", $specValue)) { - $newStr = preg_replace("/(^$enumtype\\s*\\(')|('\\).*)/i", "", $spec_orig); - $new = preg_split("/'\\s*,\\s*'/", $newStr); + $enumValuesExpr = "/^(enum|set)\\s*\\(['\"](?[^'\"]+)['\"]\\).*/i"; + if (preg_match($enumValuesExpr, $specValue, $specMatches) + && preg_match($enumValuesExpr, $spec_orig, $oldMatches) + ) { + $new = preg_split("/'\\s*,\\s*'/", $specMatches['values']); + $old = preg_split("/'\\s*,\\s*'/", $oldMatches['values']); - $oldStr = preg_replace("/(^$enumtype\\s*\\(')|('\\).*)/i", "", $fieldValue); - $old = preg_split("/'\\s*,\\s*'/", $oldStr); - - $holder = array(); - foreach ($old as $check) { - if (!in_array($check, $new)) { - $holder[] = $check; - } + $holder = array(); + foreach ($old as $check) { + if (!in_array($check, $new)) { + $holder[] = $check; } - if (count($holder)) { + } + + if (count($holder)) { + // Get default pre-escaped for SQL. We just use this directly, as we don't have a real way to + // de-encode SQL values $default = explode('default ', $spec_orig); - $default = $default[1]; - $query = "UPDATE \"$table\" SET $field=$default WHERE $field IN ("; - for ($i = 0; $i + 1 < count($holder); $i++) { - $query .= "'{$holder[$i]}', "; - } - $query .= "'{$holder[$i]}')"; - $this->query($query); + $defaultSQL = isset($default[1]) ? $default[1] : 'NULL'; + // Reset to default any value in that is in the old enum, but not the new one + $placeholders = DB::placeholders($holder); + $query = "UPDATE \"{$table}\" SET \"{$field}\" = {$defaultSQL} WHERE \"{$field}\" IN ({$placeholders})"; + $this->preparedQuery($query, $holder); $amount = $this->database->affectedRows(); - $this->alterationMessage("Changed $amount rows to default value of field $field" - . " (Value: $default)"); - } + $this->alterationMessage( + "Changed $amount rows to default value of field $field (Value: $defaultSQL)" + ); } } $this->transAlterField($table, $field, $spec_orig); diff --git a/src/includes/constants.php b/src/includes/constants.php index a619db5f2..e4e300ffa 100644 --- a/src/includes/constants.php +++ b/src/includes/constants.php @@ -41,11 +41,12 @@ if (!defined('BASE_PATH')) { define('BASE_PATH', call_user_func(function () { // Determine BASE_PATH based on the composer autoloader foreach (debug_backtrace() as $backtraceItem) { - if (isset($backtraceItem['file']) && preg_match( - '#^(?.*)(/|\\\\)vendor(/|\\\\)composer(/|\\\\)autoload_real.php#', - $backtraceItem['file'], - $matches - )) { + if (isset($backtraceItem['file']) + && preg_match( + '#^(?.*)(/|\\\\)vendor(/|\\\\)composer(/|\\\\)autoload_real.php#', + $backtraceItem['file'], + $matches + )) { return realpath($matches['base']) ?: DIRECTORY_SEPARATOR; } } @@ -132,23 +133,24 @@ if (!defined('BASE_URL')) { // When htaccess redirects from /base to /base/public folder, we need to only include /public // in the BASE_URL if it's also present in the request - if ($baseURL - && PUBLIC_DIR - && isset($_SERVER['REQUEST_URI']) - && substr($baseURL, -strlen(PUBLIC_DIR)) === PUBLIC_DIR + if (!$baseURL + || !PUBLIC_DIR + || !isset($_SERVER['REQUEST_URI']) + || substr($baseURL, -strlen(PUBLIC_DIR)) !== PUBLIC_DIR ) { - $requestURI = $_SERVER['REQUEST_URI']; - // Check if /base/public or /base are in the request - foreach ([$baseURL, dirname($baseURL)] as $candidate) { - if (stripos($requestURI, $candidate) === 0) { - return $candidate; - } - } - // Ambiguous - return ''; + return $baseURL; } - return $baseURL; + $requestURI = $_SERVER['REQUEST_URI']; + // Check if /base/public or /base are in the request + foreach ([$baseURL, dirname($baseURL)] as $candidate) { + if (stripos($requestURI, $candidate) === 0) { + return $candidate; + } + } + + // Ambiguous + return ''; })); }