Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c31343d
Ensure cache paths exist
LukeTowers Jul 13, 2023
f59d437
Add support for event:cache, event:clear, and event:list commands
LukeTowers Jul 13, 2023
7b871c3
Add newline to end of file
LukeTowers Jul 13, 2023
6979440
Added App::hasDatabaseTable() helper method
LukeTowers Jul 14, 2023
162b8e8
Added Model::hasDatabaseTable() and $model->isDatabaseReady() helpers
LukeTowers Jul 14, 2023
ae124b1
Code tidying
LukeTowers Jul 14, 2023
dd7b1b6
Disable specific phpstan complaint for now
LukeTowers Jul 14, 2023
41172a3
Fix issue with open_basedir compatibility
LukeTowers Jul 20, 2023
b9a7c98
Add hasAttribute() method to base Model class
LukeTowers Jul 23, 2023
ce542ac
Add Http->json() helper method to send the provided payload as JSON (…
mjauvin Aug 2, 2023
4665d66
Update tests for config writer v1.1.0 (#151)
jaxwilko Aug 10, 2023
4f683cc
Call model methods using event handler with default priority (#150)
mjauvin Aug 13, 2023
391bd3e
Clear model cache when using upsert (#154)
zimudec Aug 22, 2023
de146af
Adds Encryptable model behavior (#138)
der-On Sep 15, 2023
5a3ffdc
Fix docblocks for Resizer class (#158)
AIC-BV Oct 14, 2023
c0acc2b
Add event to make model validation extendable (#139)
mjauvin Oct 16, 2023
404b199
Improve automatic detaching / deletion of relations (#156)
mjauvin Oct 18, 2023
d1b95f7
Remove deprecated "get_parent_class" calls in Extendable trait. (#153)
bennothommo Oct 19, 2023
2941ef4
Restore previous tests order (#159)
mjauvin Oct 19, 2023
c779404
Make Svg::sanitize() a public method
LukeTowers Nov 29, 2023
1c8adb8
Support Throwables in SystemExceptions (#160)
msimkunas Dec 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 5 additions & 45 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ parameters:
count: 1
path: src/Auth/Models/Group.php

-
message: "#^Call to an undefined method Winter\\\\Storm\\\\Auth\\\\Models\\\\Group\\:\\:afterValidate\\(\\)\\.$#"
count: 1
path: src/Auth/Models/Group.php

-
message: "#^Call to an undefined method Winter\\\\Storm\\\\Auth\\\\Models\\\\Group\\:\\:beforeValidate\\(\\)\\.$#"
count: 1
path: src/Auth/Models/Group.php

-
message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\)\\:\\:getOriginalEncryptableValues\\(\\)\\.$#"
count: 1
Expand All @@ -30,31 +20,11 @@ parameters:
count: 1
path: src/Auth/Models/Role.php

-
message: "#^Call to an undefined method Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\:\\:afterValidate\\(\\)\\.$#"
count: 1
path: src/Auth/Models/Role.php

-
message: "#^Call to an undefined method Winter\\\\Storm\\\\Auth\\\\Models\\\\Role\\:\\:beforeValidate\\(\\)\\.$#"
count: 1
path: src/Auth/Models/Role.php

-
message: "#^Call to an undefined method \\$this\\(Winter\\\\Storm\\\\Auth\\\\Models\\\\User\\)\\:\\:getOriginalEncryptableValues\\(\\)\\.$#"
count: 1
path: src/Auth/Models/User.php

-
message: "#^Call to an undefined method Winter\\\\Storm\\\\Auth\\\\Models\\\\User\\:\\:afterValidate\\(\\)\\.$#"
count: 1
path: src/Auth/Models/User.php

-
message: "#^Call to an undefined method Winter\\\\Storm\\\\Auth\\\\Models\\\\User\\:\\:beforeValidate\\(\\)\\.$#"
count: 1
path: src/Auth/Models/User.php

-
message: "#^Parameter \\#1 \\$app of class Illuminate\\\\Database\\\\DatabaseManager constructor expects Illuminate\\\\Contracts\\\\Foundation\\\\Application, Illuminate\\\\Contracts\\\\Container\\\\Container given\\.$#"
count: 1
Expand Down Expand Up @@ -100,6 +70,11 @@ parameters:
count: 1
path: src/Database/Model.php

-
message: "#^Static property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$dispatcher \\(Illuminate\\\\Contracts\\\\Events\\\\Dispatcher\\) in isset\\(\\) is not nullable\\.$#"
count: 1
path: src/Database/Model.php

-
message: "#^Call to an undefined method Winter\\\\Storm\\\\Database\\\\Model\\:\\:errors\\(\\)\\.$#"
count: 1
Expand Down Expand Up @@ -740,21 +715,6 @@ parameters:
count: 1
path: src/Database/TreeCollection.php

-
message: "#^Winter\\\\Storm\\\\Extension\\\\Extendable\\:\\:extendableCall\\(\\) calls parent\\:\\:__call\\(\\) but Winter\\\\Storm\\\\Extension\\\\Extendable does not extend any class\\.$#"
count: 1
path: src/Extension/Extendable.php

-
message: "#^Winter\\\\Storm\\\\Extension\\\\Extendable\\:\\:extendableGet\\(\\) calls parent\\:\\:__get\\(\\) but Winter\\\\Storm\\\\Extension\\\\Extendable does not extend any class\\.$#"
count: 1
path: src/Extension/Extendable.php

-
message: "#^Winter\\\\Storm\\\\Extension\\\\Extendable\\:\\:extendableSet\\(\\) calls parent\\:\\:__set\\(\\) but Winter\\\\Storm\\\\Extension\\\\Extendable does not extend any class\\.$#"
count: 1
path: src/Extension/Extendable.php

-
message: "#^Parameter \\#2 \\$data \\(array\\) of method Winter\\\\Storm\\\\Mail\\\\Mailer\\:\\:queue\\(\\) should be compatible with parameter \\$queue \\(string\\|null\\) of method Illuminate\\\\Contracts\\\\Mail\\\\MailQueue\\:\\:queue\\(\\)$#"
count: 1
Expand Down
13 changes: 1 addition & 12 deletions src/Auth/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable
* @var array Relations
*/
public $belongsToMany = [
'groups' => [Group::class, 'table' => 'users_groups']
'groups' => [Group::class, 'table' => 'users_groups'],
];

public $belongsTo = [
Expand Down Expand Up @@ -154,17 +154,6 @@ public function afterLogin()
$this->forceSave();
}

/**
* Delete the user groups
* @return void
*/
public function afterDelete()
{
if ($this->hasRelation('groups')) {
$this->groups()->detach();
}
}

//
// Persistence (used by Cookies and Sessions)
//
Expand Down
5 changes: 5 additions & 0 deletions src/Console/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ abstract class Command extends BaseCommand implements SignalableCommandInterface
use Traits\HandlesCleanup;
use Traits\ProvidesAutocompletion;

/**
* @var \Winter\Storm\Foundation\Application
*/
protected $laravel;

/**
* @var array List of commands that this command replaces (aliases)
*/
Expand Down
9 changes: 6 additions & 3 deletions src/Database/Attach/Resizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@
* Usage:
* Resizer::open(mixed $file)
* ->resize(int $width , int $height, string 'exact, portrait, landscape, auto, fit or crop')
* ->save(string 'path/to/file.jpg', int $quality);
* ->setOptions(['quality' => int $quality])
* ->save(string 'path/to/file.jpg');
*
* // Resize and save an image.
* Resizer::open(Input::file('field_name'))
* ->resize(800, 600, 'crop')
* ->save('path/to/file.jpg', 100);
* ->setOptions(['quality' => 100])
* ->save('path/to/file.jpg');
*
* // Recompress an image.
* Resizer::open('path/to/image.jpg')
* ->save('path/to/new_image.jpg', 60);
* ->setOptions(['quality' => 60])
* ->save('path/to/new_image.jpg');
*
* @author Alexey Bobkov, Samuel Georges
*/
Expand Down
158 changes: 158 additions & 0 deletions src/Database/Behaviors/Encryptable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php namespace Winter\Storm\Database\Behaviors;

use App;
use Illuminate\Contracts\Encryption\Encrypter;
use Winter\Storm\Database\Model;
use Winter\Storm\Exception\ApplicationException;
use Winter\Storm\Extension\ExtensionBase;

/**
* Encryptable model behavior
*
* Usage:
*
* In the model class definition:
*
* public $implement = [
* \Winter\Storm\Database\Behaviors\Encryptable::class,
* ];
*
* /**
* * List of attributes to encrypt.
* * /
* protected array $encryptable = ['api_key', 'api_secret'];
*
* Dynamically attached to third party model:
*
* TargetModel::extend(function ($model) {
* $model->addDynamicProperty('encryptable', ['encrypt_this']);
* $model->extendClassWith(\Winter\Storm\Database\Behaviors\Encryptable::class);
* });
*
* >**NOTE**: Encrypted attributes will be serialized and unserialized
* as a part of the encryption / decryption process. Do not make an
* attribute that is encryptable also jsonable at the same time as the
* jsonable process will attempt to decode a value that has already been
* unserialized by the encrypter.
*
*/
class Encryptable extends ExtensionBase
{
protected Model $model;

/**
* List of attribute names which should be encrypted
*
* protected array $encryptable = [];
*/

/**
* Encrypter instance.
*/
protected ?Encrypter $encrypterInstance = null;

/**
* List of original attribute values before they were encrypted.
*/
protected array $originalEncryptableValues = [];

public function __construct($parent)
{
$this->model = $parent;
$this->bootEncryptable();
}

/**
* Boot the encryptable trait for a model.
*/
public function bootEncryptable(): void
{
$isEncryptable = $this->model->extend(function () {
/** @var Model $this */
return $this->propertyExists('encryptable');
});

if (!$isEncryptable) {
throw new ApplicationException(sprintf(
'You must define an $encryptable property on the %s class to use the Encryptable behavior.',
get_class($this->model)
));
}

/*
* Encrypt required fields when necessary
*/
$this->model->bindEvent('model.beforeSetAttribute', function ($key, $value) {
if (in_array($key, $this->getEncryptableAttributes()) && !is_null($value)) {
return $this->makeEncryptableValue($key, $value);
}
});
$this->model->bindEvent('model.beforeGetAttribute', function ($key) {
if (in_array($key, $this->getEncryptableAttributes()) && array_get($this->model->attributes, $key) != null) {
return $this->getEncryptableValue($key);
}
});
}

/**
* Encrypts an attribute value and saves it in the original locker.
*/
public function makeEncryptableValue(string $key, mixed $value): string
{
$this->originalEncryptableValues[$key] = $value;
return $this->getEncrypter()->encrypt($value);
}

/**
* Decrypts an attribute value
*/
public function getEncryptableValue(string $key): mixed
{
$attributes = $this->model->getAttributes();
return isset($attributes[$key])
? $this->getEncrypter()->decrypt($attributes[$key])
: null;
}

/**
* Returns a collection of fields that will be encrypted.
*/
public function getEncryptableAttributes(): array
{
return $this->model->extend(function () {
return $this->encryptable ?? [];
});
}

/**
* Returns the original values of any encrypted attributes.
*/
public function getOriginalEncryptableValues(): array
{
return $this->originalEncryptableValues;
}

/**
* Returns the original values of any encrypted attributes.
*/
public function getOriginalEncryptableValue(string $attribute): mixed
{
return array_get($this->originalEncryptableValues, $attribute, null);
}

/**
* Provides the encrypter instance.
*/
public function getEncrypter(): Encrypter
{
return (!is_null($this->encrypterInstance)) ? $this->encrypterInstance : App::make('encrypter');
}

/**
* Sets the encrypter instance.
*/
public function setEncrypter(Encrypter $encrypter): void
{
$this->encrypterInstance = $encrypter;
}
}
2 changes: 2 additions & 0 deletions src/Database/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ public function upsert(array $values, $uniqueBy, $update = null)
return 0;
}

$this->clearDuplicateCache();

if (!is_array(reset($values))) {
$values = [$values];
}
Expand Down
Loading