Commit de986064 authored by Emiliano Balbuena's avatar Emiliano Balbuena

(feat): Pro FS endpoint; support custom assets

1 merge request!375WIP: Pro logo and background upload
Pipeline #89349108 failed with stages
in 4 minutes and 8 seconds
<?php
/**
* pro
* @author edgebal
*/
namespace Minds\Controllers\fs\v1;
use Minds\Core\Pro\Assets\Asset;
use Minds\Interfaces;
class pro implements Interfaces\FS
{
/**
* Equivalent to HTTP GET method
* @param array $pages
* @return mixed|null
* @throws \IOException
* @throws \InvalidParameterException
* @throws \Exception
*/
public function get($pages)
{
$asset = new Asset();
$asset
->setType($pages[1] ?? null)
->setUserGuid($pages[0] ?? null);
$file = $asset->getFile();
$file->open('read');
$contents = $file->read();
header(sprintf("Content-Type: %s", $asset->getMimeType()));
header(sprintf("Expires: %s", date('r', time() + 864000)));
header('Pragma: public');
header('Cache-Control: public');
echo $contents;
exit;
}
}
<?php
/**
* Info
* @author edgebal
*/
namespace Minds\Core\Pro\Assets;
use ElggFile;
use Exception;
use Minds\Traits\MagicAttributes;
/**
* Class Asset
* @package Minds\Core\Pro\Assets
* @method string getType()
* @method int|string getUserGuid()
* @method Asset setUserGuid(int|string $userGuid)
*/
class Asset
{
use MagicAttributes;
/** @var string */
protected $type;
/** @var int|string */
protected $userGuid;
/** @var string[] */
const TYPES = ['logo', 'background'];
/**
* @param string $type
* @return Asset
* @throws Exception
*/
public function setType(string $type): Asset
{
if (!in_array($type, static::TYPES, true)) {
throw new Exception('Invalid Asset type');
}
$this->type = $type;
return $this;
}
/**
* @return string
* @throws Exception
*/
public function getExt(): string
{
switch ($this->type) {
case 'logo':
return 'png';
case 'background':
return 'jpg';
}
throw new Exception('Invalid Asset');
}
/**
* @return string
* @throws Exception
*/
public function getMimeType(): string
{
switch ($this->type) {
case 'logo':
return 'image/png';
case 'background':
return 'image/jpg';
}
throw new Exception('Invalid Asset');
}
/**
* @return ElggFile
* @throws Exception
*/
public function getFile(): ElggFile
{
$file = new ElggFile();
$file->owner_guid = $this->userGuid;
$file->setFilename(sprintf("pro/%s.%s", $this->type, $this->getExt()));
return $file;
}
}
......@@ -27,9 +27,6 @@ class Manager
/** @var User */
protected $actor;
/** @var string[] */
const TYPES = ['logo', 'background'];
/**
* Manager constructor.
* @param ImageManager $imageManager
......@@ -79,7 +76,7 @@ class Manager
{
if (!$this->user) {
throw new Exception('Invalid user');
} elseif (!$this->type || !in_array($this->type, static::TYPES, true)) {
} elseif (!$this->type || !in_array($this->type, Asset::TYPES, true)) {
throw new Exception('Invalid asset type');
}
......@@ -91,18 +88,23 @@ class Manager
$file->getClientFilename()
);
// Setup asset
$asset = new Asset();
$asset
->setType($this->type)
->setUserGuid($this->user->guid);
// Handle asset type
switch ($this->type) {
case 'logo':
$ext = 'png';
$blob = $this->imageManager
->resize(1920, 1080, false, false) // Max: 2K
->getPng();
break;
case 'background':
$ext = 'jpg';
$blob = $this->imageManager
->autorotate()
->resize(3840, 2160, false, false) // Max: 4K
......@@ -113,9 +115,7 @@ class Manager
throw new Exception('Invalid asset type handler');
}
$file = new ElggFile();
$file->owner_guid = $this->user->guid;
$file->setFilename("pro/{$this->type}.{$ext}");
$file = $asset->getFile();
$file->open('write');
$file->write($blob);
$file->close();
......
......@@ -43,10 +43,11 @@ class HydrateSettingsDelegate
public function onGet(User $user, Settings $settings): Settings
{
try {
$logoImage = $settings->getLogoGuid() ? sprintf(
'%sfs/v1/thumbnail/%s/master',
$logoImage = $settings->hasCustomLogo() ? sprintf(
'%sfs/v1/pro/%s/logo/%s',
$this->config->get('cdn_url'),
$settings->getLogoGuid()
$settings->getUserGuid(),
$settings->getTimeUpdated()
) : $user->getIconURL('large');
if ($logoImage) {
......@@ -58,17 +59,32 @@ class HydrateSettingsDelegate
}
try {
$carousels = $this->entitiesBuilder->get(['subtype' => 'carousel', 'owner_guid' => (string) $user->guid]);
$carousel = $carousels[0] ?? null;
$backgroundImage = null;
if ($carousel) {
$settings
->setBackgroundImage(sprintf(
if ($settings->hasCustomBackground()) {
$backgroundImage = sprintf(
'%sfs/v1/pro/%s/background/%s',
$this->config->get('cdn_url'),
$settings->getUserGuid(),
$settings->getTimeUpdated()
);
} else {
$carousels = $this->entitiesBuilder->get(['subtype' => 'carousel', 'owner_guid' => (string) $user->guid]);
$carousel = $carousels[0] ?? null;
if ($carousel) {
$backgroundImage = sprintf(
'%sfs/v1/banners/%s/fat/%s',
$this->config->get('cdn_url'),
$carousel->guid,
$carousel->last_updated
));
);
}
}
if ($backgroundImage) {
$settings
->setBackgroundImage($backgroundImage);
}
} catch (\Exception $e) {
error_log($e);
......
......@@ -258,18 +258,6 @@ class Manager
->setTileRatio($values['tile_ratio']);
}
if (isset($values['logo_guid']) && $values['logo_guid'] !== '') {
$image = $this->entitiesBuilder->single($values['logo_guid']);
// if the image doesn't exist or the guid doesn't correspond to an image
if (!$image || ($image->type !== 'object' || $image->subtype !== 'image')) {
throw new \Exception('logo_guid must be a valid image guid');
}
$settings
->setLogoGuid(trim($values['logo_guid']));
}
if (isset($values['footer_text'])) {
$footer_text = trim($values['footer_text']);
......@@ -322,6 +310,16 @@ class Manager
->setCustomHead($values['custom_head']);
}
if (isset($values['has_custom_logo'])) {
$settings
->setHasCustomLogo((bool) $values['has_custom_logo']);
}
if (isset($values['has_custom_background'])) {
$settings
->setHasCustomBackground((bool) $values['has_custom_background']);
}
if (isset($values['published'])) {
$this->user->setProPublished($values['published']);
$this->saveAction
......@@ -329,6 +327,8 @@ class Manager
->save();
}
$settings->setTimeUpdated(time());
$this->setupRoutingDelegate
->onUpdate($settings);
......
......@@ -92,13 +92,15 @@ class Repository
->setTextColor($data['text_color'] ?? '')
->setPrimaryColor($data['primary_color'] ?? '')
->setPlainBackgroundColor($data['plain_background_color'] ?? '')
->setLogoGuid($data['logo_guid'] ?? '')
->setTileRatio($data['tile_ratio'] ?? '')
->setFooterText($data['footer_text'] ?? '')
->setFooterLinks($data['footer_links'] ?? [])
->setTagList($data['tag_list'] ?? [])
->setScheme($data['scheme'] ?? '')
->setCustomHead($data['custom_head'] ?? '')
->setHasCustomLogo($data['has_custom_logo'] ?? false)
->setHasCustomBackground($data['has_custom_background'] ?? false)
->setTimeUpdated($data['time_updated'] ?? 0)
;
$response[] = $settings;
......@@ -140,12 +142,14 @@ class Repository
'primary_color' => $settings->getPrimaryColor(),
'plain_background_color' => $settings->getPlainBackgroundColor(),
'tile_ratio' => $settings->getTileRatio(),
'logo_guid' => $settings->getLogoGuid(),
'footer_text' => $settings->getFooterText(),
'footer_links' => $settings->getFooterLinks(),
'tag_list' => $settings->getTagList(),
'scheme' => $settings->getScheme(),
'custom_head' => $settings->getCustomHead(),
'has_custom_logo' => $settings->hasCustomLogo(),
'has_custom_background' => $settings->hasCustomBackground(),
'time_updated' => $settings->getTimeUpdated(),
]),
];
......
......@@ -28,8 +28,6 @@ use Minds\Traits\MagicAttributes;
* @method Settings setPlainBackgroundColor(string $plainBackgroundColor)
* @method string getTileRatio()
* @method Settings setTileRatio(string $tileRatio)
* @method int|string getLogoGuid()
* @method Settings setLogoGuid(int|string $logoGuid)
* @method string getFooterText()
* @method Settings setFooterText(string $footerText)
* @method array getFooterLinks()
......@@ -48,6 +46,12 @@ use Minds\Traits\MagicAttributes;
* @method Settings setCustomHead(string $customHead)
* @method bool isPublished()
* @method Settings setPublished(bool $published)
* @method bool hasCustomLogo()
* @method Settings setHasCustomLogo(bool $customLogo)
* @method bool hasCustomBackground()
* @method Settings setHasCustomBackground(bool $customBackground)
* @method int getTimeUpdated()
* @method Settings setTimeUpdated(int $timeUpdated)
*/
class Settings implements JsonSerializable
{
......@@ -92,14 +96,17 @@ class Settings implements JsonSerializable
/** @var string */
protected $plainBackgroundColor;
/** @var int */
protected $logoGuid;
/** @var string */
protected $tileRatio = '16:9';
/** @var bool */
protected $hasCustomBackground;
/** @var string */
protected $backgroundImage;
/** @var string */
protected $tileRatio = '16:9';
/** @var bool */
protected $hasCustomLogo;
/** @var string */
protected $logoImage;
......@@ -125,6 +132,9 @@ class Settings implements JsonSerializable
/** @var bool */
protected $published;
/** @var int */
protected $timeUpdated;
/**
* @return string
*/
......@@ -155,15 +165,17 @@ class Settings implements JsonSerializable
'footer_text' => $this->footerText,
'footer_links' => $this->footerLinks,
'tag_list' => $this->tagList,
'logo_guid' => (string) $this->logoGuid,
'background_image' => $this->backgroundImage,
'has_custom_logo' => $this->hasCustomLogo,
'logo_image' => $this->logoImage,
'has_custom_background' => $this->hasCustomBackground,
'background_image' => $this->backgroundImage,
'featured_content' => $this->featuredContent,
'scheme' => $this->scheme,
'custom_head' => $this->customHead,
'one_line_headline' => $this->getOneLineHeadline(),
'styles' => $this->buildStyles(),
'published' => $this->published,
'time_updated' => $this->timeUpdated,
];
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment