Commit a95de8ba authored by Yassine Doghri's avatar Yassine Doghri
Browse files

feat(components): add custom view renderer with ComponentRenderer adapted from bonfire2

- update Component class structure and remove component helper function and ComponentLoader
- update residual activitypub naming to fediverse
parent 5083cd2f
......@@ -154,8 +154,7 @@ public/media/persons/*
!public/media/persons/index.html
# Generated files
app/Language/en/PersonsTaxonomy.php
app/Language/fr/PersonsTaxonomy.php
modules/Admin/Language/*/PersonsTaxonomy.php
#-------------------------
# Docker volumes
......
......@@ -43,16 +43,14 @@ class Autoload extends AutoloadConfig
*/
public $psr4 = [
APP_NAMESPACE => APPPATH,
'Modules' => ROOTPATH . 'modules',
'Modules\Admin' => ROOTPATH . 'modules/Admin',
'Modules\Auth' => ROOTPATH . 'modules/Auth',
'Modules\Analytics' => ROOTPATH . 'modules/Analytics',
'Modules\Install' => ROOTPATH . 'modules/Install',
'Modules\Fediverse' => ROOTPATH . 'modules/Fediverse',
'Config' => APPPATH . 'Config',
'ActivityPub' => APPPATH . 'Libraries/ActivityPub',
'Analytics' => APPPATH . 'Libraries/Analytics',
'ViewComponents' => APPPATH . 'Libraries/ViewComponents',
'Modules' => ROOTPATH . 'modules/',
'Modules\Admin' => ROOTPATH . 'modules/Admin/',
'Modules\Auth' => ROOTPATH . 'modules/Auth/',
'Modules\Analytics' => ROOTPATH . 'modules/Analytics/',
'Modules\Install' => ROOTPATH . 'modules/Install/',
'Modules\Fediverse' => ROOTPATH . 'modules/Fediverse/',
'Config' => APPPATH . 'Config/',
'ViewComponents' => APPPATH . 'Libraries/ViewComponents/',
];
/**
......
......@@ -76,7 +76,7 @@ Events::on('logout', function (User $user): void {
/*
* --------------------------------------------------------------------
* ActivityPub events
* Fediverse events
* --------------------------------------------------------------------
*/
/**
......
......@@ -9,7 +9,7 @@ use CodeIgniter\Filters\CSRF;
use CodeIgniter\Filters\DebugToolbar;
use CodeIgniter\Filters\Honeypot;
use Modules\Auth\Filters\PermissionFilter;
use Modules\Fediverse\Filters\ActivityPubFilter;
use Modules\Fediverse\Filters\FediverseFilter;
use Myth\Auth\Filters\LoginFilter;
use Myth\Auth\Filters\RoleFilter;
......@@ -27,7 +27,7 @@ class Filters extends BaseConfig
'login' => LoginFilter::class,
'role' => RoleFilter::class,
'permission' => PermissionFilter::class,
'activity-pub' => ActivityPubFilter::class,
'activity-pub' => FediverseFilter::class,
];
/**
......
......@@ -7,11 +7,14 @@ namespace Config;
use App\Libraries\Breadcrumb;
use App\Libraries\Negotiate;
use App\Libraries\Router;
use App\Libraries\View;
use App\Libraries\Vite;
use CodeIgniter\Config\BaseService;
use CodeIgniter\HTTP\Request;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\Router\RouteCollectionInterface;
use Config\Services as AppServices;
use Config\View as ViewConfig;
/**
* Services Configuration file.
......@@ -46,6 +49,24 @@ class Services extends BaseService
return new Router($routes, $request);
}
/**
* The Renderer class is the class that actually displays a file to the user. The default View class within
* CodeIgniter is intentionally simple, but this service could easily be replaced by a template engine if the user
* needed to.
*/
public static function renderer(?string $viewPath = null, ?ViewConfig $config = null, bool $getShared = true): View
{
if ($getShared) {
return static::getSharedInstance('renderer', $viewPath, $config);
}
$viewPath = $viewPath ?: config('Paths')
->viewDirectory;
$config = $config ?? config('View');
return new View($config, $viewPath, AppServices::locator(), CI_DEBUG, AppServices::logger());
}
/**
* The Negotiate class provides the content negotiation features for working the request to determine correct
* language, encoding, charset, and more.
......
......@@ -11,9 +11,9 @@ declare(strict_types=1);
namespace App\Controllers;
use Modules\Analytics\AnalyticsTrait;
use Modules\Fediverse\Controllers\ActorController as ActivityPubActorController;
use Modules\Fediverse\Controllers\ActorController as FediverseActorController;
class ActorController extends ActivityPubActorController
class ActorController extends FediverseActorController
{
use AnalyticsTrait;
......
......@@ -127,6 +127,9 @@ class EpisodeCommentController extends BaseController
->setBody($commentObject->toJSON());
}
/**
* @noRector ReturnTypeDeclarationRector
*/
public function replies(): Response
{
/**
......
......@@ -222,7 +222,7 @@ class EpisodeController extends BaseController
$episodeComments = model('PostModel')
->whereIn('in_reply_to_id', function (BaseBuilder $builder): BaseBuilder {
return $builder->select('id')
->from('activitypub_posts')
->from(config('Fediverse')->tablesPrefix . 'posts')
->where('episode_id', $this->episode->id);
})
->where('`published_at` <= NOW()', null, false)
......
......@@ -21,10 +21,10 @@ use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\URI;
use CodeIgniter\I18n\Time;
use Modules\Analytics\AnalyticsTrait;
use Modules\Fediverse\Controllers\PostController as ActivityPubPostController;
use Modules\Fediverse\Entities\Post as ActivityPubPost;
use Modules\Fediverse\Controllers\PostController as FediversePostController;
use Modules\Fediverse\Entities\Post as FediversePost;
class PostController extends ActivityPubPostController
class PostController extends FediversePostController
{
use AnalyticsTrait;
......@@ -35,7 +35,7 @@ class PostController extends ActivityPubPostController
/**
* @var string[]
*/
protected $helpers = ['auth', 'activitypub', 'svg', 'components', 'misc'];
protected $helpers = ['auth', 'fediverse', 'svg', 'components', 'misc'];
public function _remap(string $method, string ...$params): mixed
{
......@@ -162,7 +162,7 @@ class PostController extends ActivityPubPostController
->with('errors', $this->validator->getErrors());
}
$newPost = new ActivityPubPost([
$newPost = new FediversePost([
'actor_id' => interact_as_actor_id(),
'in_reply_to_id' => $this->post->id,
'message' => $this->request->getPost('message'),
......
......@@ -196,7 +196,7 @@ class AddPodcasts extends Migration
$this->forge->addUniqueKey('handle');
$this->forge->addUniqueKey('guid');
$this->forge->addUniqueKey('actor_id');
$this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
$this->forge->addForeignKey('actor_id', config('Fediverse')->tablesPrefix . 'actors', 'id', '', 'CASCADE');
$this->forge->addForeignKey('category_id', 'categories', 'id');
$this->forge->addForeignKey('language_code', 'languages', 'code');
$this->forge->addForeignKey('created_by', 'users', 'id');
......
......@@ -3,7 +3,7 @@
declare(strict_types=1);
/**
* Class AddEpisodeIdToPosts Adds episode_id field to activitypub_posts table in database
* Class AddEpisodeIdToPosts Adds episode_id field to posts table in database
*
* @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
......@@ -19,18 +19,26 @@ class AddEpisodeIdToPosts extends Migration
public function up(): void
{
$prefix = $this->db->getPrefix();
$fediverseTablesPrefix = config('Fediverse')
->tablesPrefix;
$createQuery = <<<CODE_SAMPLE
ALTER TABLE {$prefix}activitypub_posts
ALTER TABLE {$prefix}{$fediverseTablesPrefix}posts
ADD COLUMN `episode_id` INT UNSIGNED NULL AFTER `replies_count`,
ADD FOREIGN KEY {$prefix}activitypub_posts_episode_id_foreign(episode_id) REFERENCES {$prefix}episodes(id) ON DELETE CASCADE;
ADD FOREIGN KEY {$prefix}{$fediverseTablesPrefix}posts_episode_id_foreign(episode_id) REFERENCES {$prefix}episodes(id) ON DELETE CASCADE;
CODE_SAMPLE;
$this->db->query($createQuery);
}
public function down(): void
{
$this->forge->dropForeignKey('activitypub_posts', 'activitypub_posts_episode_id_foreign');
$this->forge->dropColumn('activitypub_posts', 'episode_id');
$fediverseTablesPrefix = config('Fediverse')
->tablesPrefix;
$this->forge->dropForeignKey(
$fediverseTablesPrefix . 'posts',
$fediverseTablesPrefix . 'posts_episode_id_foreign'
);
$this->forge->dropColumn($fediverseTablesPrefix . 'posts', 'episode_id');
}
}
......@@ -3,7 +3,7 @@
declare(strict_types=1);
/**
* Class AddCreatedByToPosts Adds created_by field to activitypub_posts table in database
* Class AddCreatedByToPosts Adds created_by field to posts table in database
*
* @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
......@@ -19,18 +19,26 @@ class AddCreatedByToPosts extends Migration
public function up(): void
{
$prefix = $this->db->getPrefix();
$fediverseTablesPrefix = config('Fediverse')
->tablesPrefix;
$createQuery = <<<CODE_SAMPLE
ALTER TABLE {$prefix}activitypub_posts
ALTER TABLE {$prefix}{$fediverseTablesPrefix}posts
ADD COLUMN `created_by` INT UNSIGNED AFTER `episode_id`,
ADD FOREIGN KEY {$prefix}activitypub_posts_created_by_foreign(created_by) REFERENCES {$prefix}users(id) ON DELETE CASCADE;
ADD FOREIGN KEY {$prefix}{$fediverseTablesPrefix}posts_created_by_foreign(created_by) REFERENCES {$prefix}users(id) ON DELETE CASCADE;
CODE_SAMPLE;
$this->db->query($createQuery);
}
public function down(): void
{
$this->forge->dropForeignKey('activitypub_posts', 'activitypub_posts_created_by_foreign');
$this->forge->dropColumn('activitypub_posts', 'created_by');
$fediverseTablesPrefix = config('Fediverse')
->tablesPrefix;
$this->forge->dropForeignKey(
$fediverseTablesPrefix . 'posts',
$fediverseTablesPrefix . 'posts_created_by_foreign'
);
$this->forge->dropColumn($fediverseTablesPrefix . 'posts', 'created_by');
}
}
......@@ -65,9 +65,13 @@ class AddEpisodeComments extends Migration
'null' => true,
],
]);
$fediverseTablesPrefix = config('Fediverse')
->tablesPrefix;
$this->forge->addPrimaryKey('id');
$this->forge->addForeignKey('episode_id', 'episodes', 'id', '', 'CASCADE');
$this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
$this->forge->addForeignKey('actor_id', $fediverseTablesPrefix . 'actors', 'id', '', 'CASCADE');
$this->forge->addForeignKey('created_by', 'users', 'id');
$this->forge->createTable('episode_comments');
}
......
......@@ -28,9 +28,13 @@ class AddLikes extends Migration
'constraint' => 16,
],
]);
$fediverseTablesPrefix = config('Fediverse')
->tablesPrefix;
$this->forge->addField('`created_at` timestamp NOT NULL DEFAULT current_timestamp()');
$this->forge->addPrimaryKey(['actor_id', 'comment_id']);
$this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
$this->forge->addForeignKey('actor_id', $fediverseTablesPrefix . 'actors', 'id', '', 'CASCADE');
$this->forge->addForeignKey('comment_id', 'episode_comments', 'id', '', 'CASCADE');
$this->forge->createTable('likes');
}
......
......@@ -238,13 +238,13 @@ class AuthSeeder extends Seeder
[
'name' => 'block_actors',
'description' =>
'Block an activitypub actors from interacting with the instance.',
'Block fediverse actors from interacting with the instance.',
'has_permission' => ['superadmin'],
],
[
'name' => 'block_domains',
'description' =>
'Block an activitypub domains from interacting with the instance.',
'Block fediverse domains from interacting with the instance.',
'has_permission' => ['superadmin'],
],
],
......
......@@ -11,14 +11,14 @@ declare(strict_types=1);
namespace App\Entities;
use App\Models\PodcastModel;
use Modules\Fediverse\Entities\Actor as ActivityPubActor;
use Modules\Fediverse\Entities\Actor as FediverseActor;
use RuntimeException;
/**
* @property Podcast|null $podcast
* @property boolean $is_podcast
*/
class Actor extends ActivityPubActor
class Actor extends FediverseActor
{
protected ?Podcast $podcast = null;
......
......@@ -134,7 +134,7 @@ class EpisodeComment extends UuidEntity
public function setMessage(string $message): static
{
helper('activitypub');
helper('fediverse');
$messageWithoutTags = strip_tags($message);
......
......@@ -11,14 +11,14 @@ declare(strict_types=1);
namespace App\Entities;
use App\Models\EpisodeModel;
use Modules\Fediverse\Entities\Post as ActivityPubPost;
use Modules\Fediverse\Entities\Post as FediversePost;
use RuntimeException;
/**
* @property int|null $episode_id
* @property Episode|null $episode
*/
class Post extends ActivityPubPost
class Post extends FediversePost
{
protected ?Episode $episode = null;
......
......@@ -18,7 +18,7 @@ if (! function_exists('save_media')) {
/**
* Saves a file to the corresponding podcast folder in `public/media`
*/
function save_media(File|UploadedFile $file, string $folder = '', string $filename = ''): string
function save_media(File | UploadedFile $file, string $folder = '', string $filename = ''): string
{
if (($extension = $file->getExtension()) !== '') {
$filename = $filename . '.' . $extension;
......
<?php
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
return [
'your_handle' => 'Your handle',
'your_handle_hint' => 'Enter the @username@domain you want to act from.',
'follow' => [
'label' => 'Follow',
'title' => 'Follow {actorDisplayName}',
'subtitle' => 'You are going to follow:',
'accountNotFound' => 'The account could not be found.',
'submit' => 'Proceed to follow',
],
'favourite' => [
'title' => "Favourite {actorDisplayName}'s post",
'subtitle' => 'You are going to favourite:',
'submit' => 'Proceed to favourite',
],
'reblog' => [
'title' => "Share {actorDisplayName}'s post",
'subtitle' => 'You are going to share:',
'submit' => 'Proceed to share',
],
'reply' => [
'title' => "Reply to {actorDisplayName}'s post",
'subtitle' => 'You are going to reply to:',
'submit' => 'Proceed to reply',
],
];
Supports Markdown
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