forked from GNUsocial/gnu-social
[TOOLS] Fix all errors found by PHPStan level 1
This commit is contained in:
parent
0da6ff05ed
commit
add8f4a52f
@ -86,6 +86,7 @@ class Avatar extends Controller
|
|||||||
$form->addError(new FormError(_m('No avatar set, so cannot delete')));
|
$form->addError(new FormError(_m('No avatar set, so cannot delete')));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
$attachment = null;
|
||||||
if (isset($data['hidden'])) {
|
if (isset($data['hidden'])) {
|
||||||
// Cropped client side
|
// Cropped client side
|
||||||
$matches = [];
|
$matches = [];
|
||||||
@ -95,26 +96,25 @@ class Avatar extends Controller
|
|||||||
$data_user = base64_decode($data_user);
|
$data_user = base64_decode($data_user);
|
||||||
$tempfile = new TemporaryFile(['prefix' => 'gs-avatar']);
|
$tempfile = new TemporaryFile(['prefix' => 'gs-avatar']);
|
||||||
$tempfile->write($data_user);
|
$tempfile->write($data_user);
|
||||||
|
$attachment = GSFile::sanitizeAndStoreFileAsAttachment($tempfile);
|
||||||
} else {
|
} else {
|
||||||
Log::info('Avatar upload got an invalid encoding, something\'s fishy and/or wrong');
|
Log::info('Avatar upload got an invalid encoding, something\'s fishy and/or wrong');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif (isset($data['avatar'])) {
|
} elseif (isset($data['avatar'])) {
|
||||||
// Cropping failed (e.g. disabled js), use file as uploaded
|
// Cropping failed (e.g. disabled js), use file as uploaded
|
||||||
$file = $data['avatar'];
|
$file = $data['avatar'];
|
||||||
|
$attachment = GSFile::sanitizeAndStoreFileAsAttachment($file);
|
||||||
} else {
|
} else {
|
||||||
throw new ClientException('Invalid form');
|
throw new ClientException('Invalid form');
|
||||||
}
|
}
|
||||||
$attachment = GSFile::sanitizeAndStoreFileAsAttachment(
|
|
||||||
$file
|
|
||||||
);
|
|
||||||
// Delete current avatar if there's one
|
// Delete current avatar if there's one
|
||||||
$avatar = DB::find('avatar', ['gsactor_id' => $gsactor_id]);
|
$avatar = DB::find('avatar', ['gsactor_id' => $gsactor_id]);
|
||||||
$avatar?->delete();
|
$avatar?->delete();
|
||||||
DB::persist($attachment);
|
DB::persist($attachment);
|
||||||
// Can only get new id after inserting
|
// Can only get new id after inserting
|
||||||
DB::flush();
|
DB::flush();
|
||||||
DB::persist(AvatarEntity::create(['gsactor_id' => $gsactor_id, 'attachment_id' => $attachment->getId(), 'filename' => $file->getClientOriginalName()]));
|
DB::persist(AvatarEntity::create(['gsactor_id' => $gsactor_id, 'attachment_id' => $attachment->getId()]));
|
||||||
DB::flush();
|
DB::flush();
|
||||||
Event::handle('AvatarUpdate', [$user->getId()]);
|
Event::handle('AvatarUpdate', [$user->getId()]);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ define('PUBLICDIR', INSTALLDIR . '/public');
|
|||||||
define('GNUSOCIAL_ENGINE_NAME', 'GNU social');
|
define('GNUSOCIAL_ENGINE_NAME', 'GNU social');
|
||||||
// MERGE Change to https://gnu.io/social/
|
// MERGE Change to https://gnu.io/social/
|
||||||
define('GNUSOCIAL_PROJECT_URL', 'https://gnusocial.rocks/');
|
define('GNUSOCIAL_PROJECT_URL', 'https://gnusocial.rocks/');
|
||||||
|
define('GNUSOCIAL_ENGINE_URL', GNUSOCIAL_PROJECT_URL);
|
||||||
// MERGE Change to https://git.gnu.io/gnu/gnu-social
|
// MERGE Change to https://git.gnu.io/gnu/gnu-social
|
||||||
define('GNUSOCIAL_REPOSITORY_URL', 'https://code.undefinedhackers.net/GNUsocial/gnu-social');
|
define('GNUSOCIAL_REPOSITORY_URL', 'https://code.undefinedhackers.net/GNUsocial/gnu-social');
|
||||||
// Current base version, major.minor.patch
|
// Current base version, major.minor.patch
|
||||||
@ -39,6 +40,8 @@ define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
|
|||||||
define('GNUSOCIAL_CODENAME', 'Big bang');
|
define('GNUSOCIAL_CODENAME', 'Big bang');
|
||||||
define('URL_REGEX_DOMAIN_NAME', '(?:(?!-)[A-Za-z0-9\-]{1,63}(?<!-)\.)+[A-Za-z]{2,10}');
|
define('URL_REGEX_DOMAIN_NAME', '(?:(?!-)[A-Za-z0-9\-]{1,63}(?<!-)\.)+[A-Za-z]{2,10}');
|
||||||
|
|
||||||
|
define('MODULE_CACHE_FILE', INSTALLDIR . '/var/cache/module_manager.php');
|
||||||
|
|
||||||
// Work internally in UTC
|
// Work internally in UTC
|
||||||
date_default_timezone_set('UTC');
|
date_default_timezone_set('UTC');
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ class TypeResponse extends JsonResponse
|
|||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function __construct($data = null, int $status = 202, array $headers = [], bool $json = false)
|
public function __construct($data = null, int $status = 202)
|
||||||
{
|
{
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
data: !is_null($data) ? $data->toJson() : null,
|
data: !is_null($data) ? $data->toJson() : null,
|
||||||
|
@ -31,6 +31,8 @@ abstract class AbstractObject
|
|||||||
*/
|
*/
|
||||||
private array $_props = [];
|
private array $_props = [];
|
||||||
|
|
||||||
|
protected string $type = 'AbstractObject';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard setter method
|
* Standard setter method
|
||||||
* - Perform content validation if a validator exists
|
* - Perform content validation if a validator exists
|
||||||
|
@ -77,28 +77,32 @@ class Favourite extends NoteHandlerPlugin
|
|||||||
|
|
||||||
// Form handler
|
// Form handler
|
||||||
$ret = self::noteActionHandle(
|
$ret = self::noteActionHandle(
|
||||||
$request, $form_fav, $note, "favourite-{$note->getId()}", /**
|
$request, $form_fav, $note, "favourite-{$note->getId()}",
|
||||||
* Called from form handler
|
/**
|
||||||
*
|
* Called from form handler
|
||||||
* @param $note Note to be favourited
|
*
|
||||||
* @param $data Form input
|
* @param $note Note to be favourited
|
||||||
*
|
* @param $data Form input
|
||||||
* @throws RedirectException Always thrown in order to prevent accidental form re-submit from browser
|
*
|
||||||
*/ function ($note, $data) use ($opts, $request) {
|
* @throws RedirectException Always thrown in order to prevent accidental form re-submit from browser
|
||||||
$favourite_note = DB::find('favourite', $opts);
|
*/
|
||||||
if ($data["favourite-{$note->getId()}"] === '0' && $favourite_note === null) {
|
function ($note, $data) use ($opts) {
|
||||||
DB::persist(Entity\Favourite::create($opts));
|
$favourite_note = DB::find('favourite', $opts);
|
||||||
DB::flush();
|
if ($data["favourite-{$note->getId()}"] === '0' && $favourite_note === null) {
|
||||||
} else if ($data["favourite-{$note->getId()}"] === '1' && $favourite_note !== null) {
|
DB::persist(Entity\Favourite::create($opts));
|
||||||
DB::remove($favourite_note);
|
DB::flush();
|
||||||
DB::flush();
|
} else {
|
||||||
}
|
if ($data["favourite-{$note->getId()}"] === '1' && $favourite_note !== null) {
|
||||||
|
DB::remove($favourite_note);
|
||||||
|
DB::flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prevent accidental refreshes from resubmitting the form
|
// Prevent accidental refreshes from resubmitting the form
|
||||||
throw new RedirectException();
|
throw new RedirectException();
|
||||||
|
|
||||||
return Event::stop;
|
return Event::stop;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($ret !== null) {
|
if ($ret !== null) {
|
||||||
return $ret;
|
return $ret;
|
||||||
|
@ -61,7 +61,7 @@ class Repeat extends NoteHandlerPlugin
|
|||||||
|
|
||||||
// Handle form
|
// Handle form
|
||||||
$ret = self::noteActionHandle(
|
$ret = self::noteActionHandle(
|
||||||
$request, $form_repeat, $note, "repeat-{$note->getId()}", function ($note, $data, $user) use ($opts) {
|
$request, $form_repeat, $note, "repeat-{$note->getId()}", function ($note, $data, $user) {
|
||||||
if ($data["repeat-{$note->getId()}"] === '0') {
|
if ($data["repeat-{$note->getId()}"] === '0') {
|
||||||
DB::persist(Note::create([
|
DB::persist(Note::create([
|
||||||
'gsactor_id' => $user->getId(),
|
'gsactor_id' => $user->getId(),
|
||||||
|
@ -79,6 +79,7 @@ class AdminPanel extends Controller
|
|||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$value = null;
|
||||||
foreach ([
|
foreach ([
|
||||||
'int' => FILTER_VALIDATE_INT,
|
'int' => FILTER_VALIDATE_INT,
|
||||||
'bool' => FILTER_VALIDATE_BOOL,
|
'bool' => FILTER_VALIDATE_BOOL,
|
||||||
|
@ -47,11 +47,6 @@ class Note extends Controller
|
|||||||
*/
|
*/
|
||||||
public function note_show(Request $request, int $id)
|
public function note_show(Request $request, int $id)
|
||||||
{
|
{
|
||||||
return $this->note($id, function ($note) use ($id) {
|
return $this->note($id, fn ($note) => ['_template' => 'note/view.html.twig', 'note' => $note]);
|
||||||
return [
|
|
||||||
'_template' => 'note/view.html.twig',
|
|
||||||
'note' => $note,
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ abstract class Cache
|
|||||||
->lTrim($key, -$max_count ?? 0, -1)
|
->lTrim($key, -$max_count ?? 0, -1)
|
||||||
->exec();
|
->exec();
|
||||||
} else {
|
} else {
|
||||||
self::set($key, $value, $pool, $beta);
|
self::set($key, $value, $pool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ abstract class Cache
|
|||||||
$count = count($res);
|
$count = count($res);
|
||||||
$res = array_slice($res, $count - $max_count, $count); // Trim the older values
|
$res = array_slice($res, $count - $max_count, $count); // Trim the older values
|
||||||
}
|
}
|
||||||
self::set($key, $res, $pool, $beta);
|
self::set($key, $res, $pool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,11 @@ use Symfony\Component\HttpKernel\Event\ExceptionEvent;
|
|||||||
use Symfony\Component\HttpKernel\Event\ViewEvent;
|
use Symfony\Component\HttpKernel\Event\ViewEvent;
|
||||||
use Symfony\Component\HttpKernel\KernelEvents;
|
use Symfony\Component\HttpKernel\KernelEvents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method int int(string $param)
|
||||||
|
* @method bool bool(string $param)
|
||||||
|
* @method string string(string $param)
|
||||||
|
*/
|
||||||
class Controller extends AbstractController implements EventSubscriberInterface
|
class Controller extends AbstractController implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
private array $vars = [];
|
private array $vars = [];
|
||||||
|
@ -42,7 +42,10 @@ use Doctrine\ORM\Query;
|
|||||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||||
use Functional as F;
|
use Functional as F;
|
||||||
|
|
||||||
abstract class DB
|
/**
|
||||||
|
* @mixin EntityManagerInterface
|
||||||
|
*/
|
||||||
|
class DB
|
||||||
{
|
{
|
||||||
private static ?EntityManagerInterface $em;
|
private static ?EntityManagerInterface $em;
|
||||||
public static function setManager($m): void
|
public static function setManager($m): void
|
||||||
|
@ -20,13 +20,25 @@
|
|||||||
namespace App\Core;
|
namespace App\Core;
|
||||||
|
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
|
* @mixin HttpClientInterface
|
||||||
|
*
|
||||||
|
* @method static ResponseInterface head(string $url, array $options = [])
|
||||||
|
* @method static ResponseInterface get(string $url, array $options = [])
|
||||||
|
* @method static ResponseInterface post(string $url, array $options = [])
|
||||||
|
* @method static ResponseInterface put(string $url, array $options = [])
|
||||||
|
* @method static ResponseInterface delete(string $url, array $options = [])
|
||||||
|
* @method static ResponseInterface connect(string $url, array $options = [])
|
||||||
|
* @method static ResponseInterface options(string $url, array $options = [])
|
||||||
|
* @method static ResponseInterface trace(string $url, array $options = [])
|
||||||
|
* @method static ResponseInterface patch(string $url, array $options = [])
|
||||||
*/
|
*/
|
||||||
abstract class HTTPClient
|
abstract class HTTPClient
|
||||||
{
|
{
|
||||||
private static ?Httpclientinterface $client;
|
private static ?HttpClientInterface $client;
|
||||||
public static function setClient(HttpClientInterface $client)
|
public static function setClient(HttpClientInterface $client)
|
||||||
{
|
{
|
||||||
self::$client = $client;
|
self::$client = $client;
|
||||||
|
@ -316,7 +316,7 @@ function _m(...$args): string
|
|||||||
// Get the file where this function was called from, reducing the
|
// Get the file where this function was called from, reducing the
|
||||||
// memory and performance impact by not returning the arguments,
|
// memory and performance impact by not returning the arguments,
|
||||||
// and only 2 frames (this and previous)
|
// and only 2 frames (this and previous)
|
||||||
$domain = I18n::_mdomain(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)[0]['file'], 2);
|
$domain = I18n::_mdomain(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[0]['file']);
|
||||||
switch (count($args)) {
|
switch (count($args)) {
|
||||||
case 1:
|
case 1:
|
||||||
// Empty parameters, simple message
|
// Empty parameters, simple message
|
||||||
|
@ -34,6 +34,9 @@ namespace App\Core;
|
|||||||
use App\Util\Exception\ServerException;
|
use App\Util\Exception\ServerException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @mixin LoggerInterface
|
||||||
|
*/
|
||||||
abstract class Log
|
abstract class Log
|
||||||
{
|
{
|
||||||
private static ?LoggerInterface $logger;
|
private static ?LoggerInterface $logger;
|
||||||
|
@ -46,13 +46,6 @@ use Symfony\Component\DependencyInjection\Reference;
|
|||||||
|
|
||||||
class ModuleManager
|
class ModuleManager
|
||||||
{
|
{
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
if (!defined('CACHE_FILE')) {
|
|
||||||
define('CACHE_FILE', INSTALLDIR . '/var/cache/module_manager.php');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static $loader;
|
protected static $loader;
|
||||||
/** @codeCoverageIgnore */
|
/** @codeCoverageIgnore */
|
||||||
public static function setLoader($l)
|
public static function setLoader($l)
|
||||||
@ -128,7 +121,7 @@ class ModuleManager
|
|||||||
|
|
||||||
$module_manager->preRegisterEvents();
|
$module_manager->preRegisterEvents();
|
||||||
|
|
||||||
file_put_contents(CACHE_FILE, "<?php\nreturn " . var_export($module_manager, true) . ';');
|
file_put_contents(MODULE_CACHE_FILE, "<?php\nreturn " . var_export($module_manager, true) . ';');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,7 +143,7 @@ class ModuleManager
|
|||||||
*/
|
*/
|
||||||
public function loadModules()
|
public function loadModules()
|
||||||
{
|
{
|
||||||
if ($_ENV['APP_ENV'] === 'prod' && !file_exists(CACHE_FILE)) {
|
if ($_ENV['APP_ENV'] === 'prod' && !file_exists(MODULE_CACHE_FILE)) {
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
throw new \Exception('The application needs to be compiled before using in production');
|
throw new \Exception('The application needs to be compiled before using in production');
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
@ -158,7 +151,7 @@ class ModuleManager
|
|||||||
$rdi = new AppendIterator();
|
$rdi = new AppendIterator();
|
||||||
$rdi->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(INSTALLDIR . '/components', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS)));
|
$rdi->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(INSTALLDIR . '/components', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS)));
|
||||||
$rdi->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(INSTALLDIR . '/plugins', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS)));
|
$rdi->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(INSTALLDIR . '/plugins', FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS)));
|
||||||
$time = file_exists(CACHE_FILE) ? filemtime(CACHE_FILE) : 0;
|
$time = file_exists(MODULE_CACHE_FILE) ? filemtime(MODULE_CACHE_FILE) : 0;
|
||||||
|
|
||||||
if ($_ENV['APP_ENV'] === 'test' || F\some($rdi, function ($e) use ($time) { return $e->getMTime() > $time; })) {
|
if ($_ENV['APP_ENV'] === 'test' || F\some($rdi, function ($e) use ($time) { return $e->getMTime() > $time; })) {
|
||||||
Log::info('Rebuilding plugin cache at runtime. This means we can\'t update DB definitions');
|
Log::info('Rebuilding plugin cache at runtime. This means we can\'t update DB definitions');
|
||||||
@ -166,7 +159,7 @@ class ModuleManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$obj = require CACHE_FILE;
|
$obj = require MODULE_CACHE_FILE;
|
||||||
|
|
||||||
foreach ($obj->modules as $module) {
|
foreach ($obj->modules as $module) {
|
||||||
$module->loadConfig();
|
$module->loadConfig();
|
||||||
|
@ -31,8 +31,11 @@
|
|||||||
namespace App\Core\Router;
|
namespace App\Core\Router;
|
||||||
|
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
use Symfony\Component\Routing\Router as SRouter;
|
use Symfony\Component\Routing\Router as SymfonyRouter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @mixin SymfonyRouter
|
||||||
|
*/
|
||||||
abstract class Router
|
abstract class Router
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -58,7 +61,7 @@ abstract class Router
|
|||||||
*/
|
*/
|
||||||
const NETWORK_PATH = UrlGeneratorInterface::NETWORK_PATH;
|
const NETWORK_PATH = UrlGeneratorInterface::NETWORK_PATH;
|
||||||
|
|
||||||
public static ?SRouter $router = null;
|
public static ?SymfonyRouter $router = null;
|
||||||
public static ?UrlGeneratorInterface $url_gen = null;
|
public static ?UrlGeneratorInterface $url_gen = null;
|
||||||
|
|
||||||
public static function setServices($rtr, $gen): void
|
public static function setServices($rtr, $gen): void
|
||||||
|
@ -31,17 +31,19 @@
|
|||||||
namespace App\Core;
|
namespace App\Core;
|
||||||
|
|
||||||
use HtmlSanitizer\SanitizerInterface;
|
use HtmlSanitizer\SanitizerInterface;
|
||||||
use Symfony\Component\Security\Core\Security as SSecurity;
|
use Symfony\Component\Security\Core\Security as SymfonySecurity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forwards method calls to either Symfony\Component\Security\Core\Security or
|
* Forwards method calls to either Symfony\Component\Security\Core\Security or
|
||||||
* HtmlSanitizer\SanitizerInterface, calling the first existing method, in that order
|
* HtmlSanitizer\SanitizerInterface, calling the first existing method, in that order
|
||||||
*
|
*
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
|
* @mixin SymfonySecurity
|
||||||
|
* @mixin SanitizerInterface
|
||||||
*/
|
*/
|
||||||
abstract class Security
|
abstract class Security
|
||||||
{
|
{
|
||||||
private static ?SSecurity $security;
|
private static ?SymfonySecurity $security;
|
||||||
private static ?SanitizerInterface $sanitizer;
|
private static ?SanitizerInterface $sanitizer;
|
||||||
|
|
||||||
public static function setHelper($sec, $san): void
|
public static function setHelper($sec, $san): void
|
||||||
|
@ -33,6 +33,8 @@ abstract class Bitmap
|
|||||||
{
|
{
|
||||||
$init = $r;
|
$init = $r;
|
||||||
$class = static::class;
|
$class = static::class;
|
||||||
|
$obj = null;
|
||||||
|
$vals = null;
|
||||||
if ($instance) {
|
if ($instance) {
|
||||||
$obj = new $class;
|
$obj = new $class;
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,7 +50,8 @@ class AttachmentTest extends GNUsocialTestCase
|
|||||||
static::assertTrue($attachment->deleteStorage());
|
static::assertTrue($attachment->deleteStorage());
|
||||||
static::assertFalse(file_exists($path));
|
static::assertFalse(file_exists($path));
|
||||||
static::assertNull($attachment->getPath());
|
static::assertNull($attachment->getPath());
|
||||||
DB::flush($attachment);
|
DB::persist($attachment);
|
||||||
|
DB::flush();
|
||||||
|
|
||||||
// Setup the second attachment, re-adding the backed store
|
// Setup the second attachment, re-adding the backed store
|
||||||
$file = new TemporaryFile();
|
$file = new TemporaryFile();
|
||||||
|
Loading…
Reference in New Issue
Block a user