diff --git a/components/Left/Controller/EditFeeds.php b/components/Left/Controller/EditFeeds.php new file mode 100644 index 0000000000..259921903e --- /dev/null +++ b/components/Left/Controller/EditFeeds.php @@ -0,0 +1,147 @@ +. + +// }}} + +namespace Component\Left\Controller; + +use App\Core\Controller; +use App\Core\DB\DB; +use App\Core\Form; +use function App\Core\I18n\_m; +use App\Entity\Feed; +use App\Util\Common; +use Symfony\Component\Form\Extension\Core\Type\IntegerType; +use Symfony\Component\Form\Extension\Core\Type\SubmitType; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\HttpFoundation\Request; + +class EditFeeds extends Controller +{ + public function __invoke(Request $request) + { + $user = Common::ensureLoggedIn(); + $key = Feed::cacheKey($user); + $feeds = Feed::getFeeds($user); + + $form_definitions = []; + foreach ($feeds as $feed) { + $md5 = md5($feed->getUrl()); + $form_definitions[] = [$md5 . '-url', TextType::class, ['data' => $feed->getUrl(), 'label' => _m('URL'), 'block_prefix' => 'row_url']]; + $form_definitions[] = [$md5 . '-order', IntegerType::class, ['data' => $feed->getOrdering(), 'label' => _m('Order'), 'block_prefix' => 'row_order']]; + $form_definitions[] = [$md5 . '-title', TextType::class, ['data' => $feed->getTitle(), 'label' => _m('Title'), 'block_prefix' => 'row_title']]; + $form_definitions[] = [$md5 . '-remove', SubmitType::class, ['label' => _m('Remove'), 'block_prefix' => 'row_remove']]; + } + + $form_definitions[] = ['url', TextType::class, ['label' => _m('New feed'), 'required' => false]]; + $form_definitions[] = ['order', IntegerType::class, ['label' => _m('Order'), 'data' => (\count($form_definitions) / 4) + 1]]; + $form_definitions[] = ['title', TextType::class, ['label' => _m('Title'), 'required' => false]]; + $form_definitions[] = ['add', SubmitType::class, ['label' => _m('Add')]]; + $form_definitions[] = ['update_exisiting', SubmitType::class, ['label' => _m('Update existing')]]; + $form_definitions[] = ['reset', SubmitType::class, ['label' => _m('Reset to default values')]]; + + $form = Form::create($form_definitions); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + array_pop($form_definitions); + array_pop($form_definitions); + array_pop($form_definitions); + array_pop($form_definitions); + array_pop($form_definitions); + + $data = $form->getData(); + + if ($form->get('update_exisiting')->isClicked()) { + // Each feed has a URL, an order and a title + $feeds_data = array_chunk($data, 3, preserve_keys: true); + // The last three would be the new one + array_pop($feeds_data); + // Sort by the order + usort($feeds_data, fn ($fd_l, $fd_r) => next($fd_l) <=> next($fd_r)); + // Make the order sequential + $order = 1; + foreach ($feeds_data as $i => $fd) { + next($fd); + $feeds_data[$i][key($fd)] = $order++; + } + // Update the fields in the corresponding feed + foreach ($feeds_data as $fd) { + $md5 = str_replace('-url', '', array_key_first($fd)); + $feed = F\first($feeds, fn ($f) => md5($f->getUrl()) === $md5); + $feed->setUrl($fd[$md5 . '-url']); + $feed->setOrdering($fd[$md5 . '-order']); + $feed->setTitle($fd[$md5 . '-title']); + DB::merge($feed); + } + DB::flush(); + Cache::delete($key); + throw new RedirectException(); + } + + // Remove feed + foreach ($form_definitions as [$field, $type, $opts]) { + if (str_ends_with($field, '-url')) { + $remove_id = str_replace('-url', '-remove', $field); + if ($form->get($remove_id)->isClicked()) { + DB::remove(DB::getReference('feed', ['actor_id' => $user->getId(), 'url' => $opts['data']])); + DB::flush(); + Cache::delete($key); + throw new RedirectException(); + } + } + } + + if ($form->get('reset')->isClicked()) { + F\map(DB::findBy('feed', ['actor_id' => $user->getId()]), fn ($f) => DB::remove($f)); + DB::flush(); + Cache::delete($key); + Feed::createDefaultFeeds($user->getId(), $user); + DB::flush(); + throw new RedirectException(); + } + + // Add feed + try { + $match = Router::match($data['url']); + $route = $match['_route']; + DB::persist(Feed::create([ + 'actor_id' => $user->getId(), + 'url' => $data['url'], + 'route' => $route, + 'title' => $data['title'], + 'ordering' => $data['order'], + ])); + DB::flush(); + Cache::delete($key); + throw new RedirectException(); + } catch (ResourceNotFoundException) { + // throw new ClientException(_m('Invalid route')); + // continue bellow + } + } + + return [ + '_template' => 'left/edit_feeds.html.twig', + 'edit_feeds' => $form->createView(), + ]; + } +} diff --git a/components/Left/Left.php b/components/Left/Left.php index c6d7289029..2395af473b 100644 --- a/components/Left/Left.php +++ b/components/Left/Left.php @@ -23,9 +23,17 @@ namespace Component\Left; use App\Core\Event; use App\Core\Modules\Component; +use App\Core\Router\RouteLoader; +use Component\Left\Controller as C; class Left extends Component { + public function onAddRoute(RouteLoader $r): bool + { + $r->connect('edit_feeds', '/edit-feeds', C\EditFeeds::class); + return Event::next; + } + /** * Output our dedicated stylesheet * diff --git a/templates/feeds/edit_feeds.html.twig b/components/Left/templates/left/edit_feeds.html.twig similarity index 100% rename from templates/feeds/edit_feeds.html.twig rename to components/Left/templates/left/edit_feeds.html.twig diff --git a/src/Controller/Feeds.php b/src/Controller/Feeds.php index dbbbb5798b..06db69988a 100644 --- a/src/Controller/Feeds.php +++ b/src/Controller/Feeds.php @@ -35,27 +35,15 @@ declare(strict_types = 1); namespace App\Controller; -use App\Core\Cache; use App\Core\Controller; use App\Core\DB\DB; use App\Core\Event; -use App\Core\Form; use function App\Core\I18n\_m; -use App\Core\Router\Router; use App\Core\VisibilityScope; -use App\Entity\Feed; use App\Entity\Note; -use App\Util\Common; use App\Util\Exception\ClientException; use App\Util\Exception\NotFoundException; -use App\Util\Exception\NotImplementedException; -use App\Util\Exception\RedirectException; -use Functional as F; -use Symfony\Component\Form\Extension\Core\Type\IntegerType; -use Symfony\Component\Form\Extension\Core\Type\SubmitType; -use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Exception\ResourceNotFoundException; class Feeds extends Controller { @@ -137,132 +125,4 @@ class Feeds extends Controller 'page_title' => 'Network feed', ]; } - - public function edit_feeds(Request $request) - { - $user = Common::ensureLoggedIn(); - $key = Feed::cacheKey($user); - $feeds = Feed::getFeeds($user); - - $form_definitions = []; - foreach ($feeds as $feed) { - $md5 = md5($feed->getUrl()); - $form_definitions[] = [$md5 . '-url', TextType::class, ['data' => $feed->getUrl(), 'label' => _m('URL'), 'block_prefix' => 'row_url']]; - $form_definitions[] = [$md5 . '-order', IntegerType::class, ['data' => $feed->getOrdering(), 'label' => _m('Order'), 'block_prefix' => 'row_order']]; - $form_definitions[] = [$md5 . '-title', TextType::class, ['data' => $feed->getTitle(), 'label' => _m('Title'), 'block_prefix' => 'row_title']]; - $form_definitions[] = [$md5 . '-remove', SubmitType::class, ['label' => _m('Remove'), 'block_prefix' => 'row_remove']]; - } - - $form_definitions[] = ['url', TextType::class, ['label' => _m('New feed'), 'required' => false]]; - $form_definitions[] = ['order', IntegerType::class, ['label' => _m('Order'), 'data' => (\count($form_definitions) / 4) + 1]]; - $form_definitions[] = ['title', TextType::class, ['label' => _m('Title'), 'required' => false]]; - $form_definitions[] = ['add', SubmitType::class, ['label' => _m('Add')]]; - $form_definitions[] = ['update_exisiting', SubmitType::class, ['label' => _m('Update existing')]]; - $form_definitions[] = ['reset', SubmitType::class, ['label' => _m('Reset to default values')]]; - - $form = Form::create($form_definitions); - - $form->handleRequest($request); - if ($form->isSubmitted() && $form->isValid()) { - array_pop($form_definitions); - array_pop($form_definitions); - array_pop($form_definitions); - array_pop($form_definitions); - array_pop($form_definitions); - - $data = $form->getData(); - - if ($form->get('update_exisiting')->isClicked()) { - // Each feed has a URL, an order and a title - $feeds_data = array_chunk($data, 3, preserve_keys: true); - // The last three would be the new one - array_pop($feeds_data); - // Sort by the order - usort($feeds_data, fn ($fd_l, $fd_r) => next($fd_l) <=> next($fd_r)); - // Make the order sequential - $order = 1; - foreach ($feeds_data as $i => $fd) { - next($fd); - $feeds_data[$i][key($fd)] = $order++; - } - // Update the fields in the corresponding feed - foreach ($feeds_data as $fd) { - $md5 = str_replace('-url', '', array_key_first($fd)); - $feed = F\first($feeds, fn ($f) => md5($f->getUrl()) === $md5); - $feed->setUrl($fd[$md5 . '-url']); - $feed->setOrdering($fd[$md5 . '-order']); - $feed->setTitle($fd[$md5 . '-title']); - DB::merge($feed); - } - DB::flush(); - Cache::delete($key); - throw new RedirectException(); - } - - // Remove feed - foreach ($form_definitions as [$field, $type, $opts]) { - if (str_ends_with($field, '-url')) { - $remove_id = str_replace('-url', '-remove', $field); - if ($form->get($remove_id)->isClicked()) { - DB::remove(DB::getReference('feed', ['actor_id' => $user->getId(), 'url' => $opts['data']])); - DB::flush(); - Cache::delete($key); - throw new RedirectException(); - } - } - } - - if ($form->get('reset')->isClicked()) { - F\map(DB::findBy('feed', ['actor_id' => $user->getId()]), fn ($f) => DB::remove($f)); - DB::flush(); - Cache::delete($key); - Feed::createDefaultFeeds($user->getId(), $user); - DB::flush(); - throw new RedirectException(); - } - - // Add feed - try { - $match = Router::match($data['url']); - $route = $match['_route']; - DB::persist(Feed::create([ - 'actor_id' => $user->getId(), - 'url' => $data['url'], - 'route' => $route, - 'title' => $data['title'], - 'ordering' => $data['order'], - ])); - DB::flush(); - Cache::delete($key); - throw new RedirectException(); - } catch (ResourceNotFoundException) { - // throw new ClientException(_m('Invalid route')); - // continue bellow - } - } - - return [ - '_template' => 'feeds/edit_feeds.html.twig', - 'edit_feeds' => $form->createView(), - ]; - } - - public function replies(Request $request) - { - // TODO replies - throw new NotImplementedException; - $actor_id = Common::ensureLoggedIn()->getId(); - $notes = DB::dql('select n from App\Entity\Note n ' - . 'where n.reply_to is not null and n.actor_id = :id ' - . 'order by n.created DESC', ['id' => $actor_id], ); - - $notes_out = null; - Event::handle('FormatNoteList', [$notes, &$notes_out]); - - return [ - '_template' => 'feeds/feed.html.twig', - 'notes' => $notes_out, - 'page_title' => 'Replies feed', - ]; - } }