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\Database\Eloquent\Model;
|
||||
|
||||
class CompressedString implements CastsAttributes
|
||||
class CompressedStringOrNull implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Cast the given value.
|
||||
*
|
||||
* For postgresl bytea columns the value is a resource stream
|
||||
*
|
||||
* @param Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @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.
|
||||
if (is_resource($value))
|
||||
@ -28,13 +27,7 @@ class CompressedString implements CastsAttributes
|
||||
? stream_get_contents($value)
|
||||
: $value;
|
||||
|
||||
// If we get an error decompressing, it might not be zstd (or its already been done)
|
||||
try {
|
||||
return $value ? zstd_uncompress(base64_decode($value)) : '';
|
||||
|
||||
} catch (\ErrorException $e) {
|
||||
return $value;
|
||||
}
|
||||
return $value ? zstd_uncompress(base64_decode($value)) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,10 +37,10 @@ class CompressedString implements CastsAttributes
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @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\Models\{Echomail,Netmail,User};
|
||||
use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,NetmailForward,NetmailHubNoUser};
|
||||
use App\Traits\{EncodeUTF8,ParseAddresses};
|
||||
use App\Traits\ParseAddresses;
|
||||
|
||||
class MessageProcess implements ShouldQueue
|
||||
{
|
||||
private const LOGKEY = 'JMP';
|
||||
|
||||
use Dispatchable,InteractsWithQueue,Queueable,SerializesModels,ParseAddresses,EncodeUTF8;
|
||||
use Dispatchable,InteractsWithQueue,Queueable,SerializesModels,ParseAddresses;
|
||||
|
||||
private Echomail|Netmail|string $mo;
|
||||
private bool $skipbot;
|
||||
|
||||
private const cast_utf8 = [
|
||||
'mo',
|
||||
];
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* + 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
|
||||
$uo = User::active()
|
||||
->where(function($query) {
|
||||
return $query->whereRaw(sprintf("LOWER(name)='%s'",strtolower($this->mo->to)))
|
||||
->orWhereRaw(sprintf("LOWER(alias)='%s'",strtolower($this->mo->to)));
|
||||
return $query->whereRaw(sprintf("LOWER(name)='%s'",strtolower(utf8_encode($this->mo->to))))
|
||||
->orWhereRaw(sprintf("LOWER(alias)='%s'",strtolower(utf8_encode($this->mo->to))));
|
||||
})
|
||||
->whereNotNull('system_id')
|
||||
->single();
|
||||
|
@ -129,6 +129,8 @@ class PacketProcess implements ShouldQueue
|
||||
if ($queue || (! $this->interactive))
|
||||
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 {
|
||||
// Dispatch job.
|
||||
if ($queue || (! $this->interactive))
|
||||
@ -136,10 +138,12 @@ class PacketProcess implements ShouldQueue
|
||||
else
|
||||
MessageProcess::dispatchSync($msg->withoutRelations(),$this->nobot);
|
||||
|
||||
Log::debug('***',['b']);
|
||||
$count++;
|
||||
|
||||
} 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\DB;
|
||||
|
||||
use App\Casts\CompressedString;
|
||||
use App\Casts\CompressedStringOrNull;
|
||||
use App\Traits\{QueryCacheableConfig,ScopeActive};
|
||||
|
||||
class Domain extends Model
|
||||
@ -22,7 +22,7 @@ class Domain extends Model
|
||||
private const STATS_MONTHS = 6;
|
||||
|
||||
protected $casts = [
|
||||
'homepage' => CompressedString::class,
|
||||
'homepage' => CompressedStringOrNull::class,
|
||||
];
|
||||
|
||||
/* SCOPES */
|
||||
|
@ -9,7 +9,7 @@ use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Casts\{CollectionOrNull,CompressedString};
|
||||
use App\Casts\{CollectionOrNull,CompressedStringOrNull,UTF8StringOrNull};
|
||||
use App\Classes\FTN\Message;
|
||||
use App\Interfaces\Packet;
|
||||
use App\Traits\{MessageAttributes,MsgID,ParseAddresses,QueryCacheableConfig};
|
||||
@ -32,10 +32,16 @@ final class Echomail extends Model implements Packet
|
||||
public Address $tftn;
|
||||
|
||||
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',
|
||||
'kludges' => CollectionOrNull::class,
|
||||
'msg' => CompressedString::class,
|
||||
'msg_src' => CompressedString::class,
|
||||
'msg' => CompressedStringOrNull::class,
|
||||
'msg_src' => CompressedStringOrNull::class,
|
||||
'rogue_seenby' => CollectionOrNull::class,
|
||||
'rogue_path' => CollectionOrNull::class, // @deprecated?
|
||||
];
|
||||
|
@ -11,12 +11,11 @@ use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
use App\Casts\{CollectionOrNull,CompressedString};
|
||||
use App\Traits\EncodeUTF8;
|
||||
use App\Casts\{CollectionOrNull,CompressedStringOrNull};
|
||||
|
||||
class File extends Model
|
||||
{
|
||||
use SoftDeletes,EncodeUTF8;
|
||||
use SoftDeletes;
|
||||
|
||||
private const LOGKEY = 'MF-';
|
||||
private bool $no_export = FALSE;
|
||||
@ -28,18 +27,13 @@ class File extends Model
|
||||
protected $casts = [
|
||||
'kludges' => CollectionOrNull::class,
|
||||
'datetime' => 'datetime:Y-m-d H:i:s',
|
||||
'desc' => CompressedString::class,
|
||||
'ldesc' => CompressedString::class,
|
||||
'desc' => CompressedStringOrNull::class,
|
||||
'ldesc' => CompressedStringOrNull::class,
|
||||
'rogue_seenby' => CollectionOrNull::class,
|
||||
'rogue_path' => CollectionOrNull::class,
|
||||
'size' => 'int',
|
||||
];
|
||||
|
||||
private const cast_utf8 = [
|
||||
'desc',
|
||||
'ldesc',
|
||||
];
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
@ -10,7 +10,7 @@ use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Casts\{CollectionOrNull,CompressedString};
|
||||
use App\Casts\{CollectionOrNull,CompressedStringOrNull,UTF8StringOrNull};
|
||||
use App\Interfaces\Packet;
|
||||
use App\Pivots\ViaPivot;
|
||||
use App\Traits\{MessageAttributes,MsgID};
|
||||
@ -32,10 +32,16 @@ final class Netmail extends Model implements Packet
|
||||
];
|
||||
|
||||
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',
|
||||
'kludges' => CollectionOrNull::class,
|
||||
'msg' => CompressedString::class,
|
||||
'msg_src' => CompressedString::class,
|
||||
'msg' => CompressedStringOrNull::class,
|
||||
'msg_src' => CompressedStringOrNull::class,
|
||||
'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
|
||||
{
|
||||
use EncodeUTF8;
|
||||
|
||||
// Items we need to set when creating()
|
||||
public Collection $set;
|
||||
// Validation Errors
|
||||
public ?MessageBag $errors = NULL;
|
||||
|
||||
private const cast_utf8 = [
|
||||
'to',
|
||||
'from',
|
||||
'subject',
|
||||
'msg',
|
||||
'msg_src',
|
||||
'origin',
|
||||
'tearline',
|
||||
'tagline',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
Loading…
Reference in New Issue
Block a user