diff --git a/.travis.yml b/.travis.yml index 5f4ad6e2..15671fb0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: php php: - - 7.0.15 - 7.1 + - 7.2 install: - composer install diff --git a/classes/Models/Change.php b/classes/Models/Change.php index 4022594b..798920d5 100644 --- a/classes/Models/Change.php +++ b/classes/Models/Change.php @@ -96,7 +96,7 @@ public function shouldLogChange($action) public static function log(Model $model, $action, Admin $admin = null) { // Create a new change instance - if (static::shouldWriteChange($model)) { + if (static::shouldWriteChange($model, $action)) { $changed = static::getChanged($model, $action); $change = static::createLog($model, $action, $admin, $changed); } @@ -125,10 +125,12 @@ public static function log(Model $model, $action, Admin $admin = null) * besides these that changed. * * @param Model $model The model being touched + * @param string $action * @return boolean */ - static private function shouldWriteChange(Model $model) + static private function shouldWriteChange(Model $model, $action) { + if (in_array($action, ['created', 'deleted'])) return true; $changed_attributes = array_keys($model->getDirty()); $ignored = ['updated_at', 'public']; $loggable = array_diff($changed_attributes, $ignored); diff --git a/classes/Models/Command.php b/classes/Models/Command.php index aba5e9eb..ad00ad3a 100644 --- a/classes/Models/Command.php +++ b/classes/Models/Command.php @@ -35,7 +35,6 @@ public static function all() $commands['Laravel']['Seed'] = App::make('command.seed'); $commands['Laravel']['Cache clear'] = App::make('command.cache.clear'); $commands['Laravel']['Clear compiled classes'] = App::make('command.clear-compiled'); - $commands['Laravel']['Optimize classes'] = App::make('command.optimize'); // Return matching commands return $commands; diff --git a/classes/Models/Traits/Loggable.php b/classes/Models/Traits/Loggable.php index 1e97f6cb..dc256fc1 100644 --- a/classes/Models/Traits/Loggable.php +++ b/classes/Models/Traits/Loggable.php @@ -9,6 +9,7 @@ use Bkwld\Decoy\Models\Image; use Decoy; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\SoftDeletingScope; /** * Enable logging changes to models @@ -48,7 +49,8 @@ public function changes() */ public static function bootLoggable() { - // Automatically eager load the images relationship + // Add scope that will fetch trashed versions of models when the + // Change::QUERY_KEY is present. static::addGlobalScope(static::$LOGGABLE_SCOPE, function (Builder $builder) { static::showTrashedVersion($builder); }); @@ -83,7 +85,7 @@ private static function showTrashedVersion(Builder $builder) { if (($change = static::lookupRequestedChange()) && static::builderMatchesChange($change, $builder)) { - static::includeTrashed($change, $builder); + $builder->withoutGlobalScope(SoftDeletingScope::class); } } @@ -149,28 +151,6 @@ private static function builderMatchesChange(Change $change, Builder $builder) }); } - /** - * Manually remove already added soft deleted where conditions. This is - * necessary since withTrashed() can't be called on a Builder. - * http://yo.bkwld.com/1K04151B2h3M - * - * @param Change $change - * @param Builder $builder - * @return void - */ - private static function includeTrashed(Change $change, Builder $builder) - { - $class = $change->model; - $table = (new $class)->getTable(); - foreach($builder->getQuery()->wheres as $key => $where) { - if ($where['column'] == $table.'.deleted_at' - && $where['type'] == 'Null') { - unset($builder->getQuery()->wheres[$key]); - break; - } - } - } - /** * Replace all the attributes with those from the specified Change specified * in the reqeust query. diff --git a/classes/Observers/ValidateExistingFiles.php b/classes/Observers/ValidateExistingFiles.php index ebc2aa7a..c8ee7541 100644 --- a/classes/Observers/ValidateExistingFiles.php +++ b/classes/Observers/ValidateExistingFiles.php @@ -4,6 +4,7 @@ // Deps use Symfony\Component\HttpFoundation\File\File; +use Symfony\Component\HttpFoundation\File\UploadedFile; /** * When a form is updated (as opposed to created) the previous files are @@ -77,16 +78,19 @@ public function onValidating($event, $payload) } /** - * Make a file instance using uphuck from the string input value + * Make an UploadedFile instance using Upchuck from the string input value * * @param string $path - * @return File + * @return UploadedFile */ public function makeFileFromPath($path) { $upchuck_path = app('upchuck')->path($path); $absolute_path = config('upchuck.disk.path').'/'.$upchuck_path; - return new File($absolute_path); + return new UploadedFile( + $absolute_path, basename($absolute_path), + null, null, // Default mime and error + true); // Enable test mode so local file will be pass as uploaded } } diff --git a/classes/ServiceProvider.php b/classes/ServiceProvider.php index eb1b826f..c582b7c0 100644 --- a/classes/ServiceProvider.php +++ b/classes/ServiceProvider.php @@ -9,6 +9,7 @@ use Illuminate\Foundation\AliasLoader; use Illuminate\Contracts\Auth\Access\Gate; use Illuminate\Contracts\Debug\ExceptionHandler; +use Illuminate\Pagination\Paginator; use Illuminate\Support\ServiceProvider as BaseServiceProvider; class ServiceProvider extends BaseServiceProvider @@ -121,6 +122,11 @@ public function usingAdmin() // Delegate events to Decoy observers $this->delegateAdminObservers(); + + // Use Boostrap 3 classes in Laravel 5.6 + if (method_exists(Paginator::class, 'useBootstrapThree')) { + Paginator::useBootstrapThree(); + } } /** diff --git a/composer.json b/composer.json index f4aa18df..6db48f18 100644 --- a/composer.json +++ b/composer.json @@ -36,26 +36,26 @@ "cviebrock/eloquent-sluggable": "~4.0", "illuminate/support": "^5.0", "illuminate/console": "^5.0", - "symfony/yaml": "~2.5 || ^3.0", + "symfony/yaml": "~2.5 || ^3.0 || ^4.0", "zencoder/zencoder-php": "~2.2", "jenssegers/agent": "~2.1", "league/csv": "^9.1", "doctrine/dbal": "^2.5" }, "require-dev": { - "laravel/framework": "5.4.*|5.5.*", + "laravel/framework": "5.4.* || 5.5.* || 5.6.*", "filp/whoops": "~2.0", "fzaninotto/faker": "~1.4", "mockery/mockery": "0.9.*", - "phpunit/phpunit": "~6.0", - "symfony/css-selector": "3.1.*", - "symfony/dom-crawler": "3.1.*", - "satooshi/php-coveralls": "^1.0", + "phpunit/phpunit": "~6.0 || ~7.0", + "symfony/css-selector": "3.1.* || ^4.0", + "symfony/dom-crawler": "3.1.* || ^4.0", + "php-coveralls/php-coveralls": "^1.0 || ^2.0", "adlawson/vfs": "^0.12.1", "league/flysystem": "^1.0", "league/flysystem-vfs": "^1.0", "laravel/tinker": "^1.0", - "fideloper/proxy": "~3.3" + "fideloper/proxy": "~3.3 || ^4.0" }, "conflict": { "anahkiasen/html-object": "1.4.1", diff --git a/example/.env.example b/example/.env.example index 668c06f0..ec44a125 100644 --- a/example/.env.example +++ b/example/.env.example @@ -2,9 +2,10 @@ APP_NAME=Laravel APP_ENV=local APP_KEY= APP_DEBUG=true -APP_LOG_LEVEL=debug APP_URL=http://localhost +LOG_CHANNEL=stack + DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 @@ -15,6 +16,7 @@ DB_PASSWORD=secret BROADCAST_DRIVER=log CACHE_DRIVER=file SESSION_DRIVER=file +SESSION_LIFETIME=120 QUEUE_DRIVER=sync REDIS_HOST=127.0.0.1 @@ -31,3 +33,7 @@ MAIL_ENCRYPTION=null PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" diff --git a/example/app/Http/Controllers/Auth/RegisterController.php b/example/app/Http/Controllers/Auth/RegisterController.php index f77265ab..e17ee6bf 100644 --- a/example/app/Http/Controllers/Auth/RegisterController.php +++ b/example/app/Http/Controllers/Auth/RegisterController.php @@ -4,6 +4,7 @@ use App\User; use App\Http\Controllers\Controller; +use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Illuminate\Foundation\Auth\RegistersUsers; @@ -50,7 +51,7 @@ protected function validator(array $data) return Validator::make($data, [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', - 'password' => 'required|string|min:6|confirmed', + 'password' => Hash::make($data['password']), ]); } diff --git a/example/app/Http/Kernel.php b/example/app/Http/Kernel.php index 93bf68bf..3439540c 100644 --- a/example/app/Http/Kernel.php +++ b/example/app/Http/Kernel.php @@ -54,8 +54,10 @@ class Kernel extends HttpKernel 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, + 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, ]; } diff --git a/example/app/Http/Middleware/TrustProxies.php b/example/app/Http/Middleware/TrustProxies.php index ef1c00d1..7daf51f1 100644 --- a/example/app/Http/Middleware/TrustProxies.php +++ b/example/app/Http/Middleware/TrustProxies.php @@ -15,15 +15,9 @@ class TrustProxies extends Middleware protected $proxies; /** - * The current proxy header mappings. + * The headers that should be used to detect proxies. * - * @var array + * @var int */ - protected $headers = [ - Request::HEADER_FORWARDED => 'FORWARDED', - Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR', - Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST', - Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT', - Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO', - ]; + protected $headers = Request::HEADER_X_FORWARDED_ALL; } diff --git a/example/composer.json b/example/composer.json index 3ba4bd1a..d5f1ab6e 100644 --- a/example/composer.json +++ b/example/composer.json @@ -6,16 +6,16 @@ "type": "project", "require": { "php": ">=7.0.0", - "fideloper/proxy": "~3.3", - "laravel/framework": "5.5.*", - "laravel/tinker": "~1.0", - "bkwld/decoy": "5.10.x-dev" + "fideloper/proxy": "~3.3 || ^4.0", + "laravel/framework": "5.5.* || 5.6.*", + "laravel/tinker": "^1.0", + "bkwld/decoy": "5.11.x-dev" }, "require-dev": { "filp/whoops": "~2.0", "fzaninotto/faker": "~1.4", "mockery/mockery": "0.9.*", - "phpunit/phpunit": "~6.0" + "phpunit/phpunit": "~6.0 || ~7.0" }, "autoload": { "classmap": [ @@ -61,5 +61,7 @@ "preferred-install": "dist", "sort-packages": true, "optimize-autoloader": true - } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/example/config/app.php b/example/config/app.php index bbf740cb..660df5a0 100644 --- a/example/config/app.php +++ b/example/config/app.php @@ -108,23 +108,6 @@ 'cipher' => 'AES-256-CBC', - /* - |-------------------------------------------------------------------------- - | Logging Configuration - |-------------------------------------------------------------------------- - | - | Here you may configure the log settings for your application. Out of - | the box, Laravel uses the Monolog PHP logging library. This gives - | you a variety of powerful log handlers / formatters to utilize. - | - | Available Settings: "single", "daily", "syslog", "errorlog" - | - */ - - 'log' => env('APP_LOG', 'single'), - - 'log_level' => env('APP_LOG_LEVEL', 'debug'), - /* |-------------------------------------------------------------------------- | Autoloaded Service Providers diff --git a/example/config/filesystems.php b/example/config/filesystems.php index 4544f60c..84bad568 100644 --- a/example/config/filesystems.php +++ b/example/config/filesystems.php @@ -37,7 +37,7 @@ | may even configure multiple disks of the same driver. Defaults have | been setup for each driver as an example of the required options. | - | Supported Drivers: "local", "ftp", "s3", "rackspace" + | Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace" | */ @@ -61,6 +61,7 @@ 'secret' => env('AWS_SECRET'), 'region' => env('AWS_REGION'), 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), ], ], diff --git a/example/config/hashing.php b/example/config/hashing.php new file mode 100644 index 00000000..f929cf0c --- /dev/null +++ b/example/config/hashing.php @@ -0,0 +1,20 @@ + 'bcrypt', + +]; diff --git a/example/config/logging.php b/example/config/logging.php new file mode 100644 index 00000000..902efafb --- /dev/null +++ b/example/config/logging.php @@ -0,0 +1,70 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Out of + | the box, Laravel uses the Monolog PHP logging library. This gives + | you a variety of powerful log handlers / formatters to utilize. + | + | Available Drivers: "single", "daily", "slack", "syslog", + | "errorlog", "custom", "stack" + | + */ + + 'channels' => [ + 'stack' => [ + 'driver' => 'stack', + 'channels' => ['single'], + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => 'debug', + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => 'debug', + 'days' => 7, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => 'Laravel Log', + 'emoji' => ':boom:', + 'level' => 'critical', + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => 'debug', + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => 'debug', + ], + ], + +]; diff --git a/example/config/queue.php b/example/config/queue.php index 4d83ebd0..23fde089 100644 --- a/example/config/queue.php +++ b/example/config/queue.php @@ -9,9 +9,7 @@ | | Laravel's queue API supports an assortment of back-ends via a single | API, giving you convenient access to each back-end using the same - | syntax for each one. Here you may set the default queue driver. - | - | Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | syntax for every one. Here you may define a default connection. | */ @@ -26,6 +24,8 @@ | is used by your application. A default configuration has been added | for each back-end shipped with Laravel. You are free to add more. | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | */ 'connections' => [ @@ -62,6 +62,7 @@ 'connection' => 'default', 'queue' => 'default', 'retry_after' => 90, + 'block_for' => null, ], ], diff --git a/example/config/services.php b/example/config/services.php index 4460f0ec..aa1f7f82 100644 --- a/example/config/services.php +++ b/example/config/services.php @@ -22,7 +22,7 @@ 'ses' => [ 'key' => env('SES_KEY'), 'secret' => env('SES_SECRET'), - 'region' => 'us-east-1', + 'region' => env('SES_REGION', 'us-east-1'), ], 'sparkpost' => [ diff --git a/example/package.json b/example/package.json index dedcbef7..bd9b6a95 100644 --- a/example/package.json +++ b/example/package.json @@ -3,15 +3,16 @@ "scripts": { "dev": "npm run development", "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", - "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", + "watch": "npm run development -- --watch", "watch-poll": "npm run watch -- --watch-poll", "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", "prod": "npm run production", "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" }, "devDependencies": { - "axios": "^0.16.2", - "bootstrap-sass": "^3.3.7", + "axios": "^0.18", + "bootstrap": "^4.0.0", + "popper.js": "^1.12", "cross-env": "^5.0.1", "jquery": "^3.1.1", "laravel-mix": "^1.0", diff --git a/example/phpunit.xml b/example/phpunit.xml index bb9c4a7e..c9e326b6 100644 --- a/example/phpunit.xml +++ b/example/phpunit.xml @@ -24,8 +24,10 @@ + + diff --git a/tests/Integration/ChangesTest.php b/tests/Integration/ChangesTest.php index a3f51878..0d3a8da0 100644 --- a/tests/Integration/ChangesTest.php +++ b/tests/Integration/ChangesTest.php @@ -37,7 +37,7 @@ protected function setUp() { } /** - * Test that the commands page loads and all 3 changes were made + * Test that the changes page loads and all 3 changes were made * * @return void */ diff --git a/tests/Integration/FileTest.php b/tests/Integration/FileTest.php index 38811cde..e0945f27 100644 --- a/tests/Integration/FileTest.php +++ b/tests/Integration/FileTest.php @@ -138,7 +138,12 @@ public function testImageKeptOnUpdate() // Submit a save $response = $this->post('admin/articles/'.$article->id.'/edit', [ - 'title' => 'Ok?' + 'title' => 'Ok?', + 'images' => [ + $image->id => [ + 'name' => 'image' + ] + ], ]); $response->assertSessionMissing('errors'); diff --git a/tests/TestCase.php b/tests/TestCase.php index a85ee4ad..0e44b34b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -129,7 +129,7 @@ protected function createUploadedFile($filename = null) return new UploadedFile( $file_path, basename($file_path), - 'image/jpeg', + 'image/png', null, null, true