5 * Database table containing information about Pubsubhubbub subscriptions
11 public function __construct()
14 $GLOBALS['phinde']['db_dsn'],
15 $GLOBALS['phinde']['db_user'],
16 $GLOBALS['phinde']['db_pass']
18 $this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
24 * @param string $topic Topic URL
26 * @return false|object False if the row does not exist
28 public function get($topic)
30 $stmt = $this->db->prepare(
31 'SELECT * FROM subscriptions'
32 . ' WHERE sub_topic = :topic'
34 $stmt->execute([':topic' => $topic]);
36 //fetchObject() itself returns FALSE on failure
37 return $stmt->fetchObject();
43 * @param string $topic Topic URL
47 public function remove($topic)
49 $stmt = $this->db->prepare(
50 'DELETE FROM subscriptions'
51 . ' WHERE sub_topic = :topic'
53 $stmt->execute([':topic' => $topic]);
57 * Count number of subscriptions
59 * @return array Array of keys with different status, number as value
61 public function count()
63 $stmt = $this->db->prepare(
64 'SELECT COUNT(*) as count, sub_status FROM subscriptions'
65 . ' GROUP BY sub_status'
66 . ' ORDER BY sub_status'
71 foreach ($stmt as $row) {
72 $res[$row['sub_status']] = $row['count'];
79 * Get all topics that either expired or expire soon
81 * @return \PDOStatement Result iterator
83 public function getExpiring()
85 $stmt = $this->db->prepare(
86 'SELECT * FROM subscriptions'
90 . ' sub_status IN ("active", "expired")'
91 . ' AND DATEDIFF(sub_expires, NOW()) <= 2'
93 //no reaction to subscription within 10 minutes
94 . ' sub_status = "subscribing"'
95 . ' AND TIMEDIFF(NOW(), sub_created) > "00:10:00"'
104 * Create a new subscription entry in database.
105 * Automatically generates secret, capkey and lease seconds.
107 * This method does NOT:
108 * - check for duplicates (do it yourself)
109 * - return the object (fetch it yourself)
110 * - send subscription requests to the hub
112 * @param string $topic URL to subscribe to
113 * @param string $hub URL of the hub subscribing to
117 public function create($topic, $hub)
119 $stmt = $this->db->prepare(
120 'INSERT INTO subscriptions'
121 . ' (sub_topic, sub_status, sub_lease_seconds, sub_expires'
122 . ', sub_secret, sub_capkey, sub_hub, sub_created, sub_updated'
123 . ', sub_pings, sub_lastping, sub_statusmessage)'
125 . ' (:topic, "subscribing", :lease_seconds, "0000-00-00 00:00:00"'
126 . ', :secret, :capkey, :hub, NOW(), NOW()'
127 . ', 0, "0000-00-00 00:00:00", "")'
132 ':lease_seconds' => 86400 * 30,
133 ':secret' => bin2hex(openssl_random_pseudo_bytes(16)),
134 ':capkey' => bin2hex(openssl_random_pseudo_bytes(16)),
141 * Renew a subscription: Set its status to "subscribing"
143 * @param integer $subId Subscription ID
147 public function renew($subId)
150 'UPDATE subscriptions'
151 . ' SET sub_status = "subscribing"'
152 . ' , sub_updated = NOW()'
153 . ' WHERE sub_id = :id'
154 )->execute([':id' => $subId]);
158 * A subscription has been confirmed by the hub - mark it as active.
160 * @param integer $subId Subscription ID
161 * @param integer $leaseSeconds Number of seconds until subscription expires
165 public function subscribed($subId, $leaseSeconds)
168 'UPDATE subscriptions'
169 . ' SET sub_status = "active"'
170 . ' , sub_lease_seconds = :leaseSeconds'
171 . ' , sub_expires = :expires'
172 . ' , sub_updated = NOW()'
173 . ' WHERE sub_id = :id'
176 ':leaseSeconds' => $leaseSeconds,
177 ':expires' => gmdate('Y-m-d H:i:s', time() + $leaseSeconds),
184 * Mark a subscription as "unsubscribed"
186 * @param integer $subId Subscription ID
190 public function unsubscribed($subId)
193 'UPDATE subscriptions'
194 . ' SET sub_status = "unsubscribed"'
195 . ' , sub_updated = NOW()'
196 . ' WHERE sub_id = :id'
197 )->execute([':id' => $subId]);
201 * Subscription has been cancelled/denied for some reason
203 * @param integer $subId Subscription ID
204 * @param string $reason Cancellation reason
208 public function denied($subId, $reason)
211 'UPDATE subscriptions'
212 . ' SET sub_status = "denied"'
213 . ' , sub_statusmessage = :reason'
214 . ' , sub_updated = NOW()'
215 . ' WHERE sub_id = :id'
216 )->execute([':id' => $subId, ':reason' => $reason]);
220 * Topic update notification has been received
222 * @param integer $subId Subscription ID
226 public function pinged($subId)
229 'UPDATE subscriptions'
230 . ' SET sub_pings = sub_pings + 1'
231 . ' , sub_lastping = NOW()'
232 . ' , sub_updated = NOW()'
233 . ' WHERE sub_id = :id'
234 )->execute([':id' => $subId]);
238 * Detect the hub for the given topic URL
240 * @param string $url Topic URL
242 * @return array Topic URL and hub URL. Hub URL is NULL if there is none.
244 public function detectHub($url)
246 $hue = new HubUrlExtractor();
247 $hue->setRequestTemplate(new HttpRequest());
248 $urls = $hue->getUrls($url);
249 //we violate the spec by not requiring a self URL
250 $topicUrl = isset($urls['self']) ? $urls['self'] : $url;
251 $hubUrl = isset($urls['hub']) ? $urls['hub'] : null;
253 return array($topicUrl, $hubUrl);