]> git.mxchange.org Git - friendica.git/blob - src/Object/Thread.php
Channels are a new way to see different content
[friendica.git] / src / Object / Thread.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Object;
23
24 use Friendica\Content\Conversation;
25 use Friendica\Core\Logger;
26 use Friendica\Core\Protocol;
27 use Friendica\DI;
28 use Friendica\Protocol\Activity;
29 use Friendica\Security\Security;
30
31 /**
32  * A list of threads
33  *
34  * We should think about making this a SPL Iterator
35  */
36 class Thread
37 {
38         /** @var Post[] */
39         private $parents = [];
40         private $mode = null;
41         private $writable = false;
42         private $profile_owner = 0;
43         private $preview = false;
44
45         /**
46          * Constructor
47          *
48          * @param string  $mode     The mode
49          * @param boolean $preview  Are we in the preview mode?
50          * @param boolean $writable Override the writable check
51          * @throws \Exception
52          */
53         public function __construct($mode, $preview, $writable = false)
54         {
55                 $this->setMode($mode, $writable);
56                 $this->preview = $preview;
57         }
58
59         /**
60          * Set the mode we'll be displayed on
61          *
62          * @param string  $mode     The mode to set
63          * @param boolean $writable Override the writable check
64          *
65          * @return void
66          * @throws \Exception
67          */
68         private function setMode($mode, $writable)
69         {
70                 if ($this->getMode() == $mode) {
71                         return;
72                 }
73
74                 $a = DI::app();
75
76                 switch ($mode) {
77                         case Conversation::MODE_NETWORK:
78                         case Conversation::MODE_NOTES:
79                                 $this->profile_owner = DI::userSession()->getLocalUserId();
80                                 $this->writable = true;
81                                 break;
82                         case Conversation::MODE_PROFILE:
83                                 $this->profile_owner = $a->getProfileOwner();
84                                 $this->writable = Security::canWriteToUserWall($this->profile_owner) || $writable;
85                                 break;
86                         case Conversation::MODE_DISPLAY:
87                                 $this->profile_owner = $a->getProfileOwner();
88                                 $this->writable = Security::canWriteToUserWall($this->profile_owner) || $writable;
89                                 break;
90                         case Conversation::MODE_CHANNEL:
91                                 $this->profile_owner = 0;
92                                 $this->writable = $writable;
93                                 break;
94                         case Conversation::MODE_COMMUNITY:
95                                 $this->profile_owner = 0;
96                                 $this->writable = $writable;
97                                 break;
98                         case Conversation::MODE_CONTACTS:
99                                 $this->profile_owner = 0;
100                                 $this->writable = $writable;
101                                 break;
102                         default:
103                                 Logger::info('[ERROR] Conversation::setMode : Unhandled mode ('. $mode .').');
104                                 return false;
105                                 break;
106                 }
107                 $this->mode = $mode;
108         }
109
110         /**
111          * Get mode
112          *
113          * @return string
114          */
115         public function getMode()
116         {
117                 return $this->mode;
118         }
119
120         /**
121          * Check if page is writable
122          *
123          * @return boolean
124          */
125         public function isWritable()
126         {
127                 return $this->writable;
128         }
129
130         /**
131          * Check if page is a preview
132          *
133          * @return boolean
134          */
135         public function isPreview()
136         {
137                 return $this->preview;
138         }
139
140         /**
141          * Get profile owner
142          *
143          * @return integer
144          */
145         public function getProfileOwner()
146         {
147                 return $this->profile_owner;
148         }
149
150         /**
151          * Add a thread to the conversation
152          *
153          * @param Post $item The item to insert
154          *
155          * @return mixed The inserted item on success
156          *               false on failure
157          * @throws \Exception
158          */
159         public function addParent(Post $item)
160         {
161                 $item_id = $item->getId();
162
163                 if (!$item_id) {
164                         Logger::info('[ERROR] Conversation::addThread : Item has no ID!!');
165                         return false;
166                 }
167
168                 if ($this->getParent($item->getId())) {
169                         Logger::info('[WARN] Conversation::addThread : Thread already exists ('. $item->getId() .').');
170                         return false;
171                 }
172
173                 /*
174                  * Only add will be displayed
175                  */
176                 if ($item->getDataValue('network') === Protocol::MAIL && DI::userSession()->getLocalUserId() != $item->getDataValue('uid')) {
177                         Logger::info('[WARN] Conversation::addThread : Thread is a mail ('. $item->getId() .').');
178                         return false;
179                 }
180
181                 if ($item->getDataValue('verb') === Activity::LIKE || $item->getDataValue('verb') === Activity::DISLIKE) {
182                         Logger::info('[WARN] Conversation::addThread : Thread is a (dis)like ('. $item->getId() .').');
183                         return false;
184                 }
185
186                 $item->setThread($this);
187                 $this->parents[] = $item;
188
189                 return end($this->parents);
190         }
191
192         /**
193          * Get data in a form usable by a conversation template
194          *
195          * We should find a way to avoid using those arguments (at least most of them)
196          *
197          * @param array $conv_responses data
198          * @param string $formSecurityToken A 'contact_action' form security token
199          *
200          * @return mixed The data requested on success
201          *               false on failure
202          * @throws \Exception
203          */
204         public function getTemplateData(array $conv_responses, string $formSecurityToken)
205         {
206                 $result = [];
207
208                 foreach ($this->parents as $item) {
209                         if ($item->getDataValue('network') === Protocol::MAIL && DI::userSession()->getLocalUserId() != $item->getDataValue('uid')) {
210                                 continue;
211                         }
212
213                         $item_data = $item->getTemplateData($conv_responses, $formSecurityToken);
214
215                         if (!$item_data) {
216                                 Logger::info('[ERROR] Conversation::getTemplateData : Failed to get item template data ('. $item->getId() .').');
217                                 return false;
218                         }
219                         $result[] = $item_data;
220                 }
221
222                 return $result;
223         }
224
225         /**
226          * Get a thread based on its item id
227          *
228          * @param integer $id Item id
229          *
230          * @return mixed The found item on success
231          *               false on failure
232          */
233         private function getParent($id)
234         {
235                 foreach ($this->parents as $item) {
236                         if ($item->getId() == $id) {
237                                 return $item;
238                         }
239                 }
240
241                 return false;
242         }
243 }