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

feat(episode): add form to allow editing episode's publication date to a past date

This allows podcasters to reorganize their published episodes as they see fit

closes #97
parent 94c0b7c1
Loading
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
    <path fill="none" d="M0 0H24V24H0z"/>
    <path d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12h2c0 4.418 3.582 8 8 8s8-3.582 8-8-3.582-8-8-8C9.536 4 7.332 5.114 5.865 6.865L8 9H2V3l2.447 2.446C6.28 3.336 8.984 2 12 2zm1 5v4.585l3.243 3.243-1.415 1.415L11 12.413V7h2z"/>
</svg>
+12 −11
Original line number Diff line number Diff line
@@ -4,27 +4,28 @@ declare(strict_types=1);

namespace App\Views\Components;

use ViewComponents\Component;

class IconButton extends Component
class IconButton extends Button
{
    public string $glyph = '';

    public function render(): string
    public function __construct(array $attributes)
    {
        $attributes = [
        $iconButtonAttributes = [
            'isSquared' => 'true',
            'title' => $this->slot,
            'title' => $attributes['slot'],
            'data-tooltip' => 'bottom',
        ];

        $attributes = array_merge($attributes, $this->attributes);
        $glyphSize = [
            'small' => 'text-sm',
            'base' => 'text-lg',
            'large' => 'text-2xl',
        ];

        $attributes['slot'] = icon($this->glyph);
        $allAttributes = array_merge($attributes, $iconButtonAttributes);

        unset($attributes['glyph']);
        parent::__construct($allAttributes);

        $iconButton = new Button($attributes);
        return $iconButton->render();
        $this->slot = icon($this->glyph, $glyphSize[$this->size]);
    }
}
+17 −0
Original line number Diff line number Diff line
@@ -327,6 +327,23 @@ $routes->group(
                                    'permission:podcast-manage_publications',
                            ],
                        );
                        $routes->get(
                            'publish-date-edit',
                            'EpisodeController::publishDateEdit/$1/$2',
                            [
                                'as' => 'episode-publish_date_edit',
                                'filter' =>
                                    'permission:podcast-manage_publications',
                            ],
                        );
                        $routes->post(
                            'publish-date-edit',
                            'EpisodeController::attemptPublishDateEdit/$1/$2',
                            [
                                'filter' =>
                                    'permission:podcast-manage_publications',
                            ],
                        );
                        $routes->get(
                            'unpublish',
                            'EpisodeController::unpublish/$1/$2',
+89 −14
Original line number Diff line number Diff line
@@ -683,10 +683,17 @@ class EpisodeController extends BaseController
        return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]);
    }

    public function unpublish(): string | RedirectResponse
    public function publishDateEdit(): string|RedirectResponse
    {
        if ($this->episode->publication_status === 'published') {
            helper(['form']);
        // only accessible if episode is already published
        if ($this->episode->publication_status !== 'published') {
            return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id])->with(
                'error',
                lang('Episode.publish_date_edit_error')
            );
        }

        helper('form');

        $data = [
            'podcast' => $this->podcast,
@@ -697,15 +704,83 @@ class EpisodeController extends BaseController
            0 => $this->podcast->title,
            1 => $this->episode->title,
        ]);
            return view('episode/unpublish', $data);

        return view('episode/publish_date_edit', $data);
    }

    /**
     * Allows to set an episode's publication date to a past date
     *
     * Prevents setting a future date as it does not make sense to set a future published date to an already published
     * episode. This also prevents any side-effects from occurring.
     */
    public function attemptPublishDateEdit(): RedirectResponse
    {
        $rules = [
            'new_publication_date' => 'valid_date[Y-m-d H:i]',
        ];

        if (! $this->validate($rules)) {
            return redirect()
                ->back()
                ->withInput()
                ->with('errors', $this->validator->getErrors());
        }

        $newPublicationDate = $this->request->getPost('new_publication_date');

        $newPublicationDate = Time::createFromFormat(
            'Y-m-d H:i',
            $newPublicationDate,
            $this->request->getPost('client_timezone'),
        )->setTimezone(app_timezone());

        if ($newPublicationDate->isAfter(Time::now())) {
            return redirect()
                ->back()
                ->withInput()
                ->with('error', lang('Episode.publish_date_edit_future_error'));
        }

        $this->episode->published_at = $newPublicationDate;

        $episodeModel = new EpisodeModel();
        if (! $episodeModel->update($this->episode->id, $this->episode)) {
            return redirect()
                ->back()
                ->withInput()
                ->with('errors', $episodeModel->errors());
        }

        return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id])->with(
            'message',
            lang('Episode.publish_date_edit_success')
        );
    }

    public function unpublish(): string | RedirectResponse
    {
        if ($this->episode->publication_status !== 'published') {
            return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id])->with(
                'error',
                lang('Episode.unpublish_error')
            );
        }

        helper(['form']);

        $data = [
            'podcast' => $this->podcast,
            'episode' => $this->episode,
        ];

        replace_breadcrumb_params([
            0 => $this->podcast->title,
            1 => $this->episode->title,
        ]);
        return view('episode/unpublish', $data);
    }

    public function attemptUnpublish(): RedirectResponse
    {
        $rules = [
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ return [
    'persons' => 'persons',
    'publish' => 'publish',
    'publish-edit' => 'edit publication',
    'publish-date-edit' => 'edit publication date',
    'unpublish' => 'unpublish',
    'delete' => 'delete',
    'fediverse' => 'fediverse',
Loading