xref: /webtrees/app/Module/StoriesModule.php (revision 46295629d71d2c598181587a342547db33bf65db)
18c2e8227SGreg Roach<?php
28c2e8227SGreg Roach/**
38c2e8227SGreg Roach * webtrees: online genealogy
48fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team
58c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify
68c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by
78c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or
88c2e8227SGreg Roach * (at your option) any later version.
98c2e8227SGreg Roach * This program is distributed in the hope that it will be useful,
108c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
118c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128c2e8227SGreg Roach * GNU General Public License for more details.
138c2e8227SGreg Roach * You should have received a copy of the GNU General Public License
148c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
158c2e8227SGreg Roach */
16e7f56f2aSGreg Roachdeclare(strict_types=1);
17e7f56f2aSGreg Roach
1876692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
1976692c8bSGreg Roach
200e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth;
210e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
220e62c4b8SGreg Roachuse Fisharebest\Webtrees\Individual;
230e62c4b8SGreg Roachuse Fisharebest\Webtrees\Menu;
240e62c4b8SGreg Roachuse Fisharebest\Webtrees\Tree;
254b92b602SGreg Roachuse Illuminate\Database\Capsule\Manager as DB;
26225e381fSGreg Roachuse stdClass;
2772ac996dSGreg Roachuse Symfony\Component\HttpFoundation\RedirectResponse;
2872ac996dSGreg Roachuse Symfony\Component\HttpFoundation\Request;
2972ac996dSGreg Roachuse Symfony\Component\HttpFoundation\Response;
308c2e8227SGreg Roach
318c2e8227SGreg Roach/**
328c2e8227SGreg Roach * Class StoriesModule
338c2e8227SGreg Roach */
3449a243cbSGreg Roachclass StoriesModule extends AbstractModule implements ModuleInterface, ModuleConfigInterface, ModuleMenuInterface, ModuleTabInterface
35c1010edaSGreg Roach{
3649a243cbSGreg Roach    use ModuleTabTrait;
3749a243cbSGreg Roach    use ModuleConfigTrait;
3849a243cbSGreg Roach    use ModuleMenuTrait;
3949a243cbSGreg Roach
4049a243cbSGreg Roach    /** @var int The default access level for this module.  It can be changed in the control panel. */
4149a243cbSGreg Roach    protected $access_level = Auth::PRIV_HIDE;
4249a243cbSGreg Roach
438c2e8227SGreg Roach    /** {@inheritdoc} */
4449a243cbSGreg Roach    public function title(): string
45c1010edaSGreg Roach    {
46bbb76c12SGreg Roach        /* I18N: Name of a module */
47bbb76c12SGreg Roach        return I18N::translate('Stories');
488c2e8227SGreg Roach    }
498c2e8227SGreg Roach
508c2e8227SGreg Roach    /** {@inheritdoc} */
5149a243cbSGreg Roach    public function description(): string
52c1010edaSGreg Roach    {
53bbb76c12SGreg Roach        /* I18N: Description of the “Stories” module */
54bbb76c12SGreg Roach        return I18N::translate('Add narrative stories to individuals in the family tree.');
558c2e8227SGreg Roach    }
568c2e8227SGreg Roach
57aee13b6dSGreg Roach    /**
5849a243cbSGreg Roach     * The default position for this menu.  It can be changed in the control panel.
59aee13b6dSGreg Roach     *
6049a243cbSGreg Roach     * @return int
61aee13b6dSGreg Roach     */
6249a243cbSGreg Roach    public function defaultMenuOrder(): int
63c1010edaSGreg Roach    {
64*46295629SGreg Roach        return 70;
658c2e8227SGreg Roach    }
668c2e8227SGreg Roach
6749a243cbSGreg Roach    /**
6849a243cbSGreg Roach     * The default position for this tab.  It can be changed in the control panel.
6949a243cbSGreg Roach     *
7049a243cbSGreg Roach     * @return int
7149a243cbSGreg Roach     */
72cbf4b7faSGreg Roach    public function defaultTabOrder(): int
73cbf4b7faSGreg Roach    {
7449a243cbSGreg Roach        return 70;
758c2e8227SGreg Roach    }
768c2e8227SGreg Roach
778c2e8227SGreg Roach    /** {@inheritdoc} */
789b34404bSGreg Roach    public function getTabContent(Individual $individual): string
79c1010edaSGreg Roach    {
8072ac996dSGreg Roach        return view('modules/stories/tab', [
8172ac996dSGreg Roach            'is_admin'   => Auth::isAdmin(),
82225e381fSGreg Roach            'individual' => $individual,
83225e381fSGreg Roach            'stories'    => $this->getStoriesForIndividual($individual),
84225e381fSGreg Roach        ]);
858c2e8227SGreg Roach    }
868c2e8227SGreg Roach
878c2e8227SGreg Roach    /** {@inheritdoc} */
889b34404bSGreg Roach    public function hasTabContent(Individual $individual): bool
89c1010edaSGreg Roach    {
90f4afa648SGreg Roach        return Auth::isManager($individual->tree()) || !empty($this->getStoriesForIndividual($individual));
918c2e8227SGreg Roach    }
928c2e8227SGreg Roach
938c2e8227SGreg Roach    /** {@inheritdoc} */
949b34404bSGreg Roach    public function isGrayedOut(Individual $individual): bool
95c1010edaSGreg Roach    {
96225e381fSGreg Roach        return !empty($this->getStoriesForIndividual($individual));
978c2e8227SGreg Roach    }
988c2e8227SGreg Roach
998c2e8227SGreg Roach    /** {@inheritdoc} */
1009b34404bSGreg Roach    public function canLoadAjax(): bool
101c1010edaSGreg Roach    {
1028c2e8227SGreg Roach        return false;
1038c2e8227SGreg Roach    }
1048c2e8227SGreg Roach
105225e381fSGreg Roach    /**
106225e381fSGreg Roach     * @param Individual $individual
107225e381fSGreg Roach     *
108225e381fSGreg Roach     * @return stdClass[]
109225e381fSGreg Roach     */
110c1010edaSGreg Roach    private function getStoriesForIndividual(Individual $individual): array
111c1010edaSGreg Roach    {
1124b92b602SGreg Roach        $block_ids = DB::table('block')
1134b92b602SGreg Roach            ->where('module_name', '=', $this->getName())
1144b92b602SGreg Roach            ->where('xref', '=', $individual->xref())
1154b92b602SGreg Roach            ->where('gedcom_id', '=', $individual->tree()->id())
1164b92b602SGreg Roach            ->pluck('block_id');
117225e381fSGreg Roach
118225e381fSGreg Roach        $stories = [];
119225e381fSGreg Roach        foreach ($block_ids as $block_id) {
1207d988ec3SGreg Roach            $block_id = (int) $block_id;
1217d988ec3SGreg Roach
122225e381fSGreg Roach            // Only show this block for certain languages
123225e381fSGreg Roach            $languages = $this->getBlockSetting($block_id, 'languages', '');
124225e381fSGreg Roach            if ($languages === '' || in_array(WT_LOCALE, explode(',', $languages))) {
125225e381fSGreg Roach                $stories[] = (object) [
126225e381fSGreg Roach                    'block_id'   => $block_id,
127225e381fSGreg Roach                    'title'      => $this->getBlockSetting($block_id, 'title'),
12872ac996dSGreg Roach                    'story_body' => $this->getBlockSetting($block_id, 'story_body'),
129225e381fSGreg Roach                ];
130225e381fSGreg Roach            }
131225e381fSGreg Roach        }
132225e381fSGreg Roach
133225e381fSGreg Roach        return $stories;
1348c2e8227SGreg Roach    }
1358c2e8227SGreg Roach
1368c2e8227SGreg Roach    /**
1370ee13198SGreg Roach     * A menu, to be added to the main application menu.
1380ee13198SGreg Roach     *
139aee13b6dSGreg Roach     * @param Tree $tree
140aee13b6dSGreg Roach     *
1410ee13198SGreg Roach     * @return Menu|null
1420ee13198SGreg Roach     */
143*46295629SGreg Roach    public function getMenu(Tree $tree): ?Menu
144c1010edaSGreg Roach    {
14549a243cbSGreg Roach        $menu = new Menu($this->title(), route('module', [
146c1010edaSGreg Roach            'module' => $this->getName(),
147c1010edaSGreg Roach            'action' => 'ShowList',
148aa6f03bbSGreg Roach            'ged'    => $tree->name(),
149c1010edaSGreg Roach        ]), 'menu-story');
1508c2e8227SGreg Roach
1518c2e8227SGreg Roach        return $menu;
1528c2e8227SGreg Roach    }
15372ac996dSGreg Roach
15472ac996dSGreg Roach    /**
155b6db7c1fSGreg Roach     * @param Tree $tree
15672ac996dSGreg Roach     *
15772ac996dSGreg Roach     * @return Response
15872ac996dSGreg Roach     */
159b6db7c1fSGreg Roach    public function getAdminAction(Tree $tree): Response
160c1010edaSGreg Roach    {
16172ac996dSGreg Roach        $this->layout = 'layouts/administration';
16272ac996dSGreg Roach
1634b92b602SGreg Roach        $stories = DB::table('block')
1644b92b602SGreg Roach            ->where('module_name', '=', $this->getName())
1654b92b602SGreg Roach            ->where('gedcom_id', '=', $tree->id())
1664b92b602SGreg Roach            ->orderBy('xref')
1674b92b602SGreg Roach            ->get();
16872ac996dSGreg Roach
16972ac996dSGreg Roach        foreach ($stories as $story) {
1705db543e1SGreg Roach            $block_id = (int) $story->block_id;
1715db543e1SGreg Roach
17272ac996dSGreg Roach            $story->individual = Individual::getInstance($story->xref, $tree);
1735db543e1SGreg Roach            $story->title      = $this->getBlockSetting($block_id, 'title');
1745db543e1SGreg Roach            $story->languages  = $this->getBlockSetting($block_id, 'languages');
17572ac996dSGreg Roach        }
17672ac996dSGreg Roach
17772ac996dSGreg Roach        return $this->viewResponse('modules/stories/config', [
17872ac996dSGreg Roach            'stories'    => $stories,
17949a243cbSGreg Roach            'title'      => $this->title() . ' — ' . $tree->title(),
18072ac996dSGreg Roach            'tree'       => $tree,
18172ac996dSGreg Roach            'tree_names' => Tree::getNameList(),
18272ac996dSGreg Roach        ]);
18372ac996dSGreg Roach    }
18472ac996dSGreg Roach
18572ac996dSGreg Roach    /**
18672ac996dSGreg Roach     * @param Request $request
187b6db7c1fSGreg Roach     * @param Tree    $tree
18872ac996dSGreg Roach     *
18972ac996dSGreg Roach     * @return Response
19072ac996dSGreg Roach     */
191b6db7c1fSGreg Roach    public function getAdminEditAction(Request $request, Tree $tree): Response
192c1010edaSGreg Roach    {
19372ac996dSGreg Roach        $this->layout = 'layouts/administration';
19472ac996dSGreg Roach
19572ac996dSGreg Roach        $block_id = (int) $request->get('block_id');
19672ac996dSGreg Roach
19772ac996dSGreg Roach        if ($block_id === 0) {
19872ac996dSGreg Roach            // Creating a new story
19972ac996dSGreg Roach            $individual  = Individual::getInstance($request->get('xref', ''), $tree);
20072ac996dSGreg Roach            $story_title = '';
20172ac996dSGreg Roach            $story_body  = '';
20272ac996dSGreg Roach            $languages   = [];
20372ac996dSGreg Roach
204cc13d6d8SGreg Roach            $title = I18N::translate('Add a story') . ' — ' . e($tree->title());
20572ac996dSGreg Roach        } else {
20672ac996dSGreg Roach            // Editing an existing story
2074b92b602SGreg Roach            $xref = (string) DB::table('block')
2084b92b602SGreg Roach                ->where('block_id', '=', $block_id)
2094b92b602SGreg Roach                ->value('xref');
21072ac996dSGreg Roach
21172ac996dSGreg Roach            $individual  = Individual::getInstance($xref, $tree);
21272ac996dSGreg Roach            $story_title = $this->getBlockSetting($block_id, 'title', '');
21372ac996dSGreg Roach            $story_body  = $this->getBlockSetting($block_id, 'story_body', '');
21472ac996dSGreg Roach            $languages   = explode(',', $this->getBlockSetting($block_id, 'languages'));
21572ac996dSGreg Roach
216cc13d6d8SGreg Roach            $title = I18N::translate('Edit the story') . ' — ' . e($tree->title());
21772ac996dSGreg Roach        }
21872ac996dSGreg Roach
21972ac996dSGreg Roach        return $this->viewResponse('modules/stories/edit', [
22072ac996dSGreg Roach            'block_id'    => $block_id,
22172ac996dSGreg Roach            'languages'   => $languages,
22272ac996dSGreg Roach            'story_body'  => $story_body,
22372ac996dSGreg Roach            'story_title' => $story_title,
22472ac996dSGreg Roach            'title'       => $title,
22572ac996dSGreg Roach            'tree'        => $tree,
22672ac996dSGreg Roach            'individual'  => $individual,
22772ac996dSGreg Roach        ]);
22872ac996dSGreg Roach    }
22972ac996dSGreg Roach
23072ac996dSGreg Roach    /**
23172ac996dSGreg Roach     * @param Request $request
232b6db7c1fSGreg Roach     * @param Tree    $tree
23372ac996dSGreg Roach     *
23472ac996dSGreg Roach     * @return RedirectResponse
23572ac996dSGreg Roach     */
236b6db7c1fSGreg Roach    public function postAdminEditAction(Request $request, Tree $tree): RedirectResponse
237c1010edaSGreg Roach    {
23872ac996dSGreg Roach        $block_id    = (int) $request->get('block_id');
23972ac996dSGreg Roach        $xref        = $request->get('xref', '');
24072ac996dSGreg Roach        $story_body  = $request->get('story_body', '');
24172ac996dSGreg Roach        $story_title = $request->get('story_title', '');
24272ac996dSGreg Roach        $languages   = $request->get('languages', []);
24372ac996dSGreg Roach
24472ac996dSGreg Roach        if ($block_id !== 0) {
2454b92b602SGreg Roach            DB::table('block')
2464b92b602SGreg Roach                ->where('block_id', '=', $block_id)
2474b92b602SGreg Roach                ->update([
2484b92b602SGreg Roach                    'gedcom_id' => $tree->id(),
24972ac996dSGreg Roach                    'xref'      => $xref,
25072ac996dSGreg Roach                ]);
25172ac996dSGreg Roach        } else {
2524b92b602SGreg Roach            DB::table('block')->insert([
2534b92b602SGreg Roach                'gedcom_id'   => $tree->id(),
25472ac996dSGreg Roach                'xref'        => $xref,
2554b92b602SGreg Roach                'module_name' => $this->getName(),
2564b92b602SGreg Roach                'block_order' => 0,
25772ac996dSGreg Roach            ]);
25872ac996dSGreg Roach
2594b92b602SGreg Roach            $block_id = (int) DB::connection()->getPdo()->lastInsertId();
26072ac996dSGreg Roach        }
26172ac996dSGreg Roach
26272ac996dSGreg Roach        $this->setBlockSetting($block_id, 'story_body', $story_body);
26372ac996dSGreg Roach        $this->setBlockSetting($block_id, 'title', $story_title);
26472ac996dSGreg Roach        $this->setBlockSetting($block_id, 'languages', implode(',', $languages));
26572ac996dSGreg Roach
266c1010edaSGreg Roach        $url = route('module', [
26749a243cbSGreg Roach            'module' => $this->getName(),
268c1010edaSGreg Roach            'action' => 'Admin',
269aa6f03bbSGreg Roach            'ged'    => $tree->name(),
270c1010edaSGreg Roach        ]);
27172ac996dSGreg Roach
27272ac996dSGreg Roach        return new RedirectResponse($url);
27372ac996dSGreg Roach    }
27472ac996dSGreg Roach
27572ac996dSGreg Roach    /**
27672ac996dSGreg Roach     * @param Request $request
277b6db7c1fSGreg Roach     * @param Tree    $tree
27872ac996dSGreg Roach     *
27972ac996dSGreg Roach     * @return Response
28072ac996dSGreg Roach     */
281b6db7c1fSGreg Roach    public function postAdminDeleteAction(Request $request, Tree $tree): Response
282c1010edaSGreg Roach    {
28372ac996dSGreg Roach        $block_id = (int) $request->get('block_id');
28472ac996dSGreg Roach
2854b92b602SGreg Roach        DB::table('block_setting')
2864b92b602SGreg Roach            ->where('block_id', '=', $block_id)
2874b92b602SGreg Roach            ->delete();
28872ac996dSGreg Roach
2894b92b602SGreg Roach        DB::table('block')
2904b92b602SGreg Roach            ->where('block_id', '=', $block_id)
2914b92b602SGreg Roach            ->delete();
29272ac996dSGreg Roach
293c1010edaSGreg Roach        $url = route('module', [
29449a243cbSGreg Roach            'module' => $this->getName(),
295c1010edaSGreg Roach            'action' => 'Admin',
296aa6f03bbSGreg Roach            'ged'    => $tree->name(),
297c1010edaSGreg Roach        ]);
29872ac996dSGreg Roach
29972ac996dSGreg Roach        return new RedirectResponse($url);
30072ac996dSGreg Roach    }
30172ac996dSGreg Roach
30272ac996dSGreg Roach    /**
303b6db7c1fSGreg Roach     * @param Tree $tree
30472ac996dSGreg Roach     *
30572ac996dSGreg Roach     * @return Response
30672ac996dSGreg Roach     */
307b6db7c1fSGreg Roach    public function getShowListAction(Tree $tree): Response
308c1010edaSGreg Roach    {
3094b92b602SGreg Roach        $stories = DB::table('block')
3104b92b602SGreg Roach            ->where('module_name', '=', $this->getName())
3114b92b602SGreg Roach            ->where('gedcom_id', '=', $tree->id())
3124b92b602SGreg Roach            ->get()
3134b92b602SGreg Roach            ->map(function (stdClass $story) use ($tree): stdClass {
3145db543e1SGreg Roach                $block_id = (int) $story->block_id;
3155db543e1SGreg Roach
31672ac996dSGreg Roach                $story->individual = Individual::getInstance($story->xref, $tree);
3175db543e1SGreg Roach                $story->title      = $this->getBlockSetting($block_id, 'title');
3185db543e1SGreg Roach                $story->languages  = $this->getBlockSetting($block_id, 'languages');
31972ac996dSGreg Roach
3204b92b602SGreg Roach                return $story;
3214b92b602SGreg Roach            })->filter(function (stdClass $story): bool {
32272ac996dSGreg Roach                // Filter non-existant and private individuals.
3234b92b602SGreg Roach                return $story->individual instanceof Individual && $story->individual->canShow();
3244b92b602SGreg Roach            })->filter(function (stdClass $story): bool {
32572ac996dSGreg Roach                // Filter foreign languages.
326a44b57a9SGreg Roach                return $story->languages === '' || in_array(WT_LOCALE, explode(',', $story->languages));
32772ac996dSGreg Roach            });
32872ac996dSGreg Roach
32972ac996dSGreg Roach        return $this->viewResponse('modules/stories/list', [
33072ac996dSGreg Roach            'stories' => $stories,
33149a243cbSGreg Roach            'title'   => $this->title(),
33272ac996dSGreg Roach        ]);
33372ac996dSGreg Roach    }
3348c2e8227SGreg Roach}
335