Completed
Pull Request — master (#9)
by
unknown
08:34
created

FacebookFeed_Page::Fetch()   D

Complexity

Conditions 18
Paths 16

Size

Total Lines 64

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
nc 16
nop 1
dl 0
loc 64
rs 4.8666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SunnysideUp\ShareThis;
4
5
use SilverStripe\Forms\TreeMultiSelectField;
6
use SunnysideUp\ShareThis\FacebookFeed_Item;
7
use SilverStripe\CMS\Model\SiteTree;
8
use SilverStripe\Security\Permission;
9
use SilverStripe\Forms\LiteralField;
10
use SilverStripe\ORM\DB;
11
use SunnysideUp\ShareThis\SilverstripeFacebookConnector;
12
use SilverStripe\ORM\DataObject;
13
14
/**
15
 * FROM: http://www.acornartwork.com/blog/2010/04/19/tutorial-facebook-rss-feed-parser-in-pure-php/
16
 * EXAMPLE:
17
 *		//Run the function with the url and a number as arguments
18
 *		$fb = new TheFaceBook_communicator();
19
 *		$dos = $fb->fetchFBFeed('http://facebook.com/feeds/status.php?id=xxxxxx&viewer=xxxxxx&key=xxxxx&format=rss20', 3);
20
 *		//Print Facebook status updates
21
 *		echo '<ul class="fb-updates">';
22
 *			 foreach ($dos as $do) {
23
 *					echo '<li>';
24
 *					echo '<span class="update">' .$do->Description. '</span>';
25
 *					echo '<span class="date">' .$do->Date. '</span>';
26
 *					echo '<span class="link"><a href="' .$do->Link. '">more</a></span>';
27
 *					echo '</li>';
28
 *			 }
29
 *		echo '</ul>';
30
 *
31
 *  SEE README on getting facebook URL for RSS Feed.
32
 *
33
 *
34
 **/
35
class FacebookFeed_Page extends DataObject
36
{
37
    /**
38
     * @var string
39
     */
40
    private static $table_name = 'FacebookFeed_Page';
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
41
42
    /**
43
     * @var array
44
     */
45
    private static $db = [
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
46
        "Title" => "Varchar(244)",
47
        'FacebookPageID' => 'Varchar(40)'
48
    ];
49
50
    /**
51
     * @var array
52
     */
53
    private static $has_many = [
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
54
        'Items' => FacebookFeed_Item::class
55
    ];
56
57
    /**
58
     * @var array
59
     */
60
    private static $many_many = [
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
61
        'Pages' => SiteTree::class
62
    ];
63
64
    /**
65
     * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
66
     */
67
    public function canCreate($member = null, $context = [])
68
    {
69
        return Permission::checkMember($member, 'SOCIAL_MEDIA');
70
    }
71
72
    /**
73
     * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
74
     */
75
    public function canView($member = null)
76
    {
77
        return Permission::checkMember($member, 'SOCIAL_MEDIA');
78
    }
79
80
    /**
81
     * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
82
     */
83
    public function canEdit($member = null)
84
    {
85
        return Permission::checkMember($member, 'SOCIAL_MEDIA');
86
    }
87
88
    /**
89
     * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
90
     */
91
    public function canDelete($member = null)
92
    {
93
        return Permission::checkMember($member, 'SOCIAL_MEDIA');
94
    }
95
96
    /**
97
     * @return FieldList $fields
0 ignored issues
show
Documentation introduced by
Should the return type not be \SilverStripe\Forms\FieldList?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
98
     */
99
    public function getCMSFields()
100
    {
101
        $fields = parent::getCMSFields();
102
103
        $fields->addFieldToTab(
104
            "Root.Main",
105
            LiteralField::create(
106
                "HowToFindPageID",
107
                "<p>
108
                To find the Facebook Page ID value, you can follow these steps :</p>
109
                <ol>
110
                    <li>Open a new tab and open <a href=\"http://www.facebook.com\" target=\"_blank\">facebook</a></li>
111
                    <li>Find your page (e.g. https://www.facebook.com/EOSAsia)</li>
112
                    <li>Note the name (e.g. EOSAsia)</li>
113
                    <li>Go to <a href=\"http://findmyfacebookid.com\" target=\"_blank\">http://findmyfacebookid.com</a></li>
114
                    <li>Enter http://www.facebook.com/EOSAsia</li>
115
                    <li>You'll get the answer (e.g. 357864420974239)</li>
116
                </ol>"
117
            )
118
        );
119
120
        $fields->addFieldToTab(
121
            "Root.Pages",
122
            TreeMultiSelectField::create("Pages", "Show on", SiteTree::class)
123
        );
124
125
        $pages = $this->Pages();
0 ignored issues
show
Documentation Bug introduced by
The method Pages does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Page>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
126
127
        if ($pages && $pages->count()) {
128
            $links = [];
129
130
            foreach ($pages as $page) {
131
                $links[] = "<li><a href=\"".$page->Link("updatefb")."\">".$page->Title."</a></li>";
132
            }
133
134
            if (count($links)) {
135
                $fields->addFieldToTab(
136
                    "Root.Pages",
137
                    LiteralField::create(
138
                        "LinksToCheck",
139
                        "<p>
140
                            Choose the links below to view your facebook feed:
141
                        <ol>
142
                            ".implode("", $links)."
143
                        </ol>"
144
                    )
145
                );
146
            }
147
        }
148
149
        return $fields;
150
    }
151
152
    /**
153
     *
154
     * @param SiteTree | Int $page - page or page id
155
     * @param Int $limit
156
     *
157
     */
158
    public static function all_for_one_page($page, $limit = 10)
159
    {
160
        if ($page instanceof SiteTree) {
161
            $pageID = $page->ID;
162
        } else {
163
            $pageID = $page;
164
        }
165
166
        $feedIDs = [];
167
168
        $sql = "
169
            SELECT \"FacebookFeed_Page_Pages\".\"FacebookFeed_PageID\"
170
            FROM \"FacebookFeed_Page_Pages\"
171
            WHERE \"FacebookFeed_Page_Pages\".\"SiteTreeID\" = $pageID";
172
173
        $rows = DB::query($sql);
174
175
        if ($rows) {
176
            foreach ($rows as $row) {
177
                $feedIDs[$row["FacebookFeed_PageID"]] = $row["FacebookFeed_PageID"];
178
            }
179
        }
180
181
        if (count($feedIDs)) {
182
            return FacebookFeed_Item::get()->filter(
183
                [
184
                    "FacebookFeed_PageID" => $feedIDs,
185
                    "Hide" => 0
186
                ]
187
            )
188
            ->limit($limit);
189
        }
190
    }
191
192
    /**
193
     * ShowableItems
194
     * @param integer $limit
195
     */
196
    public function ShowableItems($limit = 10)
197
    {
198
        return $this->getComponents('Items', 'Hide = 0', null, '', $limit);
0 ignored issues
show
Unused Code introduced by
The call to FacebookFeed_Page::getComponents() has too many arguments starting with null.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
199
    }
200
201
    /**
202
     * Fetch
203
     * @param boolean $verbose
204
     */
205
    public function Fetch($verbose = false)
206
    {
207
        $count = 0;
208
        if ($this->FacebookPageID) {
0 ignored issues
show
Documentation introduced by
The property FacebookPageID does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Page>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
209
            $items = SilverstripeFacebookConnector::get_feed($this->FacebookPageID);
0 ignored issues
show
Documentation introduced by
The property FacebookPageID does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Page>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
210
211
            if ($items) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $items of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
212
                foreach ($items as $item) {
213
                    $filter = [
214
                        "UID" => $item["id"]
215
                    ];
216
217
                    if (! FacebookFeed_Item::get()->filter($filter)->first()) {
218
                        $count++;
219
                        $message = "";
220
221
                        if (isset($item["message"])) {
222
                            $message = $item["message"];
223
                        } elseif (isset($item["description"])) {
224
                            $message = $item["description"];
225
                        }
226
227
                        //Converts UTF-8 into ISO-8859-1 to solve special symbols issues
228
                        $message = iconv("UTF-8", "ISO-8859-1//TRANSLIT", $message);
229
                        $message = $this->stripUnsafe($message);
230
231
                        //Get status update time
232
                        $pubDate = strtotime(isset($item["created_time"]) ? $item["created_time"] : "today");
233
234
                        //Customize this to your liking
235
                        $convertedDate = gmdate($timeFormat = 'Y-m-d', $pubDate);
236
237
                        //Store values in array
238
                        $obj = FacebookFeed_Item::create($filter);
239
                        $obj->Title = (string) (isset($item["name"]) ? $item["name"] : "");
240
                        $obj->Date = $convertedDate;
0 ignored issues
show
Documentation introduced by
The property Date does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Item>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
241
                        $obj->Author = (string) (isset($item["from"]["name"]) ? $item["from"]["name"] : "");
0 ignored issues
show
Documentation introduced by
The property Author does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Item>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
242
                        $obj->Link = (string) (isset($item["link"]) ? $item["link"] : "");
0 ignored issues
show
Documentation introduced by
The property Link does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Item>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
243
                        $obj->PictureLink = (string) (isset($item["full_picture"]) ? $item["full_picture"] : "");
0 ignored issues
show
Documentation introduced by
The property PictureLink does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Item>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
244
                        $obj->Description = $message;
0 ignored issues
show
Documentation introduced by
The property Description does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Item>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
245
                        $obj->FacebookFeed_PageID = $this->ID;
0 ignored issues
show
Documentation introduced by
The property FacebookFeed_PageID does not exist on object<SunnysideUp\ShareThis\FacebookFeed_Item>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
246
                        $obj->write();
247
                    }
248
                }
249
            } else {
250
                if ($verbose) {
251
                    DB::alteration_message("ERROR: no data returned", "deleted");
252
                }
253
            }
254
255
            if ($count == 0 && $verbose) {
256
                DB::alteration_message("Nothing to add.");
257
            }
258
259
        } else {
260
            if ($verbose) {
261
                DB::alteration_message("ERROR: no Facebook Page ID provided", "deleted");
262
            }
263
        }
264
265
        if ($count && $verbose) {
266
            DB::alteration_message("Added $count items", "created");
267
        }
268
    }
269
270
    /**
271
     * stripUnsafe
272
     * @param  string $string
273
     *
274
     * @return string $string
275
     */
276
    public function stripUnsafe($string)
277
    {
278
        // Unsafe HTML tags that members may abuse
279
        $unsafe = [
280
            '/onmouseover="(.*?)"/is',
281
            '/onclick="(.*?)"/is',
282
            '/style="(.*?)"/is',
283
            '/target="(.*?)"/is',
284
            '/onunload="(.*?)"/is',
285
            '/rel="(.*?)"/is',
286
            '/<a(.*?)>/is',
287
            '/<\/a>/is'
288
        ];
289
290
        $string= preg_replace($unsafe, " ", $string);
291
        return $string;
292
    }
293
}
294