Issues (326)

src/Controller/Component/PostingComponent.php (3 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace App\Controller\Component;
14
15
use App\Model\Entity\Entry;
16
use App\Model\Table\EntriesTable;
17
use Cake\Controller\Component;
18
use Cake\ORM\TableRegistry;
19
use Saito\Exception\SaitoForbiddenException;
20
use Saito\Posting\Basic\BasicPostingInterface;
21
use Saito\Posting\Posting;
22
use Saito\User\CurrentUser\CurrentUserInterface;
23
24
class PostingComponent extends Component
25
{
26
27
    /**
28
     * Creates a new posting from user
29
     *
30
     * @param array $data raw posting data
31
     * @param CurrentUserInterface $CurrentUser the current user
32
     * @return Entry|null on success, null otherwise
33
     */
34
    public function create(array $data, CurrentUserInterface $CurrentUser): ?Entry
35
    {
36
        if (!empty($data['pid'])) {
37
            /// new posting is answer to existing posting
38
            $parent = $this->getTable()->get($data['pid']);
39
            $data = $this->prepareChildPosting($parent, $data);
0 ignored issues
show
$parent of type Cake\Datasource\EntityInterface|array is incompatible with the type Saito\Posting\Basic\BasicPostingInterface expected by parameter $parent of App\Controller\Component...::prepareChildPosting(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

39
            $data = $this->prepareChildPosting(/** @scrutinizer ignore-type */ $parent, $data);
Loading history...
40
        } else {
41
            /// if no pid is provided the new posting is root-posting
42
            $data['pid'] = 0;
43
            // We can't wait for entity-validation cause we check the category
44
            // in permissions.
45
            if (!isset($data['category_id'])) {
46
                throw new \InvalidArgumentException(
47
                    'No category for new posting provided.',
48
                    1573123345
49
                );
50
            }
51
        }
52
53
        $posting = new Posting($data + ['id' => 0]);
54
        $action = $posting->isRoot() ? 'thread' : 'answer';
55
        // @td better return !$posting->isAnsweringForbidden();
56
        $allowed = $CurrentUser->getCategories()->permission($action, $posting->get('category_id'));
57
        if ($allowed !== true) {
58
            throw new SaitoForbiddenException('Creating new posting not allowed.');
59
        }
60
61
        return $this->getTable()->createEntry($data);
62
    }
63
64
    /**
65
     * Updates an existing posting
66
     *
67
     * @param Entry $entry the posting to update
68
     * @param array $data data the posting should be updated with
69
     * @param CurrentUserInterface $CurrentUser the current-user
70
     * @return Entry|null the posting which was asked to update
71
     */
72
    public function update(Entry $entry, array $data, CurrentUserInterface $CurrentUser): ?Entry
73
    {
74
        $isRoot = $entry->isRoot();
75
76
        if (!$isRoot) {
77
            $parent = $this->getTable()->get($entry->get('pid'));
78
            $data = $this->prepareChildPosting($parent, $data);
0 ignored issues
show
$parent of type Cake\Datasource\EntityInterface|array is incompatible with the type Saito\Posting\Basic\BasicPostingInterface expected by parameter $parent of App\Controller\Component...::prepareChildPosting(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

78
            $data = $this->prepareChildPosting(/** @scrutinizer ignore-type */ $parent, $data);
Loading history...
79
        }
80
81
        $allowed = $entry->toPosting()->withCurrentUser($CurrentUser)->isEditingAllowed();
82
        if ($allowed !== true) {
83
            throw new SaitoForbiddenException('Updating posting not allowed.');
84
        }
85
86
        return $this->getTable()->updateEntry($entry, $data);
87
    }
88
89
    /**
90
     * Populates data of an child derived from its parent-posting
91
     *
92
     * @param BasicPostingInterface $parent parent data
93
     * @param array $data current posting data
94
     * @return array populated $data
95
     */
96
    public function prepareChildPosting(BasicPostingInterface $parent, array $data): array
97
    {
98
        if (empty($data['subject'])) {
99
            // if new subject is empty use the parent's subject
100
            $data['subject'] = $parent->get('subject');
101
        }
102
103
        $data['category_id'] = $data['category_id'] ?? $parent->get('category_id');
104
        $data['tid'] = $parent->get('tid');
105
106
        return $data;
107
    }
108
109
    /**
110
     * Get Entries table
111
     *
112
     * @return EntriesTable
113
     */
114
    protected function getTable(): EntriesTable
115
    {
116
        /** @var EntriesTable */
117
        $table = TableRegistry::getTableLocator()->get('Entries');
118
119
        return $table;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $table returns the type Cake\ORM\Table which includes types incompatible with the type-hinted return App\Model\Table\EntriesTable.
Loading history...
120
    }
121
}
122