3d567353c9
- Add ACL check and parameterized query to PreviewController - Filter articles by user view access levels - Update README with new features (AI captions, social preview, OG image gen, link shortening, post calendar, analytics) - Update Nostr status from stub to implemented - Add security fix entry to CHANGELOG Authored-by: Moko Consulting
102 lines
3.3 KiB
PHP
102 lines
3.3 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @package MokoSuiteCross
|
|
* @subpackage com_mokosuitecross
|
|
* @author Moko Consulting <hello@mokoconsulting.tech>
|
|
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
|
* @license GNU General Public License version 3 or later; see LICENSE
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
namespace Joomla\Component\MokoSuiteCross\Administrator\Controller;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\MVC\Controller\BaseController;
|
|
use Joomla\CMS\Session\Session;
|
|
use Joomla\CMS\Uri\Uri;
|
|
use Joomla\Component\MokoSuiteCross\Administrator\Helper\CrossPostDispatcher;
|
|
use Joomla\Component\MokoSuiteCross\Administrator\Helper\PreviewHelper;
|
|
|
|
class PreviewController extends BaseController
|
|
{
|
|
public function render(): void
|
|
{
|
|
if (!Session::checkToken('get')) {
|
|
echo json_encode(['error' => 'Invalid token']);
|
|
$this->app->close();
|
|
|
|
return;
|
|
}
|
|
|
|
$user = $this->app->getIdentity();
|
|
|
|
if (!$user->authorise('core.manage', 'com_mokosuitecross')
|
|
&& !$user->authorise('core.edit', 'com_content')
|
|
&& !$user->authorise('core.edit.own', 'com_content')) {
|
|
echo json_encode(['error' => 'Permission denied']);
|
|
$this->app->close();
|
|
|
|
return;
|
|
}
|
|
|
|
$articleId = $this->input->getInt('article_id', 0);
|
|
$platform = $this->input->getCmd('platform', 'twitter');
|
|
|
|
if ($articleId < 1) {
|
|
echo json_encode(['error' => 'Missing article ID']);
|
|
$this->app->close();
|
|
|
|
return;
|
|
}
|
|
|
|
$db = Factory::getDbo();
|
|
|
|
$groups = $user->getAuthorisedViewLevels();
|
|
|
|
$query = $db->getQuery(true)
|
|
->select('*')
|
|
->from($db->quoteName('#__content'))
|
|
->where($db->quoteName('id') . ' = :id')
|
|
->where($db->quoteName('access') . ' IN (' . implode(',', array_map('intval', $groups)) . ')')
|
|
->bind(':id', $articleId, \Joomla\Database\ParameterType::INTEGER);
|
|
$db->setQuery($query);
|
|
$article = $db->loadObject();
|
|
|
|
if (!$article) {
|
|
echo json_encode(['error' => 'Article not found']);
|
|
$this->app->close();
|
|
|
|
return;
|
|
}
|
|
|
|
$meta = CrossPostDispatcher::buildArticleMeta($article);
|
|
|
|
$title = $meta['{title}'] ?? '';
|
|
$text = $meta['{introtext}'] ?? '';
|
|
$url = $meta['{url}'] ?? '';
|
|
$imageUrl = $meta['{image}'] ?? '';
|
|
$authorName = $meta['{author}'] ?? '';
|
|
|
|
$supportedPlatforms = PreviewHelper::getSupportedPlatforms();
|
|
$html = '';
|
|
|
|
if ($platform === 'all') {
|
|
foreach ($supportedPlatforms as $p) {
|
|
$html .= '<div style="margin-bottom:20px;">'
|
|
. '<div style="font-weight:600;font-size:13px;color:#666;margin-bottom:6px;text-transform:uppercase;">' . htmlspecialchars(ucfirst($p)) . '</div>'
|
|
. PreviewHelper::render($p, $title, $text, $url, $imageUrl, $authorName)
|
|
. '</div>';
|
|
}
|
|
} else {
|
|
$html = PreviewHelper::render($platform, $title, $text, $url, $imageUrl, $authorName);
|
|
}
|
|
|
|
$this->app->setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
echo $html;
|
|
$this->app->close();
|
|
}
|
|
}
|