Skip to content
Commits on Source (12)
......@@ -181,7 +181,10 @@ class Factory
'status' => 'success', //should success be assumed?
], $data);
ob_end_clean();
if (ob_get_level() > 1) {
// New PSR-7 Router has an OB started all the time
ob_end_clean();
}
static::setCORSHeader();
......
......@@ -337,6 +337,15 @@ class blog implements Interfaces\Api
]);
}
// This is a first create blog that should have a banner
// We are trying to stop spam with this check
if ($blog->isPublished() && !$editing && !is_uploaded_file($_FILES['file']['tmp_name'])) {
return Factory::response([
'status' => 'error',
'message' => 'You must upload a banner'
]);
}
try {
if ($editing) {
$saved = $manager->update($blog);
......
......@@ -28,11 +28,13 @@ class channel implements Interfaces\Api
*/
public function get($pages)
{
$currentUser = Session::getLoggedinUser();
$channel = new User(strtolower($pages[0]));
$channel->fullExport = true; //get counts
$channel->exportCounts = true;
if (!$channel->isPro()) {
if (!$channel->isPro() && $channel->getGuid() !== $currentUser->getGuid()) {
return Factory::response([
'status' => 'error',
'message' => 'E_NOT_PRO'
......
......@@ -75,14 +75,14 @@ class settings implements Interfaces\Api
->setUser($user)
->setActor(Session::getLoggedinUser());
if (!$manager->isActive()) {
return Factory::response([
'status' => 'error',
'message' => 'You are not Pro',
]);
}
if (isset($_POST['domain'])) {
// if (!$manager->isActive()) {
// return Factory::response([
// 'status' => 'error',
// 'message' => 'You are not Pro',
// ]);
// }
if (isset($_POST['domain']) && $manager->isActive()) {
/** @var ProDomain $proDomain */
$proDomain = Di::_()->get('Pro\Domain');
......
......@@ -85,12 +85,12 @@ class assets implements Interfaces\Api
->setUser($user)
->setActor(Session::getLoggedinUser());
if (!$manager->isActive()) {
return Factory::response([
'status' => 'error',
'message' => 'You are not Pro',
]);
}
// if (!$manager->isActive()) {
// return Factory::response([
// 'status' => 'error',
// 'message' => 'You are not Pro',
// ]);
// }
/** @var AssetsManager $assetsManager */
$assetsManager = Di::_()->get('Pro\Assets\Manager');
......
......@@ -104,7 +104,7 @@ class account implements Interfaces\Api
Factory::isLoggedIn();
$response = [];
$vars = Core\Router::getPutVars();
$vars = Core\Router\PrePsr7\Router::getPutVars();
$user = Core\Session::getLoggedInUser();
......
......@@ -102,7 +102,7 @@ class Repository
->setRating($data['rating'])
->setTags($data['tags'])
->setNsfw($data['nsfw'])
->setRejectReason($data['rejection_reason'])
->setRejectedReason($data['rejection_reason'])
->setChecksum($data['checksum']);
$response[] = $boost;
......
<?php
/**
* Ref.
* Holds a forward reference to a provider and a method.
* Used by PSR-7 Router to resolve DI bindings.
*
* @author edgebal
*/
namespace Minds\Core\Di;
use Minds\Traits\MagicAttributes;
/**
* Class Ref
* @package Minds\Core\Di
* @method string getProvider()
* @method Ref setProvider(string $provider)
* @method string getMethod()
* @method Ref setMethod(string $method)
*/
class Ref
{
use MagicAttributes;
/** @var string */
protected $provider;
/** @var string */
protected $method;
/**
* Ref constructor.
* @param string $provider
* @param string $method
*/
public function __construct(string $provider, string $method)
{
$this->setProvider($provider);
$this->setMethod($method);
}
/**
* @param string $provider
* @param string $method
* @return Ref
*/
public static function _(string $provider, string $method): Ref
{
return new static($provider, $method);
}
}
Great news! Your channel is now eligible for a free preview of [Minds Pro](https://minds.com/pro?__e_ct_guid=<?= $vars['guid']?>&campaign=<?= $vars['campaign']?>&topic=<?= $vars['topic'] ?>&validator=<?= $vars['validator'] ?>).
This gives you a chance to test out our new features and decide if the product is right for you. Pro provides you with the tools to launch your own website and monetize your content without fear of unfair algorithms, censorship or demonetization.
| |
|:--:|
| [![Try Pro](https://cdn-assets.minds.com/emails/try-pro.png){=150x}](https://www.minds.com/pro/<?= $vars['user']->username ?>/settings?__e_ct_guid=<?= $vars['guid']?>&campaign=<?= $vars['campaign']?>&topic=<?= $vars['topic'] ?>&validator=<?= $vars['validator'] ?>) |
| |
Specifically, be sure to check out your new [Analytics](https://www.minds.com/analytics/dashboard) console in the right-hand menu once you log in. Please remember that purchasing our [products](https://minds.com/upgrade?__e_ct_guid=<?= $vars['guid']?>&campaign=<?= $vars['campaign']?>&topic=<?= $vars['topic'] ?>&validator=<?= $vars['validator'] ?>) is an invaluable donation to the financial sustainability of our platform and community.
Thank you for your support!
......@@ -51,7 +51,7 @@ class Manager
$features = $this->config->get('features') ?: [];
if (!isset($features[$feature])) {
error_log("[Features\Manager] Feature '{$feature}' is not declared. Assuming false.");
// error_log("[Features\Manager] Feature '{$feature}' is not declared. Assuming false.");
return false;
}
......
......@@ -6,14 +6,21 @@
namespace Minds\Core\Feeds\Activity;
use Zend\Diactoros\ServerRequest;
class Manager
{
public function add()
public function add(ServerRequest $request)
{
throw new \NotImplementedException();
}
public function update(ServerRequest $request)
{
throw new \NotImplementedException();
}
public function update()
public function delete(ServerRequest $request)
{
throw new \NotImplementedException();
}
......
......@@ -12,6 +12,10 @@ class FeedsProvider extends Provider
return new Elastic\Manager();
});
$this->di->bind('Feeds\Activity\Manager', function ($di) {
return new Activity\Manager();
});
$this->di->bind('Feeds\Firehose\Manager', function ($di) {
return new Firehose\Manager();
});
......
<?php
/**
* Module
* @author edgebal
*/
namespace Minds\Core\Feeds;
use Minds\Interfaces\ModuleInterface;
class Module implements ModuleInterface
{
/**
* Executed onInit
* @return void
*/
public function onInit(): void
{
(new FeedsProvider())->register();
(new Routes())->register();
}
}
<?php
/**
* Routes
* @author edgebal
*/
namespace Minds\Core\Feeds;
use Minds\Core\Di\Ref;
use Minds\Core\Router\Middleware\LoggedInMiddleware;
use Minds\Core\Router\ModuleRoutes;
use Minds\Core\Router\Route;
class Routes extends ModuleRoutes
{
/**
* Registers all module routes
*/
public function register(): void
{
$this->route
->withPrefix('api/v3/newsfeed')
->withMiddleware([
LoggedInMiddleware::class,
])
->do(function (Route $route) {
$route->post(
'',
Ref::_('Feeds\Activity\Manager', 'add')
);
$route->post(
':guid',
Ref::_('Feeds\Activity\Manager', 'update')
);
$route->delete(
':guid',
Ref::_('Feeds\Activity\Manager', 'delete')
);
});
}
}
......@@ -45,8 +45,8 @@ class Repository
'must' => [
[
'range' => [
'votes:up:24h:synced' => [
'gte' => $opts['from'],
'@timestamp' => [
'gte' => $opts['from'] * 1000,
],
],
],
......@@ -81,7 +81,7 @@ class Repository
'aggs' => [
'counts' => [
'max' => [
'field' => 'votes:up:24h',
'field' => 'votes:up',
],
],
'owners' => [
......
......@@ -4,6 +4,7 @@ namespace Minds\Core;
use Minds\Core\Di\Di;
use Minds\Core\Events\Dispatcher;
use Minds\Interfaces\ModuleInterface;
/**
* Core Minds Engine.
......@@ -28,6 +29,7 @@ class Minds extends base
Referrals\Module::class,
Reports\Module::class,
VideoChat\Module::class,
Feeds\Module::class,
Front\Module::class,
];
......@@ -60,6 +62,7 @@ class Minds extends base
/*
* Initialise the modules
*/
/** @var ModuleInterface $module */
foreach ($modules as $module) {
$module->onInit();
}
......@@ -111,7 +114,6 @@ class Minds extends base
(new Plus\PlusProvider())->register();
(new Pro\ProProvider())->register();
(new Hashtags\HashtagsProvider())->register();
(new Feeds\FeedsProvider())->register();
(new Analytics\AnalyticsProvider())->register();
(new Channels\ChannelsProvider())->register();
(new Blogs\BlogsProvider())->register();
......
......@@ -157,6 +157,13 @@ class Manager
'user_guid' => $this->user->guid,
])->first();
// If requested by an inactive user, this is preview mode
if (!$settings && !$this->isActive()) {
$settings = new Settings();
$settings->setUserGuid($this->user->guid);
$settings->setTitle($this->user->name ?: $this->user->username);
}
if (!$settings) {
return null;
}
......@@ -333,8 +340,11 @@ class Manager
$settings->setTimeUpdated(time());
$this->setupRoutingDelegate
->onUpdate($settings);
// Only update routing if we are active
if ($this->isActive()) {
$this->setupRoutingDelegate
->onUpdate($settings);
}
return $this->repository->update($settings);
}
......
......@@ -116,6 +116,6 @@ class ChannelDeferredOps implements Interfaces\QueueRunner
default:
echo "ERROR! Invalid type {$type} passed\n\n";
}
});
}, [ 'max_messages' => 1 ]);
}
}
......@@ -242,7 +242,9 @@ class Repository
->setAppeal(isset($row['appeal_note']) ? true : false)
->setAppealNote(isset($row['appeal_note']) ? (string) $row['appeal_note'] : '')
->setReports(
isset($row['reports']) ?
$this->buildReports($row['reports']->values())
: null
)
->setInitialJuryDecisions(
isset($row['initial_jury']) ?
......
<?php
<?php declare(strict_types=1);
/**
* Router
* @author edgebal
*/
namespace Minds\Core;
use Minds\Core\Di\Di;
use Minds\Core\I18n\I18n;
use Minds\Core\Router\Manager;
use Minds\Helpers;
use Zend\Diactoros\Response\JsonResponse;
use Minds\Core\Features\Manager as Features;
use Minds\Core\Router\Dispatcher;
use Minds\Core\Router\Middleware\Kernel;
use Minds\Core\Router\PrePsr7\Fallback;
use Zend\Diactoros\ServerRequestFactory;
use Zend\Diactoros\Uri;
/**
* Minds Core Router.
*/
class Router
{
// these are core pages, other pages are registered by plugins
public static $routes = [
'/archive/thumbnail' => 'Minds\\Controllers\\fs\\v1\\thumbnail',
'/api/v1/archive/thumbnails' => 'Minds\\Controllers\\api\\v1\\media\\thumbnails',
/** @var Dispatcher */
protected $dispatcher;
'/oauth2/token' => 'Minds\\Controllers\\oauth2\\token',
'/oauth2/implicit' => 'Minds\\Controllers\\oauth2\\implicit',
'/icon' => 'Minds\\Controllers\\icon',
'//icon' => 'Minds\\Controllers\\icon',
'/api' => 'Minds\\Controllers\\api\\api',
'/fs' => 'Minds\\Controllers\\fs\\fs',
'/thumbProxy' => 'Minds\\Controllers\\thumbProxy',
'/wall' => 'Minds\\Controllers\\Legacy\\wall',
'/not-supported' => "Minds\Controllers\\notSupported",
// "/app" => "minds\\pages\\app",
'/emails/unsubscribe' => 'Minds\\Controllers\\emails\\unsubscribe',
'/sitemap' => 'Minds\\Controllers\\sitemap',
'/apple-app-site-association' => '\\Minds\\Controllers\\deeplinks',
'/sitemaps' => '\\Minds\\Controllers\\sitemaps',
'/checkout' => '\\Minds\\Controllers\\checkout',
];
/** @var Features */
protected $features;
/** @var Manager */
protected $manager;
/** @var Fallback */
protected $fallback;
/**
* Router constructor.
* @param Manager $manager
* @param Dispatcher $dispatcher
* @param Features $features
* @param Fallback $fallback
*/
public function __construct(
$manager = null
$dispatcher = null,
$features = null,
$fallback = null
) {
/** @var Router\Manager $manager */
$this->manager = $manager ?: Di::_()->get('Router\Manager');
$this->dispatcher = $dispatcher ?: Di::_()->get('Router');
$this->features = $features ?: Di::_()->get('Features');
$this->fallback = $fallback ?: new Fallback();
}
/**
* Route the pages
* (fallback to elgg page handler if we fail).
*
* @param string $uri
* @param string $method
*
* @return null|mixed
* @param string|null $uri
* @param string|null $method
* @param string|null $host
*/
public function route($uri = null, $method = null)
public function route(string $uri = null, string $method = null, string $host = null): void
{
if ((!$uri) && (isset($_SERVER['REDIRECT_ORIG_URI']))) {
$uri = strtok($_SERVER['REDIRECT_ORIG_URI'], '?');
if (!$this->features->has('psr7-router')) {
$this->fallback->route();
return;
}
if (!$uri) {
$uri = strtok($_SERVER['REQUEST_URI'], '?');
}
$this->detectContentType();
header('X-Frame-Options: DENY');
$route = rtrim($uri, '/');
$segments = explode('/', $route);
$method = $method ? $method : strtolower($_SERVER['REQUEST_METHOD']);
if ($method == 'post') {
$this->postDataFix();
}
$request = ServerRequestFactory::fromGlobals();
$response = new JsonResponse([]);
$result = $this->manager
->handle($request, $response);
if ($result === false) {
return null;
}
if ($request->getMethod() === 'OPTIONS') {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With,X-No-Cache');
return null;
}
// Sessions
// TODO: Support middleware
$session = Di::_()->get('Sessions\Manager');
$session->withRouterRequest($request);
// OAuth Middleware
// TODO: allow interface to bypass
// TODO: Support middleware
if (!Session::isLoggedIn()) { // Middleware will resolve this
Session::withRouterRequest($request, $response);
}
// XSRF Cookie - may be able to remove now with OAuth flow
Security\XSRF::setCookie();
if (Session::isLoggedin()) {
Helpers\Analytics::increment('active');
}
if (isset($_GET['__e_ct_guid']) && is_numeric($_GET['__e_ct_guid'])) {
Helpers\Analytics::increment('active', $_GET['__e_ct_guid']);
Helpers\Campaigns\EmailRewards::reward($_GET['campaign'], $_GET['__e_ct_guid']);
}
Di::_()->get('Email\RouterHooks')
->withRouterRequest($request);
Di::_()->get('Referrals\Cookie')
->withRouterRequest($request)
->create();
$loop = count($segments);
while ($loop >= 0) {
$offset = $loop - 1;
if ($loop < count($segments)) {
$slug_length = strlen($segments[$offset + 1].'/');
$route_length = strlen($route);
$route = substr($route, 0, $route_length - $slug_length);
}
if (isset(self::$routes[$route])) {
$handler = new self::$routes[$route]();
$pages = array_splice($segments, $loop) ?: [];
if (method_exists($handler, $method)) {
// Set the request
if (method_exists($handler, 'setRequest')) {
$handler->setRequest($request);
}
// Set the response
if (method_exists($handler, 'setResponse')) {
$handler->setResponse($response);
}
return $handler->$method($pages);
} else {
exit;
}
}
--$loop;
$uri = strtok($_SERVER['REDIRECT_ORIG_URI'] ?? $_SERVER['REQUEST_URI'], '?');
}
if (!$this->legacyRoute($uri)) {
(new I18n())->serveIndex();
if (!$method) {
$method = $_SERVER['REQUEST_METHOD'];
}
return null;
}
/**
* Legacy Router fallback.
*
* @param string $uri
*
* @return bool
*/
public function legacyRoute($uri)
{
$path = explode('/', substr($uri, 1));
$handler = array_shift($path);
$page = implode('/', $path);
new page(false); //just to load init etc
return false;
}
/**
* Detects request content type and apply the corresponding polyfills.
*/
public function detectContentType()
{
if (isset($_SERVER['CONTENT_TYPE']) && $_SERVER['CONTENT_TYPE'] == 'application/json') {
//\elgg_set_viewtype('json');
if (strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
$this->postDataFix();
}
if (!$host) {
$host = $_SERVER['HTTP_HOST'];
}
}
/**
* Populates $_POST and $_REQUEST with request's JSON payload.
*/
public function postDataFix()
{
$postdata = file_get_contents('php://input');
$request = json_decode($postdata, true);
if ($request) {
foreach ($request as $k => $v) {
$_POST[$k] = $v;
$_REQUEST[$k] = $v;
$request = ServerRequestFactory::fromGlobals()
->withMethod($method)
->withUri(
(new Uri($uri))
->withHost($host)
);
$response = $this->dispatcher
->pipe(new Kernel\ContentNegotiationMiddleware())
->pipe(new Kernel\ErrorHandlerMiddleware())
->pipe(
(new Kernel\RouteResolverMiddleware())
->setAttributeName('_request-handler')
) // Note: Pre-PSR7 routes will not advance further than this
->pipe(new Kernel\CorsMiddleware())
->pipe(new Kernel\JsonPayloadMiddleware())
->pipe(new Kernel\FrameSecurityMiddleware())
->pipe(
(new Kernel\SessionMiddleware())
->setAttributeName('_user')
)
->pipe(
(new Kernel\OauthMiddleware())
->setAttributeName('_user')
)
->pipe(new Kernel\XsrfCookieMiddleware())
->pipe(
(new Kernel\RequestHandlerMiddleware())
->setAttributeName('_request-handler')
)
->handle($request);
foreach ($response->getHeaders() as $header => $values) {
foreach ($values as $value) {
header(sprintf('%s: %s', $header, $value), false);
}
}
}
/**
* Return vars for request
* @return array
*/
public static function getPutVars()
{
$postdata = file_get_contents('php://input');
$request = json_decode($postdata, true);
return $request;
}
/**
* Register routes.
*
* @param array $routes - an array of routes to handlers
*
* @return array - the array of all your routes
*/
public static function registerRoutes($routes = [])
{
return self::$routes = array_merge(self::$routes, $routes);
http_response_code($response->getStatusCode());
echo $response->getBody();
}
}