FacebookFeed_Item::onBeforeWrite()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SunnysideUp\ShareThis;
4
5
use HtmlEditorField;
0 ignored issues
show
Bug introduced by
The type HtmlEditorField was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SunnysideUp\ShareThis\FacebookFeed_Page;
7
use SilverStripe\Security\Permission;
8
use SilverStripe\Control\Director;
9
use SilverStripe\Forms\LiteralField;
10
use SilverStripe\Forms\TextField;
11
use SilverStripe\Core\Injector\Injector;
12
use SunnysideUp\ShareThis\RemoveFacebookItemController;
13
use SilverStripe\ORM\DataObject;
14
use SilverStripe\ORM\Filters\PartialMatchFilter;
15
16
/**
17
 * FROM: http://www.acornartwork.com/blog/2010/04/19/tutorial-facebook-rss-feed-parser-in-pure-php/
18
 * EXAMPLE:
19
 *		//Run the function with the url and a number as arguments
20
 *		$fb = new TheFaceBook_communicator();
21
 *		$dos = $fb->fetchFBFeed('http://facebook.com/feeds/status.php?id=xxxxxx&viewer=xxxxxx&key=xxxxx&format=rss20', 3);
22
 *		//Print Facebook status updates
23
 *		echo '<ul class="fb-updates">';
24
 *			 foreach ($dos as $do) {
25
 *					echo '<li>';
26
 *					echo '<span class="update">' .$do->Description. '</span>';
27
 *					echo '<span class="date">' .$do->Date. '</span>';
28
 *					echo '<span class="link"><a href="' .$do->Link. '">more</a></span>';
29
 *					echo '</li>';
30
 *			 }
31
 *		echo '</ul>';
32
 *
33
 *  SEE README on getting facebook URL for RSS Feed.
34
 *
35
 *
36
 **/
37
class FacebookFeed_Item extends DataObject
38
{
39
    /**
40
     * @var string
41
     */
42
    private static $table_name = 'FacebookFeed_Item';
0 ignored issues
show
introduced by
The private property $table_name is not used, and could be removed.
Loading history...
43
44
    /**
45
     * @var array
46
     */
47
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
48
        "Title" => "Varchar(255)",
49
        "KeepOnTop" => "Boolean",
50
        "Hide" => "Boolean",
51
        "UID" => "Varchar(32)",
52
        "Author" => "Varchar(244)",
53
        "Description" => "HTMLText",
54
        "DescriptionWithShortLink" => "HTMLText",
55
        "Link" => "Varchar(244)",
56
        "PictureLink" => "Text"
57
    ];
58
59
    /**
60
     * @var array
61
     */
62
    private static $summary_fields = [
0 ignored issues
show
introduced by
The private property $summary_fields is not used, and could be removed.
Loading history...
63
        "Created.Nice" => "Created",
64
        "FacebookFeed_Page.Title" => "Feed",
65
        "Title" => "Title",
66
        "KeepOnTopNice" => "Keep on top",
67
        "HideNice" => "Hide",
68
    ];
69
70
    /**
71
     * @var array
72
     */
73
    private static $has_one = [
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
74
        "FacebookFeed_Page" => FacebookFeed_Page::class
75
    ];
76
77
    /**
78
     * @var array
79
     */
80
    private static $indexes = [
0 ignored issues
show
introduced by
The private property $indexes is not used, and could be removed.
Loading history...
81
        "UID" => true
82
    ];
83
84
    /**
85
     * @var array
86
     */
87
    private static $casting = [
0 ignored issues
show
introduced by
The private property $casting is not used, and could be removed.
Loading history...
88
        'KeepOnTopNice' => 'Varchar',
89
        'HideNice' => 'Varchar',
90
        'FacebookPostLink' => 'Varchar'
91
    ];
92
93
    /**
94
     * @var array
95
     */
96
    private static $searchable_fields = [
0 ignored issues
show
introduced by
The private property $searchable_fields is not used, and could be removed.
Loading history...
97
        'Title' => PartialMatchFilter::class,
98
        'Author' => PartialMatchFilter::class,
99
        'Description' => PartialMatchFilter::class
100
    ];
