• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Freegle / iznik-server / ac01ac35-adb7-4112-8801-592c373b89ea

11 Jun 2024 08:22AM UTC coverage: 94.856% (-0.007%) from 94.863%
ac01ac35-adb7-4112-8801-592c373b89ea

push

circleci

edwh
Add user id and gift aid id to gift aid claim csv

25431 of 26810 relevant lines covered (94.86%)

31.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.35
/include/misc/Shortlink.php
1
<?php
2
namespace Freegle\Iznik;
3

4

5

6
class Shortlink extends Entity
7
{
8
    /** @var  $dbhm LoggedPDO */
9
    var $publicatts = array('id', 'name', 'type', 'groupid', 'url', 'clicks', 'created');
10
    var $settableatts = array('name');
11

12
    const TYPE_GROUP = 'Group';
13
    const TYPE_OTHER = 'Other';
14

15
    function __construct(LoggedPDO $dbhr, LoggedPDO $dbhm, $id = NULL)
16
    {
17
        $this->fetch($dbhr, $dbhm, $id, 'shortlinks', 'shortlink', $this->publicatts);
356✔
18
    }
19

20
    public function create($name, $type, $groupid = NULL, $url = NULL) {
21
        $ret = NULL;
317✔
22

23
        $rc = $this->dbhm->preExec("INSERT INTO shortlinks (name, type, groupid, url) VALUES (?,?,?,?);", [
317✔
24
            $name,
317✔
25
            $type,
317✔
26
            $groupid,
317✔
27
            $url
317✔
28
        ]);
317✔
29

30
        $id = $this->dbhm->lastInsertId();
317✔
31

32
        if ($rc && $id) {
317✔
33
            $this->fetch($this->dbhm, $this->dbhm, $id, 'shortlinks', 'shortlink', $this->publicatts);
317✔
34
            $ret = $id;
317✔
35
        }
36

37
        return($ret);
317✔
38
    }
39

40
    public function resolve($name, $countclicks = TRUE) {
41
        $url = NULL;
3✔
42
        $id = NULL;
3✔
43
        $links = $this->dbhr->preQuery("SELECT * FROM shortlinks WHERE name LIKE ?;", [ $name ]);
3✔
44
        foreach ($links as $link) {
3✔
45
            $id = $link['id'];
3✔
46
            if ($link['type'] == Shortlink::TYPE_GROUP) {
3✔
47
                $g = new Group($this->dbhr, $this->dbhm, $link['groupid']);
2✔
48

49
                # Where we redirect to depends on the group settings.
50
                $external = $g->getPrivate('external');
2✔
51

52
                if ($external) {
2✔
53
                    $url = $external;
×
54
                } else {
55
                    $url = $g->getPrivate('onhere') ? ('https://' . USER_SITE . '/explore/' . $g->getPrivate('nameshort')) : ('https://groups.yahoo.com/' . $g->getPrivate('nameshort'));
2✔
56
                }
57
            } else {
58
                $url = $link['url'];
1✔
59

60
                if (strpos($url, 'http://groups.yahoo.com/group/') === 0) {
1✔
61
                    $url = str_replace('http://groups.yahoo.com/group/', 'http://groups.yahoo.com/neo/groups/', $url);
×
62
                }
63
            }
64

65
            if ($countclicks) {
3✔
66
                $this->dbhm->background("UPDATE shortlinks SET clicks = clicks + 1 WHERE id = {$link['id']};");
2✔
67
                $this->dbhm->background("INSERT INTO shortlink_clicks (shortlinkid) VALUES ({$link['id']});");
2✔
68
            }
69
        }
70

71
        return([$id, $url]);
3✔
72
    }
73

74
    public function listAll($groupid = NULL) {
75
        $groupq = $groupid ? " WHERE groupid = $groupid " : "";
3✔
76
        $links = $this->dbhr->preQuery("SELECT * FROM shortlinks $groupq ORDER BY LOWER(name) ASC;");
3✔
77
        foreach ($links as &$link) {
3✔
78
            if ($link['type'] == Shortlink::TYPE_GROUP) {
3✔
79
                $g = new Group($this->dbhr, $this->dbhm, $link['groupid']);
3✔
80
                $link['nameshort'] = $g->getPrivate('nameshort');
3✔
81

82
                # Where we redirect to depends on the group settings.
83
                $link['url'] = $g->getPrivate('onhere') ? ('https://' . USER_SITE . '/explore/' . $g->getPrivate('nameshort')) : ('https://groups.yahoo.com/neo/groups' . $g->getPrivate('nameshort'));
3✔
84
            }
85
        }
86

87
        return($links);
3✔
88
    }
89

90
    public function getPublic() {
91
        $ret = $this->getAtts($this->publicatts);
3✔
92
        $ret['created'] = Utils::ISODate($ret['created']);
3✔
93

94
        if ($ret['type'] == Shortlink::TYPE_GROUP) {
3✔
95
            $g = new Group($this->dbhr, $this->dbhm, $ret['groupid']);
2✔
96
            $ret['nameshort'] = $g->getPrivate('nameshort');
2✔
97

98
            # Where we redirect to depends on the group settings.
99
            $ret['url'] = $g->getPrivate('onhere') ? ('https://' . USER_SITE . '/explore/' . $g->getPrivate('nameshort')) : ('https://groups.yahoo.com/neo/groups' . $g->getPrivate('nameshort'));
2✔
100
        }
101

102
        $clickhistory = $this->dbhr->preQuery("SELECT DATE(timestamp) AS date, COUNT(*) AS count FROM `shortlink_clicks` WHERE shortlinkid = ? GROUP BY date ORDER BY date ASC", [
3✔
103
            $this->id
3✔
104
        ]);
3✔
105
        foreach ($clickhistory as &$c) {
3✔
106
            $c['date'] = Utils::ISODate($c['date']);
1✔
107
        }
108
        $ret['clickhistory'] = $clickhistory;
3✔
109
        return($ret);
3✔
110
    }
111

112
    public function delete() {
113
        $rc = $this->dbhm->preExec("DELETE FROM shortlinks WHERE id = ?;", [$this->id]);
2✔
114
        return($rc);
2✔
115
    }
116

117
    public function expandExternal($url, $depth = 1) {
118
        $ret = Spam::URL_REMOVED;
40✔
119

120
        if ($depth > 10) {
40✔
121
            # Redirect loop?
122
            error_log("Loop in $url at $depth");
×
123
            return $ret;
×
124
        }
125

126
        if (strpos($url, 'https://' . USER_SITE) === 0 || strpos($url, USER_TEST_SITE) === 0) {
40✔
127
            # Ours - so no need to expand.
128
            error_log("URL $url is our domain " . USER_SITE . " or " . USER_TEST_SITE);
8✔
129
            return $url;
8✔
130
        }
131

132
        if (stripos($url, 'www.facebook.com')) {
38✔
133
            # Facebook bounces us with unsupported browser, but we don't need to expand them anyway.
134
            error_log("URL $url is Facebook");
×
135
            return $url;
×
136
        }
137

138
        if (stripos($url, 'http') !== 0) {
38✔
139
            # We don't want to follow http links.
140
            error_log("Add http:// to $url");
4✔
141
            $url = "http://$url";
4✔
142
        }
143

144
        try {
145
            # Timeout - if a shortener doesn't return in time we'll filter out the URL.
146
            $opts['http']['timeout'] = 5;
38✔
147
            $context = stream_context_create($opts);
38✔
148

149
            $response = get_headers($url, 1, $context);
38✔
150

151
            if ($response) {
38✔
152
                # The location property of the response header is used for redirect.
153
                if (array_key_exists('Location', $response)) {
31✔
154
                    $location = $response["Location"];
14✔
155

156
                    if (is_array($location)) {
14✔
157
                        # Find the first entry  in the array starting with http
158
                        $newloc = null;
12✔
159

160
                        foreach ($location as $l) {
12✔
161
                            if (strpos($l, 'http') === 0) {
12✔
162
                                $newloc = $l;
12✔
163
                                break;
12✔
164
                            }
165
                        }
166

167
                        if ($newloc) {
12✔
168
                            $ret = $this->expandExternal($newloc, $depth + 1);
12✔
169
                        } else {
170
                            error_log("Redirect not handled for $url: " . json_encode($location));
×
171
                            $ret = Spam::URL_REMOVED;
12✔
172
                        }
173
                    } else if (stripos($location, 'http') === FALSE) {
14✔
174
                        // Not a link - probably redirecting to relative path.
175
                        $ret = $url;
2✔
176
                    } else {
177
                        $ret = $this->expandExternal($location, $depth + 1);
14✔
178
                    }
179
                } else {
180
                    $ret = $url;
31✔
181
                }
182
            } else {
183
                error_log("$url returned no response");
38✔
184
            }
185
        } catch (\Exception $e) {
×
186
            error_log("Failed to expand $url: " . $e->getMessage());
×
187
        }
188

189
        return $ret;
38✔
190
    }
191

192
    function expandAllUrls($str) {
193
        $urls = [];
271✔
194

195
        if (preg_match_all(Utils::URL_PATTERN, $str, $matches)) {
271✔
196
            foreach ($matches as $val) {
39✔
197
                foreach ($val as $url) {
39✔
198
                    $urls[] = $url;
39✔
199
                }
200
            }
201

202
            $urls = array_unique($urls);
39✔
203

204
            foreach ($urls as $url) {
39✔
205
                if ($url) {
39✔
206
                    $newurl = $this->expandExternal($url);
39✔
207

208
                    if ($newurl != $url) {
39✔
209
                        $str = str_replace($url, $newurl, $str);
20✔
210
                        error_log("Expand $url to $newurl");
20✔
211
                    }
212
                }
213
            }
214
        }
215

216
        return $str;
271✔
217
    }
218
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc