Browse Source

Merge branch '3.next' into 4.x

Mark Story 8 years ago
parent
commit
7f526397ef

+ 3 - 0
src/Database/Dialect/PostgresDialectTrait.php

@@ -132,6 +132,9 @@ trait PostgresDialectTrait
             case 'NOW':
                 $expression->setName('LOCALTIMESTAMP')->add([' 0 ' => 'literal']);
                 break;
+            case 'RAND':
+                $expression->setName('RANDOM');
+                break;
             case 'DATE_ADD':
                 $expression
                     ->setName('')

+ 5 - 0
src/Database/Dialect/SqliteDialectTrait.php

@@ -108,6 +108,11 @@ trait SqliteDialectTrait
             case 'NOW':
                 $expression->setName('DATETIME')->add(["'now'" => 'literal']);
                 break;
+            case 'RAND':
+                $expression
+                    ->setName('ABS')
+                    ->add(["RANDOM() % 1" => 'literal'], [], true);
+                break;
             case 'CURRENT_DATE':
                 $expression->setName('DATE')->add(["'now'" => 'literal']);
                 break;

+ 10 - 0
src/Database/FunctionsBuilder.php

@@ -61,6 +61,16 @@ class FunctionsBuilder
     }
 
     /**
+     * Returns a FunctionExpression representing a call to SQL RAND function.
+     *
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function rand()
+    {
+        return $this->_build('RAND', [], [], 'float');
+    }
+
+    /**
      * Returns a FunctionExpression representing a call to SQL SUM function.
      *
      * @param mixed $expression the function argument

+ 7 - 1
src/Error/BaseErrorHandler.php

@@ -38,6 +38,11 @@ abstract class BaseErrorHandler
     protected $_options = [];
 
     /**
+     * @var bool
+     */
+    protected $_handled = false;
+
+    /**
      * Display an error message in an environment specific way.
      *
      * Subclasses should implement this method to display the error as
@@ -75,7 +80,7 @@ abstract class BaseErrorHandler
         set_error_handler([$this, 'handleError'], $level);
         set_exception_handler([$this, 'wrapAndHandleException']);
         register_shutdown_function(function () {
-            if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+            if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && $this->_handled) {
                 return;
             }
             $megabytes = Configure::read('Error.extraFatalErrorMemory');
@@ -128,6 +133,7 @@ abstract class BaseErrorHandler
         if (error_reporting() === 0) {
             return false;
         }
+        $this->_handled = true;
         list($error, $log) = static::mapErrorCode($code);
         if ($log === LOG_ERR) {
             return $this->handleFatalError($code, $description, $file, $line);

+ 4 - 3
src/Http/ServerRequest.php

@@ -112,7 +112,7 @@ class ServerRequest implements ArrayAccess, ServerRequestInterface
      * The full address to the current request
      *
      * @var string
-     * @deprecated 3.4.0 This public property will be removed in 4.0.0. Use getUri()->getPath() instead.
+     * @deprecated 3.4.0 This public property will be removed in 4.0.0. Use getAttribute('here') or getUri()->getPath() instead.
      */
     protected $here;
 
@@ -2150,7 +2150,7 @@ class ServerRequest implements ArrayAccess, ServerRequestInterface
     /**
      * Get all the attributes in the request.
      *
-     * This will include the params, webroot, and base attributes that CakePHP
+     * This will include the params, webroot, base, and here attributes that CakePHP
      * provides.
      *
      * @return array
@@ -2160,7 +2160,8 @@ class ServerRequest implements ArrayAccess, ServerRequestInterface
         $emulated = [
             'params' => $this->params,
             'webroot' => $this->webroot,
-            'base' => $this->base
+            'base' => $this->base,
+            'here' => $this->here
         ];
 
         return $this->attributes + $emulated;

+ 13 - 0
tests/TestCase/Database/FunctionsBuilderTest.php

@@ -217,4 +217,17 @@ class FunctionsBuilderTest extends TestCase
         $this->assertEquals('DAYOFWEEK(created)', $function->sql(new ValueBinder));
         $this->assertEquals('integer', $function->getReturnType());
     }
+
+    /**
+     * Tests generating a RAND() function
+     *
+     * @return void
+     */
+    public function testRand()
+    {
+        $function = $this->functions->rand();
+        $this->assertInstanceOf('Cake\Database\Expression\FunctionExpression', $function);
+        $this->assertEquals('RAND()', $function->sql(new ValueBinder));
+        $this->assertEquals('float', $function->getReturnType());
+    }
 }

+ 2 - 1
tests/TestCase/Http/ServerRequestTest.php

@@ -3627,7 +3627,8 @@ XML;
                 'pass' => [],
             ],
             'webroot' => '',
-            'base' => ''
+            'base' => '',
+            'here' => '/'
         ];
         $this->assertEquals($expected, $new->getAttributes());
     }

+ 20 - 0
tests/TestCase/ORM/QueryTest.php

@@ -1701,6 +1701,26 @@ class QueryTest extends TestCase
     }
 
     /**
+     * Test that RAND() returns correct results.
+     *
+     * @return void
+     */
+    public function testSelectRandom()
+    {
+        $table = $this->getTableLocator()->get('articles');
+        $query = $table
+            ->query();
+
+        $query->select(['s' => $query->func()->rand()]);
+        $result = $query
+            ->extract('s')
+            ->first();
+
+        $this->assertGreaterThanOrEqual(0, $result);
+        $this->assertLessThan(1, $result);
+    }
+
+    /**
      * Test update method.
      *
      * @return void