1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* ownCloud - News |
4
|
|
|
* |
5
|
|
|
* This file is licensed under the Affero General Public License version 3 or |
6
|
|
|
* later. See the COPYING file. |
7
|
|
|
* |
8
|
|
|
* @author Alessandro Cosentino <[email protected]> |
9
|
|
|
* @author Bernhard Posselt <[email protected]> |
10
|
|
|
* @copyright Alessandro Cosentino 2012 |
11
|
|
|
* @copyright Bernhard Posselt 2012, 2014 |
12
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
namespace OCA\News\Db; |
15
|
|
|
|
16
|
|
|
use \OCP\AppFramework\Db\Entity; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* @method integer getId() |
20
|
|
|
* @method void setId(integer $value) |
21
|
|
|
* @method string getGuid() |
22
|
|
|
* @method void setGuid(string $value) |
23
|
|
|
* @method string getGuidHash() |
24
|
|
|
* @method void setGuidHash(string $value) |
25
|
|
|
* @method string getUrl() |
26
|
|
|
* @method string getTitle() |
27
|
|
|
* @method string getAuthor() |
28
|
|
|
* @method string getRtl() |
29
|
|
|
* @method string getFingerprint() |
30
|
|
|
* @method string getContentHash() |
31
|
|
|
* @method integer getPubDate() |
32
|
|
|
* @method void setPubDate(integer $value) |
33
|
|
|
* @method string getBody() |
34
|
|
|
* @method string getEnclosureMime() |
35
|
|
|
* @method void setEnclosureMime(string $value) |
36
|
|
|
* @method string getEnclosureLink() |
37
|
|
|
* @method void setEnclosureLink(string $value) |
38
|
|
|
* @method integer getFeedId() |
39
|
|
|
* @method void setFeedId(integer $value) |
40
|
|
|
* @method integer getStatus() |
41
|
|
|
* @method void setStatus(integer $value) |
42
|
|
|
* @method void setRtl(boolean $value) |
43
|
|
|
* @method integer getLastModified() |
44
|
|
|
* @method void setLastModified(integer $value) |
45
|
|
|
* @method void setFingerprint(string $value) |
46
|
|
|
* @method void setContentHash(string $value) |
47
|
|
|
* @method void setSearchIndex(string $value) |
48
|
|
|
*/ |
49
|
|
|
class Item extends Entity implements IAPI, \JsonSerializable { |
50
|
|
|
|
51
|
|
|
use EntityJSONSerializer; |
52
|
|
|
|
53
|
|
|
protected $contentHash; |
54
|
|
|
protected $guidHash; |
55
|
|
|
protected $guid; |
56
|
|
|
protected $url; |
57
|
|
|
protected $title; |
58
|
|
|
protected $author; |
59
|
|
|
protected $pubDate; |
60
|
|
|
protected $body; |
61
|
|
|
protected $enclosureMime; |
62
|
|
|
protected $enclosureLink; |
63
|
|
|
protected $feedId; |
64
|
|
|
protected $status = 0; |
65
|
|
|
protected $lastModified; |
66
|
|
|
protected $searchIndex; |
67
|
|
|
protected $rtl; |
68
|
14 |
|
protected $fingerprint; |
69
|
14 |
|
|
70
|
14 |
|
public function __construct() { |
71
|
14 |
|
$this->addType('pubDate', 'integer'); |
72
|
14 |
|
$this->addType('feedId', 'integer'); |
73
|
14 |
|
$this->addType('status', 'integer'); |
74
|
14 |
|
$this->addType('lastModified', 'integer'); |
75
|
|
|
$this->addType('rtl', 'boolean'); |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
public function setRead() { |
79
|
|
|
$this->markFieldUpdated('status'); |
80
|
|
|
$this->status &= ~StatusFlag::UNREAD; |
81
|
|
|
} |
82
|
4 |
|
|
83
|
4 |
|
public function isRead() { |
84
|
|
|
return !(($this->status & StatusFlag::UNREAD) === StatusFlag::UNREAD); |
85
|
|
|
} |
86
|
1 |
|
|
87
|
1 |
|
public function setUnread() { |
88
|
1 |
|
$this->markFieldUpdated('status'); |
89
|
1 |
|
$this->status |= StatusFlag::UNREAD; |
90
|
|
|
} |
91
|
4 |
|
|
92
|
4 |
|
public function isUnread() { |
93
|
|
|
return !$this->isRead(); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
public function setStarred() { |
97
|
|
|
$this->markFieldUpdated('status'); |
98
|
|
|
$this->status |= StatusFlag::STARRED; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
public function isStarred() { |
102
|
|
|
return ($this->status & StatusFlag::STARRED) === StatusFlag::STARRED; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
public function setUnstarred() { |
106
|
|
|
$this->markFieldUpdated('status'); |
107
|
|
|
$this->status &= ~StatusFlag::STARRED; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
public function isUnstarred() { |
111
|
|
|
return !$this->isStarred(); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Turns entitie attributes into an array |
116
|
|
|
*/ |
117
|
|
|
public function jsonSerialize() { |
118
|
|
|
return [ |
119
|
|
|
'id' => $this->getId(), |
120
|
|
|
'guid' => $this->getGuid(), |
121
|
|
|
'guidHash' => $this->getGuidHash(), |
122
|
|
|
'url' => $this->getUrl(), |
123
|
|
|
'title' => $this->getTitle(), |
124
|
|
|
'author' => $this->getAuthor(), |
125
|
|
|
'pubDate' => $this->getPubDate(), |
126
|
|
|
'body' => $this->getBody(), |
127
|
|
|
'enclosureMime' => $this->getEnclosureMime(), |
128
|
|
|
'enclosureLink' => $this->getEnclosureLink(), |
129
|
|
|
'feedId' => $this->getFeedId(), |
130
|
|
|
'unread' => $this->isUnread(), |
131
|
|
|
'starred' => $this->isStarred(), |
132
|
|
|
'lastModified' => $this->getLastModified(), |
133
|
|
|
'rtl' => $this->getRtl(), |
134
|
|
|
'intro' => $this->getIntro(), |
135
|
|
|
'fingerprint' => $this->getFingerprint(), |
136
|
|
|
]; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
public function toAPI() { |
140
|
|
|
return [ |
141
|
|
|
'id' => $this->getId(), |
142
|
|
|
'guid' => $this->getGuid(), |
143
|
|
|
'guidHash' => $this->getGuidHash(), |
144
|
|
|
'url' => $this->getUrl(), |
145
|
|
|
'title' => $this->getTitle(), |
146
|
|
|
'author' => $this->getAuthor(), |
147
|
|
|
'pubDate' => $this->getPubDate(), |
148
|
|
|
'body' => $this->getBody(), |
149
|
|
|
'enclosureMime' => $this->getEnclosureMime(), |
150
|
|
|
'enclosureLink' => $this->getEnclosureLink(), |
151
|
|
|
'feedId' => $this->getFeedId(), |
152
|
|
|
'unread' => $this->isUnread(), |
153
|
|
|
'starred' => $this->isStarred(), |
154
|
|
|
'lastModified' => $this->getLastModified(), |
155
|
|
|
'rtl' => $this->getRtl(), |
156
|
|
|
'fingerprint' => $this->getFingerprint(), |
157
|
|
|
'contentHash' => $this->getContentHash() |
158
|
|
|
]; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
public function toExport($feeds) { |
162
|
|
|
return [ |
163
|
|
|
'guid' => $this->getGuid(), |
164
|
|
|
'url' => $this->getUrl(), |
165
|
|
|
'title' => $this->getTitle(), |
166
|
|
|
'author' => $this->getAuthor(), |
167
|
|
|
'pubDate' => $this->getPubDate(), |
168
|
|
|
'body' => $this->getBody(), |
169
|
|
|
'enclosureMime' => $this->getEnclosureMime(), |
170
|
|
|
'enclosureLink' => $this->getEnclosureLink(), |
171
|
|
|
'unread' => $this->isUnread(), |
172
|
|
|
'starred' => $this->isStarred(), |
173
|
|
|
'feedLink' => $feeds['feed' . $this->getFeedId()]->getLink(), |
174
|
|
|
'rtl' => $this->getRtl(), |
175
|
|
|
]; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
public function getIntro() { |
179
|
|
|
return strip_tags($this->getBody()); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
public static function fromImport($import) { |
183
|
|
|
$item = new static(); |
184
|
|
|
$item->setGuid($import['guid']); |
185
|
|
|
$item->setGuidHash($import['guid']); |
186
|
|
|
$item->setUrl($import['url']); |
187
|
|
|
$item->setTitle($import['title']); |
188
|
|
|
$item->setAuthor($import['author']); |
189
|
|
|
$item->setPubDate($import['pubDate']); |
190
|
|
|
$item->setBody($import['body']); |
191
|
|
|
$item->setEnclosureMime($import['enclosureMime']); |
192
|
|
|
$item->setEnclosureLink($import['enclosureLink']); |
193
|
|
|
$item->setRtl($import['rtl']); |
194
|
|
|
if ($import['unread']) { |
195
|
|
|
$item->setUnread(); |
196
|
|
|
} else { |
197
|
|
|
$item->setRead(); |
198
|
|
|
} |
199
|
|
|
if ($import['starred']) { |
200
|
|
|
$item->setStarred(); |
201
|
|
|
} else { |
202
|
|
|
$item->setUnstarred(); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
return $item; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
public function setAuthor($name) { |
209
|
14 |
|
parent::setAuthor(strip_tags($name)); |
210
|
14 |
|
} |
211
|
14 |
|
|
212
|
|
|
public function setTitle($title) { |
213
|
|
|
parent::setTitle(strip_tags($title)); |
214
|
14 |
|
} |
215
|
14 |
|
|
216
|
14 |
|
public function generateSearchIndex() { |
217
|
|
|
$this->setSearchIndex( |
218
|
14 |
|
mb_strtolower( |
219
|
14 |
|
html_entity_decode(strip_tags($this->getBody())) . |
220
|
14 |
|
html_entity_decode($this->getAuthor()) . |
221
|
14 |
|
html_entity_decode($this->getTitle()) . |
222
|
14 |
|
$this->getUrl(), |
223
|
14 |
|
'UTF-8' |
224
|
14 |
|
) |
225
|
|
|
); |
226
|
14 |
|
$this->setFingerprint($this->computeFingerprint()); |
227
|
14 |
|
$this->setContentHash($this->computeContentHash()); |
228
|
14 |
|
} |
229
|
14 |
|
|
230
|
|
|
private function computeContentHash() { |
231
|
14 |
|
return md5($this->getTitle() . $this->getUrl() . $this->getBody() . |
232
|
14 |
|
$this->getEnclosureLink() . $this->getEnclosureMime() . |
233
|
14 |
|
$this->getAuthor()); |
234
|
|
|
} |
235
|
|
|
|
236
|
14 |
|
private function computeFingerprint() { |
237
|
14 |
|
return md5($this->getTitle() . $this->getUrl() . $this->getBody() . |
238
|
14 |
|
$this->getEnclosureLink()); |
239
|
14 |
|
} |
240
|
14 |
|
|
241
|
14 |
|
public function setUrl($url) { |
242
|
|
|
$url = trim($url); |
243
|
|
|
if (strpos($url, 'http') === 0 || strpos($url, 'magnet') === 0) { |
244
|
14 |
|
parent::setUrl($url); |
245
|
|
|
} |
246
|
|
|
} |
247
|
14 |
|
|
248
|
14 |
|
public function setBody($body) { |
249
|
14 |
|
// FIXME: this should not happen if the target="_blank" is already |
250
|
14 |
|
// on the link |
251
|
|
|
parent::setBody(str_replace( |
252
|
|
|
'<a', '<a target="_blank" rel="noreferrer"', $body |
253
|
|
|
)); |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
} |
257
|
|
|
|