Remove EncodeUTF8 infavour of using attribute casting only. The implementation of EncodeUTF8 was not correct, essentially removing any previous casting causing issues when saving a record.
This commit is contained in:
parent
b5047c52f0
commit
81f59dcbb8
@ -5,20 +5,19 @@ namespace App\Casts;
|
|||||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class CompressedString implements CastsAttributes
|
class CompressedStringOrNull implements CastsAttributes
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Cast the given value.
|
* Cast the given value.
|
||||||
*
|
*
|
||||||
* For postgresl bytea columns the value is a resource stream
|
|
||||||
*
|
|
||||||
* @param Model $model
|
* @param Model $model
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $attributes
|
* @param array $attributes
|
||||||
* @return string
|
* @return string|null
|
||||||
|
* @note postgres bytea columns the value is a resource stream
|
||||||
*/
|
*/
|
||||||
public function get($model,string $key,mixed $value,array $attributes): string
|
public function get(Model $model,string $key,mixed $value,array $attributes): ?string
|
||||||
{
|
{
|
||||||
// For stream resources, we to fseek in case we've already read it.
|
// For stream resources, we to fseek in case we've already read it.
|
||||||
if (is_resource($value))
|
if (is_resource($value))
|
||||||
@ -28,13 +27,7 @@ class CompressedString implements CastsAttributes
|
|||||||
? stream_get_contents($value)
|
? stream_get_contents($value)
|
||||||
: $value;
|
: $value;
|
||||||
|
|
||||||
// If we get an error decompressing, it might not be zstd (or its already been done)
|
return $value ? zstd_uncompress(base64_decode($value)) : NULL;
|
||||||
try {
|
|
||||||
return $value ? zstd_uncompress(base64_decode($value)) : '';
|
|
||||||
|
|
||||||
} catch (\ErrorException $e) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,10 +37,10 @@ class CompressedString implements CastsAttributes
|
|||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $attributes
|
* @param array $attributes
|
||||||
* @return string
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function set($model,string $key,$value,array $attributes): string
|
public function set(Model $model,string $key,$value,array $attributes): ?string
|
||||||
{
|
{
|
||||||
return $value ? base64_encode(zstd_compress($value)) : '';
|
return $value ? base64_encode(zstd_compress($value)) : NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
29
app/Casts/UTF8StringOrNull.php
Normal file
29
app/Casts/UTF8StringOrNull.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Casts;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class UTF8StringOrNull implements CastsAttributes
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Cast the given value.
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $attributes
|
||||||
|
*/
|
||||||
|
public function get(Model $model,string $key,mixed $value,array $attributes): ?string
|
||||||
|
{
|
||||||
|
return $value ? utf8_decode($value) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the given value for storage.
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $attributes
|
||||||
|
*/
|
||||||
|
public function set(Model $model,string $key,mixed $value,array $attributes): ?string
|
||||||
|
{
|
||||||
|
return $value ? utf8_encode($value) : NULL;
|
||||||
|
}
|
||||||
|
}
|
@ -14,21 +14,17 @@ use Illuminate\Support\Facades\Notification;
|
|||||||
use App\Classes\FTN\Message;
|
use App\Classes\FTN\Message;
|
||||||
use App\Models\{Echomail,Netmail,User};
|
use App\Models\{Echomail,Netmail,User};
|
||||||
use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,NetmailForward,NetmailHubNoUser};
|
use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,NetmailForward,NetmailHubNoUser};
|
||||||
use App\Traits\{EncodeUTF8,ParseAddresses};
|
use App\Traits\ParseAddresses;
|
||||||
|
|
||||||
class MessageProcess implements ShouldQueue
|
class MessageProcess implements ShouldQueue
|
||||||
{
|
{
|
||||||
private const LOGKEY = 'JMP';
|
private const LOGKEY = 'JMP';
|
||||||
|
|
||||||
use Dispatchable,InteractsWithQueue,Queueable,SerializesModels,ParseAddresses,EncodeUTF8;
|
use Dispatchable,InteractsWithQueue,Queueable,SerializesModels,ParseAddresses;
|
||||||
|
|
||||||
private Echomail|Netmail|string $mo;
|
private Echomail|Netmail|string $mo;
|
||||||
private bool $skipbot;
|
private bool $skipbot;
|
||||||
|
|
||||||
private const cast_utf8 = [
|
|
||||||
'mo',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a message from a packet
|
* Process a message from a packet
|
||||||
*
|
*
|
||||||
@ -54,16 +50,6 @@ class MessageProcess implements ShouldQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __serialize()
|
|
||||||
{
|
|
||||||
return $this->encode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __unserialize(array $values)
|
|
||||||
{
|
|
||||||
$this->decode($values);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At this point, we know that the packet is from a system we know about, and the packet is to us:
|
* At this point, we know that the packet is from a system we know about, and the packet is to us:
|
||||||
* + From a system that is configured with us, and the password has been validated
|
* + From a system that is configured with us, and the password has been validated
|
||||||
@ -144,8 +130,8 @@ class MessageProcess implements ShouldQueue
|
|||||||
// Check if the netmail is to a user, with netmail forwarding enabled
|
// Check if the netmail is to a user, with netmail forwarding enabled
|
||||||
$uo = User::active()
|
$uo = User::active()
|
||||||
->where(function($query) {
|
->where(function($query) {
|
||||||
return $query->whereRaw(sprintf("LOWER(name)='%s'",strtolower($this->mo->to)))
|
return $query->whereRaw(sprintf("LOWER(name)='%s'",strtolower(utf8_encode($this->mo->to))))
|
||||||
->orWhereRaw(sprintf("LOWER(alias)='%s'",strtolower($this->mo->to)));
|
->orWhereRaw(sprintf("LOWER(alias)='%s'",strtolower(utf8_encode($this->mo->to))));
|
||||||
})
|
})
|
||||||
->whereNotNull('system_id')
|
->whereNotNull('system_id')
|
||||||
->single();
|
->single();
|
||||||
|
@ -129,6 +129,8 @@ class PacketProcess implements ShouldQueue
|
|||||||
if ($queue || (! $this->interactive))
|
if ($queue || (! $this->interactive))
|
||||||
Log::info(sprintf('%s:! Message [%s] will be sent to the queue to process',self::LOGKEY,$msg->msgid));
|
Log::info(sprintf('%s:! Message [%s] will be sent to the queue to process',self::LOGKEY,$msg->msgid));
|
||||||
|
|
||||||
|
//dump(['msg'=>$msg]);
|
||||||
|
Log::debug('***',['a']);
|
||||||
try {
|
try {
|
||||||
// Dispatch job.
|
// Dispatch job.
|
||||||
if ($queue || (! $this->interactive))
|
if ($queue || (! $this->interactive))
|
||||||
@ -136,10 +138,12 @@ class PacketProcess implements ShouldQueue
|
|||||||
else
|
else
|
||||||
MessageProcess::dispatchSync($msg->withoutRelations(),$this->nobot);
|
MessageProcess::dispatchSync($msg->withoutRelations(),$this->nobot);
|
||||||
|
|
||||||
|
Log::debug('***',['b']);
|
||||||
$count++;
|
$count++;
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error(sprintf('%s:! Got error dispatching message [%s] (%d:%s-%s).',self::LOGKEY,$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage()));
|
Log::debug('***',['c']);
|
||||||
|
Log::error(sprintf('%s:! Got error [%s] dispatching message [%s] (%d:%s-%s).',self::LOGKEY,get_class($e),$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
use App\Casts\CompressedString;
|
use App\Casts\CompressedStringOrNull;
|
||||||
use App\Traits\{QueryCacheableConfig,ScopeActive};
|
use App\Traits\{QueryCacheableConfig,ScopeActive};
|
||||||
|
|
||||||
class Domain extends Model
|
class Domain extends Model
|
||||||
@ -22,7 +22,7 @@ class Domain extends Model
|
|||||||
private const STATS_MONTHS = 6;
|
private const STATS_MONTHS = 6;
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'homepage' => CompressedString::class,
|
'homepage' => CompressedStringOrNull::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/* SCOPES */
|
/* SCOPES */
|
||||||
|
@ -9,7 +9,7 @@ use Illuminate\Support\Collection;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
use App\Casts\{CollectionOrNull,CompressedString};
|
use App\Casts\{CollectionOrNull,CompressedStringOrNull,UTF8StringOrNull};
|
||||||
use App\Classes\FTN\Message;
|
use App\Classes\FTN\Message;
|
||||||
use App\Interfaces\Packet;
|
use App\Interfaces\Packet;
|
||||||
use App\Traits\{MessageAttributes,MsgID,ParseAddresses,QueryCacheableConfig};
|
use App\Traits\{MessageAttributes,MsgID,ParseAddresses,QueryCacheableConfig};
|
||||||
@ -32,10 +32,16 @@ final class Echomail extends Model implements Packet
|
|||||||
public Address $tftn;
|
public Address $tftn;
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
|
'to' => UTF8StringOrNull::class,
|
||||||
|
'from' => UTF8StringOrNull::class,
|
||||||
|
'subject' => UTF8StringOrNull::class,
|
||||||
|
'origin' => UTF8StringOrNull::class,
|
||||||
|
'tearline' => UTF8StringOrNull::class,
|
||||||
|
'tagline' => UTF8StringOrNull::class,
|
||||||
'datetime' => 'datetime:Y-m-d H:i:s',
|
'datetime' => 'datetime:Y-m-d H:i:s',
|
||||||
'kludges' => CollectionOrNull::class,
|
'kludges' => CollectionOrNull::class,
|
||||||
'msg' => CompressedString::class,
|
'msg' => CompressedStringOrNull::class,
|
||||||
'msg_src' => CompressedString::class,
|
'msg_src' => CompressedStringOrNull::class,
|
||||||
'rogue_seenby' => CollectionOrNull::class,
|
'rogue_seenby' => CollectionOrNull::class,
|
||||||
'rogue_path' => CollectionOrNull::class, // @deprecated?
|
'rogue_path' => CollectionOrNull::class, // @deprecated?
|
||||||
];
|
];
|
||||||
|
@ -11,12 +11,11 @@ use Illuminate\Support\Facades\DB;
|
|||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
use App\Casts\{CollectionOrNull,CompressedString};
|
use App\Casts\{CollectionOrNull,CompressedStringOrNull};
|
||||||
use App\Traits\EncodeUTF8;
|
|
||||||
|
|
||||||
class File extends Model
|
class File extends Model
|
||||||
{
|
{
|
||||||
use SoftDeletes,EncodeUTF8;
|
use SoftDeletes;
|
||||||
|
|
||||||
private const LOGKEY = 'MF-';
|
private const LOGKEY = 'MF-';
|
||||||
private bool $no_export = FALSE;
|
private bool $no_export = FALSE;
|
||||||
@ -28,18 +27,13 @@ class File extends Model
|
|||||||
protected $casts = [
|
protected $casts = [
|
||||||
'kludges' => CollectionOrNull::class,
|
'kludges' => CollectionOrNull::class,
|
||||||
'datetime' => 'datetime:Y-m-d H:i:s',
|
'datetime' => 'datetime:Y-m-d H:i:s',
|
||||||
'desc' => CompressedString::class,
|
'desc' => CompressedStringOrNull::class,
|
||||||
'ldesc' => CompressedString::class,
|
'ldesc' => CompressedStringOrNull::class,
|
||||||
'rogue_seenby' => CollectionOrNull::class,
|
'rogue_seenby' => CollectionOrNull::class,
|
||||||
'rogue_path' => CollectionOrNull::class,
|
'rogue_path' => CollectionOrNull::class,
|
||||||
'size' => 'int',
|
'size' => 'int',
|
||||||
];
|
];
|
||||||
|
|
||||||
private const cast_utf8 = [
|
|
||||||
'desc',
|
|
||||||
'ldesc',
|
|
||||||
];
|
|
||||||
|
|
||||||
public static function boot()
|
public static function boot()
|
||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
|
@ -10,7 +10,7 @@ use Illuminate\Support\Collection;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
use App\Casts\{CollectionOrNull,CompressedString};
|
use App\Casts\{CollectionOrNull,CompressedStringOrNull,UTF8StringOrNull};
|
||||||
use App\Interfaces\Packet;
|
use App\Interfaces\Packet;
|
||||||
use App\Pivots\ViaPivot;
|
use App\Pivots\ViaPivot;
|
||||||
use App\Traits\{MessageAttributes,MsgID};
|
use App\Traits\{MessageAttributes,MsgID};
|
||||||
@ -32,10 +32,16 @@ final class Netmail extends Model implements Packet
|
|||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
|
'to' => UTF8StringOrNull::class,
|
||||||
|
'from' => UTF8StringOrNull::class,
|
||||||
|
'subject' => UTF8StringOrNull::class,
|
||||||
|
'origin' => UTF8StringOrNull::class,
|
||||||
|
'tearline' => UTF8StringOrNull::class,
|
||||||
|
'tagline' => UTF8StringOrNull::class,
|
||||||
'datetime' => 'datetime:Y-m-d H:i:s',
|
'datetime' => 'datetime:Y-m-d H:i:s',
|
||||||
'kludges' => CollectionOrNull::class,
|
'kludges' => CollectionOrNull::class,
|
||||||
'msg' => CompressedString::class,
|
'msg' => CompressedStringOrNull::class,
|
||||||
'msg_src' => CompressedString::class,
|
'msg_src' => CompressedStringOrNull::class,
|
||||||
'sent_at' => 'datetime:Y-m-d H:i:s',
|
'sent_at' => 'datetime:Y-m-d H:i:s',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode our data so that it can be serialised
|
|
||||||
*/
|
|
||||||
namespace App\Traits;
|
|
||||||
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
|
|
||||||
trait EncodeUTF8
|
|
||||||
{
|
|
||||||
private array $_encoded = []; // Remember what we've decoded - when calling getAttribute()
|
|
||||||
|
|
||||||
private function decode(array $values): void
|
|
||||||
{
|
|
||||||
$properties = (new \ReflectionClass($this))->getProperties();
|
|
||||||
|
|
||||||
$class = get_class($this);
|
|
||||||
|
|
||||||
foreach ($properties as $property) {
|
|
||||||
if ($property->isStatic())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$name = $property->getName();
|
|
||||||
$decode = in_array($name,self::cast_utf8);
|
|
||||||
|
|
||||||
if ($property->isPrivate())
|
|
||||||
$name = "\0{$class}\0{$name}";
|
|
||||||
elseif ($property->isProtected())
|
|
||||||
$name = "\0*\0{$name}";
|
|
||||||
|
|
||||||
if (! array_key_exists($name,$values))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$property->setAccessible(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$property->setValue(
|
|
||||||
$this,$decode ? utf8_decode($values[$name]) : $values[$name]
|
|
||||||
);
|
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
dd(['e'=>$e->getMessage(),'name'=>$name,'values'=>$values[$name],'decode'=>$decode]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function encode(): array
|
|
||||||
{
|
|
||||||
$values = [];
|
|
||||||
|
|
||||||
$properties = (new \ReflectionClass($this))->getProperties();
|
|
||||||
|
|
||||||
$class = get_class($this);
|
|
||||||
|
|
||||||
foreach ($properties as $property) {
|
|
||||||
// Dont serialize the validation error
|
|
||||||
if (($property->name === 'errors') || $property->isStatic())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$property->setAccessible(true);
|
|
||||||
|
|
||||||
if (! $property->isInitialized($this))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$name = $property->getName();
|
|
||||||
$encode = in_array($name,self::cast_utf8);
|
|
||||||
|
|
||||||
if ($property->isPrivate())
|
|
||||||
$name = "\0{$class}\0{$name}";
|
|
||||||
elseif ($property->isProtected())
|
|
||||||
$name = "\0*\0{$name}";
|
|
||||||
|
|
||||||
$property->setAccessible(true);
|
|
||||||
$value = $property->getValue($this);
|
|
||||||
$values[$name] = $encode ? utf8_encode($value) : $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAttribute($key)
|
|
||||||
{
|
|
||||||
if (in_array($key,self::cast_utf8) && Arr::get($this->attributes,$key) && (! Arr::get($this->_encoded,$key))) {
|
|
||||||
// We need to get it from the parent first, taking into account any casting
|
|
||||||
$this->attributes[$key] = utf8_decode(parent::getAttribute($key));
|
|
||||||
$this->_encoded[$key] = TRUE;
|
|
||||||
|
|
||||||
return $this->attributes[$key];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Arr::get($this->_encoded,$key) ? $this->attributes[$key] : parent::getAttribute($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setAttribute($key,$value)
|
|
||||||
{
|
|
||||||
return parent::setAttribute($key,in_array($key,self::cast_utf8) ? utf8_encode($value) : $value);
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,24 +15,11 @@ use App\Models\{Address,Echomail};
|
|||||||
|
|
||||||
trait MessageAttributes
|
trait MessageAttributes
|
||||||
{
|
{
|
||||||
use EncodeUTF8;
|
|
||||||
|
|
||||||
// Items we need to set when creating()
|
// Items we need to set when creating()
|
||||||
public Collection $set;
|
public Collection $set;
|
||||||
// Validation Errors
|
// Validation Errors
|
||||||
public ?MessageBag $errors = NULL;
|
public ?MessageBag $errors = NULL;
|
||||||
|
|
||||||
private const cast_utf8 = [
|
|
||||||
'to',
|
|
||||||
'from',
|
|
||||||
'subject',
|
|
||||||
'msg',
|
|
||||||
'msg_src',
|
|
||||||
'origin',
|
|
||||||
'tearline',
|
|
||||||
'tagline',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
Loading…
Reference in New Issue
Block a user