101
102
    /**
103
     * @var string
104
     */
105
    private static $singular_name = "Facebook Item";
0 ignored issues
show
introduced by
The private property $singular_name is not used, and could be removed.
Loading history...
106
107
    /**
108
     * @var string
109
     */
110
    private static $plural_name = "Facebook Items";
0 ignored issues
show
introduced by
The private property $plural_name is not used, and could be removed.
Loading history...
111
112
    /**
113
     * @var string
114
     */
115
    private static $default_sort = "\"Created\" DESC";
0 ignored issues
show
introduced by
The private property $default_sort is not used, and could be removed.
Loading history...
116
117
    /**
118
     * @return boolean
119
     */
120
    public function canCreate($member = null, $context = [])
121
    {
122
        return false;
123
    }
124
125
    /**
126
     * @return boolean
127
     */
128
    public function canView($member = null)
129
    {
130
        return Permission::checkMember($member, 'SOCIAL_MEDIA');
131
    }
132
133
    /**
134
     * @return boolean
135
     */
136
    public function canEdit($member = null)
137
    {
138
        return Permission::checkMember($member, 'SOCIAL_MEDIA');
139
    }
140
141
    /**
142
     * @return boolean
143
     */
144
    public function canDelete($member = null)
145
    {
146
        return false;
147
    }
148
149
    /**
150
     * @return string
151
     */
152
    public function i18n_singular_name()
153
    {
154
        return "Facebook Item";
155
    }
156
157
    /**
158
     * @return string
159
     */
160
    public function i18n_plural_name()
161
    {
162
        return "Facebook Items";
163
    }
164
165
    /**
166
     * @return void
167
     */
168
    public function onBeforeWrite()
169
    {
170
        parent::onBeforeWrite();
171
        $this->DescriptionWithShortLink = $this->Description;
0 ignored issues
show
Bug Best Practice introduced by
The property Description does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property DescriptionWithShortLink does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
172
    }
173
174
    /**
175
     * @return void
176
     */
177
    protected function createDescriptionWithShortLinks()
178
    {
179
        require_once(Director::baseFolder()."/".SS_SHARETHIS_DIR.'/code/api/thirdparty/simple_html_dom.php');
180
        $html = str_get_html($this->Description);
0 ignored issues
show
Bug Best Practice introduced by
The property Description does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
181
        if ($html) {
182
            foreach ($html->find('text') as $element) {
183
                //what exactly does it do?
184
                if (! in_array($element->parent()->tag, array('a', 'img'))) {
185
                    $element->innertext = $this->replaceLinksWithProperOnes($element->innertext);
186
                }
187
            }
188
        } else {
189
            $this->Hide = true;
0 ignored issues
show
Bug Best Practice introduced by
The property Hide does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
190
            $this->write();
191
        }
192
    }
193
194
    /**
195
     * @param  string
196
     *
197
     * @return string
198
     */
199
    protected function replaceLinksWithProperOnes($text)
