Skip to content
Commits on Source (20)
<?php
namespace Minds\Controllers\Cli;
use Minds\Cli;
use Minds\Core\Events\Dispatcher;
use Minds\Interfaces;
class Notification extends Cli\Controller implements Interfaces\CliControllerInterface
{
public function help($command = null)
{
switch ($command) {
case 'send':
$this->out('Send a notification');
$this->out('--namespace=<type> Notification namespace');
$this->out('--to=<user guid> User to send notification to');
$this->out('--from=<entity guid> Entity notification is from (defaults to system user)');
$this->out('--view=<view> Notification view');
$this->out('--params=<params> JSON payload data');
// no break
default:
$this->out('Syntax usage: cli notification <cmd>');
$this->displayCommandHelp();
}
}
public function exec()
{
$this->help();
}
public function send()
{
$namespace = $this->getOpt('namespace');
$to = $this->getOpt('to');
$from = $this->getOpt('from') ?? \Minds\Core\Notification\Notification::SYSTEM_ENTITY;
$view = $this->getOpt('view');
$params = $this->getOpt('params') ?? '{}';
if (is_null($namespace)) {
$this->out('namespace must be set');
return;
}
if (is_null($to)) {
$this->out('to must be set');
return;
}
if (is_null($view)) {
$this->out('view must be set');
return;
}
$paramsDecoded = json_decode($params, true);
if (is_null($paramsDecoded)) {
$this->out('Params is not valid JSON');
return;
}
$eventParams = [
'to' => [$to],
'from' => $from,
'notification_view' => $view,
'params' => $paramsDecoded
];
$sent = Dispatcher::trigger('notification', $namespace, $eventParams);
if ($sent) {
$this->out('Notification sent');
} else {
$this->out('Error sending notification - is from guid valid?');
}
}
}
......@@ -31,7 +31,7 @@ class reports implements Interfaces\Api, Interfaces\ApiAdminPam
/** @var Core\Reports\Repository $repository */
$repository = Di::_()->get('Reports\Repository');
$reports = $repository->getAll([
$reports = $repository->getList([
'state' => $state,
'limit' => $limit,
'offset' => $offset
......
......@@ -344,14 +344,20 @@ class blog implements Interfaces\Api
}
if ($saved && is_uploaded_file($_FILES['file']['tmp_name'])) {
/** @var Core\Media\Imagick\Manager $manager */
$manager = Core\Di\Di::_()->get('Media\Imagick\Manager');
$manager->setImage($_FILES['file']['tmp_name'])
->resize(2000, 1000);
try {
$manager->setImage($_FILES['file']['tmp_name'])
->resize(2000, 1000);
$header->write($blog, $manager->getJpeg(), isset($_POST['header_top']) ? (int) $_POST['header_top'] : 0);
$header->write($blog, $manager->getJpeg(), isset($_POST['header_top']) ? (int)$_POST['header_top'] : 0);
} catch (\ImagickException $e) {
return Factory::response([
'status' => 'error',
'message' => 'Invalid image file',
]);
}
}
if ($saved) {
......
......@@ -13,6 +13,7 @@ use Minds\Helpers;
use Minds\Entities;
use Minds\Interfaces;
use Minds\Api\Factory;
use Minds\Core\Features\Manager as FeaturesManager;
class thumbnails implements Interfaces\Api, Interfaces\ApiIgnorePam
{
......@@ -28,6 +29,17 @@ class thumbnails implements Interfaces\Api, Interfaces\ApiIgnorePam
exit;
}
$featuresManager = new FeaturesManager();
if ($featuresManager->has('cdn-jwt')) {
error_log("{$_SERVER['REQUEST_URI']} was hit, and should not have been");
return Factory::response([
'status' => 'error',
'message' => 'This endpoint has been deprecated. Please use fs/v1/thumbnail',
]);
}
$guid = $pages[0];
Core\Security\ACL::$ignore = true;
......
......@@ -53,6 +53,7 @@ class views implements Interfaces\Api
$viewsManager->record(
(new Core\Analytics\Views\View())
->setEntityUrn($boost->getEntity()->getUrn())
->setOwnerGuid((string) $boost->getEntity()->getOwnerGuid())
->setClientMeta($_POST['client_meta'] ?? [])
);
} catch (\Exception $e) {
......@@ -105,6 +106,7 @@ class views implements Interfaces\Api
$viewsManager->record(
(new Core\Analytics\Views\View())
->setEntityUrn($activity->getUrn())
->setOwnerGuid((string) $activity->getOwnerGuid())
->setClientMeta($_POST['client_meta'] ?? [])
);
} catch (\Exception $e) {
......
......@@ -20,7 +20,14 @@ class connect implements Interfaces\Api
$connectManager = new Stripe\Connect\Manager();
$account = $connectManager->getByUser($user);
try {
$account = $connectManager->getByUser($user);
} catch (\Exception $e) {
return Factory::response([
'status' => 'error',
'message' => 'There was an error returning the usd account',
]);
}
return Factory::response([
'account' => $account->export(),
......
<?php
/**
*
*/
namespace Minds\Controllers\api\v2\payments\stripe\connect;
use Minds\Api\Factory;
use Minds\Common\Cookie;
use Minds\Core\Di\Di;
use Minds\Core\Config;
use Minds\Core\Session;
use Minds\Interfaces;
use Minds\Core\Payments\Stripe;
class photoid implements Interfaces\Api
{
public function get($pages)
{
return Factory::response([]);
}
public function post($pages)
{
$user = Session::getLoggedInUser();
$connectManager = new Stripe\Connect\Manager();
$account = $connectManager->getByUser($user);
$fp = fopen($_FILES['file']['tmp_name'], 'r');
$connectManager->addPhotoId($account, $fp);
return Factory::response([ 'account_id' => $account->getId() ]);
}
public function put($pages)
{
return Factory::response([]);
}
public function delete($pages)
{
return Factory::response([]);
}
}
<?php
/**
*
*/
namespace Minds\Controllers\api\v2\payments\stripe\connect;
use Minds\Api\Factory;
use Minds\Common\Cookie;
use Minds\Core\Di\Di;
use Minds\Core\Config;
use Minds\Core\Session;
use Minds\Interfaces;
use Minds\Core\Payments\Stripe;
class terms implements Interfaces\Api
{
public function get($pages)
{
return Factory::response([]);
}
public function post($pages)
{
return Factory::response([]);
}
public function put($pages)
{
$user = Session::getLoggedInUser();
$connectManager = new Stripe\Connect\Manager();
$account = $connectManager->getByUser($user);
$account->setIp($_SERVER['HTTP_X_FORWARDED_FOR']);
$connectManager->acceptTos($account);
return Factory::response([]);
}
public function delete($pages)
{
return Factory::response([]);
}
}
<?php
/**
*
*/
namespace Minds\Controllers\api\v2\payments\stripe;
use Minds\Api\Factory;
use Minds\Common\Cookie;
use Minds\Core\Di\Di;
use Minds\Core\Config;
use Minds\Core\Session;
use Minds\Interfaces;
use Minds\Core\Payments\Stripe;
class transactions implements Interfaces\Api
{
public function get($pages)
{
$user = Session::getLoggedInUser();
$connectManager = new Stripe\Connect\Manager();
try {
$account = $connectManager->getByUser($user);
} catch (\Exception $e) {
return Factory::response([
'status' => 'error',
'message' => 'There was an error returning the usd account',
]);
}
$transactionsManger = new Stripe\Transactions\Manager();
$transactions = $transactionsManger->getByAccount($account);
return Factory::response([
'transactions' => Factory::exportable($transactions),
]);
}
public function post($pages)
{
return Factory::response([]);
}
public function put($pages)
{
return Factory::response([]);
}
public function delete($pages)
{
return Factory::response([]);
}
}
......@@ -8,6 +8,7 @@ use Minds\Interfaces;
use Minds\Core\Entities\Actions\Save;
use Minds\Core\Session;
use Minds\Core\Permissions\Permissions;
use Minds\Core\Permissions\Entities\EntityPermissions;
class comments implements Interfaces\Api
{
......
......@@ -8,6 +8,7 @@ use Minds\Core;
use Minds\Core\Di\Di;
use Minds\Entities;
use Minds\Interfaces;
use Minds\Core\Features\Manager as FeaturesManager;
class thumbnail extends Core\page implements Interfaces\page
{
......@@ -17,6 +18,16 @@ class thumbnail extends Core\page implements Interfaces\page
exit;
}
$featuresManager = new FeaturesManager;
if ($featuresManager->has('cdn-jwt')) {
$signedUri = new Core\Security\SignedUri();
$uri = (string) \Zend\Diactoros\ServerRequestFactory::fromGlobals()->getUri();
if (!$signedUri->confirm($uri)) {
exit;
}
}
/** @var Core\Media\Thumbnails $mediaThumbnails */
$mediaThumbnails = Di::_()->get('Media\Thumbnails');
......
......@@ -55,6 +55,7 @@ class ElasticRepository
'uuid' => $view->getUuid(),
'@timestamp' => $view->getTimestamp() * 1000,
'entity_urn' => $view->getEntityUrn(),
'owner_guid' => $view->getOwnerGuid(),
'page_token' => $view->getPageToken(),
'campaign' => $view->getCampaign(),
'delta' => (int) $view->getDelta(),
......
......@@ -104,6 +104,7 @@ class Repository
->setDay((int) $row['day'] ?: null)
->setUuid($row['uuid']->uuid() ?: null)
->setEntityUrn($row['entity_urn'])
->setOwnerGuid($row['owner_guid'])
->setPageToken($row['page_token'])
->setPosition((int) $row['position'])
->setSource($row['platform'])
......@@ -135,13 +136,14 @@ class Repository
$timestamp = $view->getTimestamp() ?: time();
$date = new DateTime("@{$timestamp}", new DateTimeZone('utc'));
$cql = "INSERT INTO views (year, month, day, uuid, entity_urn, page_token, position, platform, source, medium, campaign, delta) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$cql = "INSERT INTO views (year, month, day, uuid, entity_urn, owner_guid, page_token, position, platform, source, medium, campaign, delta) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$values = [
(int) ($view->getYear() ?? $date->format('Y')),
new Tinyint((int) ($view->getMonth() ?? $date->format('m'))),
new Tinyint((int) ($view->getDay() ?? $date->format('d'))),
new Timeuuid($view->getUuid() ?? $timestamp * 1000),
$view->getEntityUrn() ?: '',
(string) ($view->getOwnerGuid() ?? ''),
$view->getPageToken() ?: '',
(int) ($view->getPosition() ?? -1),
$view->getPlatform() ?: '',
......
......@@ -21,6 +21,8 @@ use Minds\Traits\MagicAttributes;
* @method string getUuid()
* @method View setEntityUrn(string $entityUrn)
* @method string getEntityUrn()
* @method View setOwnerGuid(string $ownerGuid)
* @method string getOwnerGuid()
* @method View setPageToken(string $pageToken)
* @method string getPageToken()
* @method View setPosition(int $position)
......@@ -57,6 +59,9 @@ class View
/** @var string */
protected $entityUrn;
/** @var string */
protected $ownerGuid;
/** @var string */
protected $pageToken;
......
......@@ -9,6 +9,7 @@ use Minds\Entities\RepositoryEntity;
use Minds\Entities\User;
use Minds\Helpers\Flags;
use Minds\Helpers\Unknown;
use Minds\Core\Di\Di;
/**
* Comment Entity
......@@ -284,6 +285,21 @@ class Comment extends RepositoryEntity
return "{$this->getParentGuidL1()}:{$this->getParentGuidL2()}:{$this->getGuid()}";
}
/**
* Return an array of thumbnails
* @return array
*/
public function getThumbnails(): array
{
$thumbnails = [];
$mediaManager = Di::_()->get('Media\Image\Manager');
$sizes = [ 'xlarge', 'large' ];
foreach ($sizes as $size) {
$thumbnails[$size] = $mediaManager->getPublicAssetUri($this, $size);
}
return $thumbnails;
}
/**
* Return the urn for the comment
* @return string
......@@ -384,6 +400,8 @@ class Comment extends RepositoryEntity
$output['thumbs:down:count'] = count($this->getVotesDown());
}
$output['thumbnails'] = $this->getThumbnails();
$output['can_reply'] = (bool) !$this->getParentGuidL2();
//$output['parent_guid'] = (string) $this->entityGuid;
......
......@@ -5,21 +5,40 @@
namespace Minds\Core\Data\PubSub\Redis;
use Minds\Core\Config;
use \Redis as RedisServer;
class Client
{
/**
* @var \Redis
*/
private $redis;
/**
* @var string
*/
private $host;
public function __construct($redis = null)
{
if (class_exists('\Redis')) {
$this->redis = $redis ?: new RedisServer();
$this->redis = $redis ?: new \Redis();
$config = Config::_()->get('redis');
try {
$this->redis->connect($config['pubsub'] ?: $config['master'] ?: '127.0.0.1');
} catch (\Exception $e) {
$this->host = $config['pubsub'] ?: $config['master'] ?: '127.0.0.1';
$this->connect();
}
}
/**
* @throws \Exception
*/
public function connect(): void
{
if (!$this->redis instanceof \Redis) {
$this->redis = new \Redis();
}
if (!$this->redis->isConnected()) {
if (!@$this->redis->connect($this->host)) {
throw new \Exception("Unable to connect to Redis: " . $this->redis->getLastError());
}
}
}
......@@ -34,11 +53,17 @@ class Client
}
}
/**
* @param $channel
* @param string $data
* @return bool|int
*/
public function publish($channel, $data = '')
{
if (!$this->redis) {
if (!$this->redis->isConnected()) {
return false;
}
return $this->redis->publish($channel, $data);
}
}
......@@ -16,7 +16,7 @@
</a>
</td>
<td style="width: 70%">
<h4 <?php echo $emailStyles->getStyles('m-clear', 'm-fonts', 'm-header'); ?>>@<?php echo $vars['sender']->get('name'); ?> wired you</h4>
<h4 <?php echo $emailStyles->getStyles('m-clear', 'm-fonts', 'm-header'); ?>>@<?php echo $vars['sender']->get('username'); ?> wired you</h4>
<p <?php echo $emailStyles->getStyles('m-fonts', 'm-subtitle', 'm-clear'); ?>>Transfer Date and Amount:</p>
<p <?php echo $emailStyles->getStyles('m-fonts', 'm-subtitle', 'm-clear'); ?>>
<?php echo $wireDate; ?>; +<?php echo $amount ?>
......
......@@ -16,7 +16,7 @@
</a>
</td>
<td style="width: 70%">
<h4 <?php echo $emailStyles->getStyles('m-clear', 'm-fonts', 'm-header'); ?>>You wired @<?php echo $vars['receiver']->get('name'); ?></h4>
<h4 <?php echo $emailStyles->getStyles('m-clear', 'm-fonts', 'm-header'); ?>>You wired @<?php echo $vars['receiver']->get('username'); ?></h4>
<p <?php echo $emailStyles->getStyles('m-fonts', 'm-subtitle', 'm-clear'); ?>>Transfer Date and Amount:</p>
<p <?php echo $emailStyles->getStyles('m-fonts', 'm-subtitle', 'm-clear'); ?>>
<?php echo $wireDate; ?>; +<?php echo $amount ?>
......
<?php
/**
* Image Manager
*/
namespace Minds\Core\Media\Image;
use Minds\Core\Config;
use Minds\Core\Di\Di;
use Minds\Core\Session;
use Minds\Entities\Entity;
use Minds\Entities\Activity;
use Minds\Entities\Image;
use Minds\Entities\Video;
use Minds\Core\Comments\Comment;
use Minds\Core\Security\SignedUri;
use Lcobucci\JWT;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Zend\Diactoros\Uri;
class Manager
{
/** @var Config $config */
private $config;
/** @var SignedUri $signedUri */
private $signedUri;
public function __construct($config = null, $signedUri = null)
{
$this->config = $config ?? Di::_()->get('Config');
$this->signedUri = $signedUri ?? new SignedUri;
}
/**
* Return a public asset uri for entity type
* @param Entity $entity
* @param string $size
* @return string
*/
public function getPublicAssetUri($entity, $size = 'xlarge'): string
{
$uri = null;
$asset_guid = null;
switch (get_class($entity)) {
case Activity::class:
switch ($entity->get('custom_type')) {
case "batch":
$asset_guid = $entity->get('entity_guid');
break;
default:
$asset_guid = $entity->get('entity_guid');
}
break;
case Image::class:
$asset_guid = $entity->getGuid();
break;
case Video::class:
$asset_guid = $entity->getGuid();
break;
case Comment::class:
$asset_guid = $entity->getAttachments()['attachment_guid'];
break;
}
$uri = $this->config->get('cdn_url') . 'fs/v1/thumbnail/' . $asset_guid . '/' . $size;
$uri = $this->signUri($uri);
return $uri;
}
/**
* Sign a uri and return the uri with the signature attached
* @param string $uri
* @return string
*/
private function signUri($uri, $pub = ""): string
{
$now = new \DateTime();
$expires = $now->modify('midnight + 30 days')->getTimestamp();
return $this->signedUri->sign($uri, $expires);
}
/**
* Config signed uri
* @param string $uri
* @return string
*/
public function confirmSignedUri($uri): bool
{
return $this->signedUri->confirm($uri);
}
}
......@@ -12,6 +12,12 @@ class MediaProvider extends Provider
{
public function register()
{
$this->di->bind('Media\Image\Manager', function ($di) {
return new Image\Manager();
}, ['useFactory' => true]);
$this->di->bind('Media\Video\Manager', function ($di) {
return new Video\Manager();
}, ['useFactory' => true]);
$this->di->bind('Media\Albums', function ($di) {
return new Albums(new Core\Data\Call('entities_by_time'));
}, ['useFactory' => true]);
......