200
    {
201
        $rexProtocol = '(https?://)?';
202
        $rexDomain   = '((?:[-a-zA-Z0-9]{1,63}\.)+[-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})';
203
        $rexPort     = '(:[0-9]{1,5})?';
204
        $rexPath     = '(/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?';
205
        $rexQuery    = '(\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
206
        $rexFragment = '(#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
207
        $outcome  = "";
208
        $validTlds = array_fill_keys(explode(" ", ".aero .asia .biz .cat .com .coop .edu .gov .info .int .jobs .mil .mobi .museum .name .net .org .pro .tel .travel .ac .ad .ae .af .ag .ai .al .am .an .ao .aq .ar .as .at .au .aw .ax .az .ba .bb .bd .be .bf .bg .bh .bi .bj .bm .bn .bo .br .bs .bt .bv .bw .by .bz .ca .cc .cd .cf .cg .ch .ci .ck .cl .cm .cn .co .cr .cu .cv .cx .cy .cz .de .dj .dk .dm .do .dz .ec .ee .eg .er .es .et .eu .fi .fj .fk .fm .fo .fr .ga .gb .gd .ge .gf .gg .gh .gi .gl .gm .gn .gp .gq .gr .gs .gt .gu .gw .gy .hk .hm .hn .hr .ht .hu .id .ie .il .im .in .io .iq .ir .is .it .je .jm .jo .jp .ke .kg .kh .ki .km .kn .kp .kr .kw .ky .kz .la .lb .lc .li .lk .lr .ls .lt .lu .lv .ly .ma .mc .md .me .mg .mh .mk .ml .mm .mn .mo .mp .mq .mr .ms .mt .mu .mv .mw .mx .my .mz .na .nc .ne .nf .ng .ni .nl .no .np .nr .nu .nz .om .pa .pe .pf .pg .ph .pk .pl .pm .pn .pr .ps .pt .pw .py .qa .re .ro .rs .ru .rw .sa .sb .sc .sd .se .sg .sh .si .sj .sk .sl .sm .sn .so .sr .st .su .sv .sy .sz .tc .td .tf .tg .th .tj .tk .tl .tm .tn .to .tp .tr .tt .tv .tw .tz .ua .ug .uk .us .uy .uz .va .vc .ve .vg .vi .vn .vu .wf .ws .ye .yt .yu .za .zm .zw .xn--0zwm56d .xn--11b5bs3a9aj6g .xn--80akhbyknj4f .xn--9t4b11yi5a .xn--deba0ad .xn--g6w251d .xn--hgbk6aj7f53bba .xn--hlcj6aya9esc7a .xn--jxalpdlp .xn--kgbechtv .xn--zckzah .arpa"), true);
209
210
        $position = 0;
211
        while (preg_match("{\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))}", $text, $match, PREG_OFFSET_CAPTURE, $position)) {
212
            list($url, $urlPosition) = $match[0];
213
214
            // Print the text leading up to the URL.
215
            $outcome .= (htmlspecialchars(substr($text, $position, $urlPosition - $position)));
216
217
            $domain = $match[2][0];
218
            $port   = $match[3][0];
219
            $path   = $match[4][0];
220
221
            // Check if the TLD is valid - or that $domain is an IP address.
222
            $tld = strtolower(strrchr($domain, '.'));
223
            if (preg_match('{\.[0-9]{1,3}}', $tld) || isset($validTlds[$tld])) {
224
                // Prepend http:// if no protocol specified
225
                $completeUrl = $match[1][0] ? $url : "http://$url";
226
227
                // Print the hyperlink.
228
                $outcome .= sprintf('<a href="%s">%s</a>', htmlspecialchars($completeUrl), htmlspecialchars("$domain$port$path"));
229
            } else {
230
                // Not a valid URL.
231
                $outcome .= (htmlspecialchars($url));
232
            }
233
234
            // Continue text parsing from after the URL.
235
            $position = $urlPosition + strlen($url);
236
        }
237
238
        // Print the remainder of the text.
239
        $outcome .= ((substr($text, $position)));
240
        return $outcome;
241
    }
242
243
    /**
244
     * @return FieldList $fields
0 ignored issues
show
Bug introduced by
The type SunnysideUp\ShareThis\FieldList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
245
     */
246
    public function getCMSFields()
247
    {
248
        $fields = parent::getCMSFields();
249
250
        $fields->removeByName("UID");
251
        $fields->removeByName("PictureLink");
252
253
        if ($this->PictureLink) {
0 ignored issues
show
Bug Best Practice introduced by
The property PictureLink does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
254
            $fields->addFieldToTab("Root.Main", LiteralField::create("PictureLinkIMG", "<img src=\"".$this->PictureLink."\" alt=\"\" />"), "Author");
255
        }
256
257
        if ($this->Link) {
0 ignored issues
show
Bug Best Practice introduced by
The property Link does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
258
            $fields->addFieldToTab("Root.Main", LiteralField::create("LinkLink", "<h2><a href=\"".$this->Link."\" >go to link final link: ".substr($this->Link, 0, 45)."...</a></h2>"), "Author");
259
            $fields->addFieldToTab("Root.Main", LiteralField::create("LinkLink", "<h2><a href=\"".$this->getFacebookPostLink()."\" >go to face book post: ".substr($this->getFacebookPostLink(), 0, 45)."...</a></h2>"), "Author");
260
            $fields->addFieldToTab("Root.RawData", TextField::create("Link", "Link"));
261
        }
262
263
        if ($this->Description) {
0 ignored issues
show
Bug Best Practice introduced by
The property Description does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
264
            $fields->addFieldToTab("Root.RawData", HtmlEditorField::create("Description"));
265
            $fields->addFieldToTab("Root.Main", HtmlEditorField::create("DescriptionWithShortLink", "Edited Description"));
266
        }
267
268
        return $fields;
269
    }
270
271
    /**
272
     * KeepOnTopNice
273
     */
274
    public function KeepOnTopNice()
275
    {
276
        return $this->dbObject('KeepOnTop')->Nice();
277
    }
278
279
    /**
280
     * HideNice
281
     */
282
    public function HideNice()
283
    {
284
        return $this->dbObject('Hide')->Nice();
285
    }
286
287
    /**
288
     * @return string
289
     */
290
    public function getFacebookPostLink()
291
    {
292
        return "https://facebook.com/" . $this->UID;
0 ignored issues
show
Bug Best Practice introduced by
The property UID does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
293
    }
294
295
    /**
296
     * is the link attached to the FB post a link back to this site?
297
     *
298
     * @return bool
299
     */
300
    public function IsLinkBackToSite()
301
    {
302
        $currentURL = Director::absoluteBaseURL();
303
        if (strpos($this->Link, $currentURL) === false) {
0 ignored issues
show
Bug Best Practice introduced by
The property Link does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
304
            return false;
305
        }
306
        return true;
307
    }
308
309
    /**
310
     * returns a link back to the same site if that is what the FB post links to
311
     * or a link to FB if it ultimately links to third-party site.
312
     *
313
     * @return strring
0 ignored issues
show
Bug introduced by
The type SunnysideUp\ShareThis\strring was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
314
     */
315
    public function SmartLink()
316
    {
317
        if ($this->IsLinkBackToSite()) {
318
            return $this->Link;
0 ignored issues
show
Bug Best Practice introduced by
The property Link does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
319
        } else {
320
            return $this->getFacebookPostLink();
321
        }
322
    }
323
324
    /**
325
     * Check whether Facebook post exists
326
     */
327
    public function fbpostExists()
328
    {
329
        $exists = true;
330
        $handle = curl_init($this->getFacebookPostLink());
331
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

331
        curl_setopt(/** @scrutinizer ignore-type */ $handle, CURLOPT_RETURNTRANSFER, true);
Loading history...
332
333
        /* Get the HTML or whatever is linked in $url. */
334
        $response = curl_exec($handle);
0 ignored issues
show
Unused Code introduced by
The assignment to $response is dead and can be removed.
Loading history...
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

334
        $response = curl_exec(/** @scrutinizer ignore-type */ $handle);
Loading history...
335
336
        /* Check for 404 (file not found). */
337
        $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

337
        $httpCode = curl_getinfo(/** @scrutinizer ignore-type */ $handle, CURLINFO_HTTP_CODE);
Loading history...
338
        if ($httpCode !== 200 && $httpCode !== 301) {
339
            $exists = false;
340
        }
341
342
        curl_close($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

342
        curl_close(/** @scrutinizer ignore-type */ $handle);
Loading history...
343
344
        return $exists();
345
    }
346
347
    /**
348
     * @return boolean
349
     */
350
    public function canRemove()
351
    {
352
        return Permission::check('CMS_ACCESS_CMSMain') ? true : false;
353
    }
354
355
    /**
356
     * Remove the link
357
     *
358
     * @return string
359
     */
360
    public function RemoveLink()
361
    {
362
        $obj = Injector::inst()->get(RemoveFacebookItemController::class);
363
364
        return $obj->Link('remove/'.$this->UID.'/');
0 ignored issues
show
Bug Best Practice introduced by
The property UID does not exist on SunnysideUp\ShareThis\FacebookFeed_Item. Since you implemented __get, consider adding a @property annotation.
Loading history...
365
    }
366
}
367