changed git call from https to git readonly
[atutor.git] / mods / social / lib / classes / Application.class.php
1 <?php
2 /****************************************************************/
3 /* ATutor                                                                                                               */
4 /****************************************************************/
5 /* Copyright (c) 2002-2009                                                                              */
6 /* Adaptive Technology Resource Centre / University of Toronto  */
7 /* http://atutor.ca                                                                                             */
8 /*                                                              */
9 /* This program is free software. You can redistribute it and/or*/
10 /* modify it under the terms of the GNU General Public License  */
11 /* as published by the Free Software Foundation.                                */
12 /****************************************************************/
13 // $Id$
14
15 require_once(dirname(__FILE__) . '/Applications.class.php');
16 require_once(dirname(__FILE__) .'/../SecurityToken.php');
17 require_once(dirname(__FILE__) .'/../BlobCrypter.php');
18 require_once(dirname(__FILE__) .'/../Crypto.php');
19 require_once(dirname(__FILE__) .'/../BasicSecurityToken.php');
20 require_once(dirname(__FILE__) .'/../BasicBlobCrypter.php');
21
22 /**
23  * Object for Application, (aka Gadgets)
24  */
25 class Application extends Applications{
26         var $id;        //application id
27         var $url, $title, $height, $screenshot, $thumbnail, $author, $author_email, $description, $settings, $views;
28         var $version;
29
30         //constructor
31         function Application ($id=0){
32                 if ($id!=0){
33                         $this->id = $id;
34                         $this->getApplicationPrefs();   
35                 }
36         }
37
38         /* 
39          * Add application by URL
40          * @param       object          gadget object retrieved from JSON + cURL
41          */
42         function addApplication($gadget_obj){ 
43                 global $db, $addslashes;
44
45                 //TODO: Many more fields to add
46 //              $id                                             = $gadget_obj['moduleId'];   //after i change the URL to the key.
47                 $author                                 = $addslashes($gadget_obj->author);
48                 $author_email                   = $addslashes($gadget_obj->authorEmail);
49                 $description                    = $addslashes($gadget_obj->description);
50                 $screenshot                             = $addslashes($gadget_obj->screenshot);
51                 $thumbnail                              = $addslashes($gadget_obj->thumbnail);
52                 $title                                  = $addslashes($gadget_obj->title);
53                 $height                                 = intval($gadget_obj->height);
54                 $module_id                              = intval($gadget_obj->module_id);
55                 $url                                    = $addslashes($gadget_obj->url);
56                 $userPrefs                              = $addslashes(serialize($gadget_obj->userPrefs));
57                 $views                                  = $addslashes(serialize($gadget_obj->views));
58
59                 //determine next id
60                 $sql = 'SELECT MAX(id) AS max_id FROM '.TABLE_PREFIX.'social_applications';
61                 $result = mysql_query($sql, $db);
62                 if ($result){
63                         $row = mysql_fetch_assoc($result);
64                         $id = $row['max_id'] + 1;
65                 } else {
66                         $id = 1;
67                 }
68                 $member_id = $_SESSION['member_id'];
69
70                 $sql = 'INSERT INTO '.TABLE_PREFIX."social_applications (id, url, title, height, screenshot, thumbnail, author, author_email, description, settings, views, last_updated) VALUES ($id, '$url', '$title', $height, '$screenshot', '$thumbnail', '$author', '$author_email', '$description', '$userPrefs', '$views', NOW())";
71                 $result = mysql_query($sql, $db);
72                 
73                 //This application is already in the database, get its ID out
74                 if (!$result){                  
75                         $sql = 'SELECT id, UNIX_TIMESTAMP(last_updated) AS last_updated FROM '.TABLE_PREFIX."social_applications WHERE url='$url'";
76                         $result = mysql_query($sql, $db);
77                         $row = mysql_fetch_assoc($result);
78                         $id = $row['id'];
79
80                         //Update the gadget
81                         //TODO: Needs some sort of comparing instead of blinding updating everytime. Version(can't find any)? Date(need another field in db?)
82                         //Use TIMESTAMP for now, but i perfer version #.
83                         //If the gadget is SOCIAL_APPLICATION_UPDATE_SCHEDULE days old, update it
84                         if (abs($row['last_updated']) < strtotime('-'.SOCIAL_APPLICATION_UPDATE_SCHEDULE.' day')){
85                                 $sql = 'UPDATE '.TABLE_PREFIX."social_applications SET title='$title', height=$height, screenshot='$screenshot', thumbnail='$thumbnail', author='$author', author_email='$author_email', description='$description', settings='$userPrefs', views='$views', last_updated=NOW() WHERE url='$url'";
86                                 $result = mysql_query($sql, $db);
87                                 //echo $sql;
88                         }
89                 } 
90
91                 //Add a record into application_member table for mapping
92                 $this->addMemberApplication($member_id, $id);
93         }
94
95
96         /**
97          * Add this application to the member's application list
98          * @param       int             member_id
99          * @param       int             application_id
100          */
101         function addMemberApplication($member_id, $app_id){
102                 global $db;
103
104                 $member_id = intval($member_id);
105                 $app_id = intval($app_id);
106
107                 $sql = 'INSERT INTO '.TABLE_PREFIX."social_members_applications (member_id, application_id) VALUES ($member_id, $app_id)";
108                 $result = mysql_query($sql, $db);
109
110                 if ($result){
111                         //Add this to the home page
112                         $home_settings = $this->getHomeDisplaySettings();
113                         $home_settings[$app_id] = 1;    //manually set this application
114                         $this->setHomeDisplaySettings($home_settings);
115
116                         $act = new Activity();          
117                         $act->addActivity($_SESSION['member_id'], '', $app_id);
118                         unset($act);
119                 }
120         }
121
122
123         /**
124          * Parse application details
125          * @return      array of the attributes
126          *
127          */
128         function parseModulePrefs($app_url){
129                 //parse all the attributes of the <ModulePrefs> tag
130                 //and save everything in the object.
131                  $gadget = $this->fetch_gadget_metadata($app_url);
132                  return $gadget->gadgets;
133         }
134
135
136         // Restful - JSON CURL data transfer
137         private function fetch_gadget_metadata($app_url) {
138                 $request = json_encode(array(
139                         'context' => array('country' => 'US', 'language' => 'en', 'view' => 'default', 
140                                 'container' => 'atutor'), 
141                         'gadgets' => array(array('url' => $app_url, 'moduleId' => '1'))));
142                 $ch = curl_init();
143                 curl_setopt($ch, CURLOPT_URL, AT_SHINDIG_URL.'/gadgets/metadata');
144                 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
145                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
146                 curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
147                 curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
148                 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4);
149                 curl_setopt($ch, CURLOPT_TIMEOUT, 20);
150                 curl_setopt($ch, CURLOPT_POST, 1);
151                 curl_setopt($ch, CURLOPT_POSTFIELDS, 'request=' . urlencode($request));
152                 $content = @curl_exec($ch);
153                 return json_decode($content);
154         }
155
156
157         /**
158          * Add application perferences into the table.
159          * @param       int             member id
160          * @param       string  hash's key, usually the name of the application
161          * @param       string  hash's value, contains key, value, and st.
162          * @return      true(1) if the perference has been updated, false(0) otherwise.
163          */
164         function setApplicationSettings($member_id, $key, $value){
165                 global $addslashes, $db;
166
167                 $app_id         = $this->id;
168                 $member_id      = intval($member_id);           
169                 $key            = $addslashes($key);
170                 $value          = $addslashes($value);
171
172                 $sql = 'INSERT INTO '.TABLE_PREFIX."social_application_settings (application_id, member_id, name, value) VALUES ($app_id, $member_id, '$key', '$value') ON DUPLICATE KEY UPDATE value='$value'";
173                 $result = mysql_query($sql, $db);
174
175                 //TODO: Might want to add something here to throw appropriate exceptions
176                 return $result;
177         }
178
179
180         /**
181          * Get member's applications
182          * @param       int             the member id
183          */
184         function getMemberApplications($member_id){
185                 global $db;
186                 $result = array();
187
188                 $member_id = intval($member_id);
189                 $sql = 'SELECT * FROM '.TABLE_PREFIX.'social_members_applications WHERE member_id='.$member_id;
190                 $rs = mysql_query($sql, $db);
191                 if ($rs){
192                         while($row = mysql_fetch_assoc($rs)){
193                                 $result[] = $row['app_id'];
194                         }
195                 }
196                 return $result;
197         }
198
199
200         /**
201          * Get user perferences for this application
202          * @return      array
203          */
204         function getApplicationSettings($member_id){
205                 global $db;
206                 $result = array();
207                 $member_id = intval($member_id);
208
209                 $sql = 'SELECT * FROM '.TABLE_PREFIX."social_application_settings WHERE member_id=$member_id AND application_id=".$this->id;
210                 $rs = mysql_query($sql);
211                 if ($rs){
212                         //loop cause an application can have multiple pairs of key=>value
213                         while ($row = mysql_fetch_assoc($rs)){
214                                 $result[$row['name']] = $row['value'];
215                         }
216                 }
217                 return $result;
218         }
219
220         function getId(){
221                 return $this->id;
222         }
223
224         function getUrl(){
225                 return $this->url;
226         }
227
228         function getTitle(){
229                 return $this->title;
230         }
231
232         function getModuleId(){
233                 return intval($this->module_id);
234         }
235
236         function getHeight(){
237                 if ($this->height==0){
238                         return 600;
239                 }
240                 return $this->height;
241         }
242
243         function getScreenshot(){
244                 return $this->screenshot;
245         }
246
247         function getThumbnail(){
248                 //check if this thumbnail link is a relative link
249                 $url = parse_url($this->thumbnail);
250                 if (!isset($url['scheme']) && !isset($url['host'])){
251                         $orig_url = parse_url($this->getUrl());
252                         return $orig_url['scheme'].'://'.$orig_url['host'].$this->thumbnail;
253                 }
254                 return $this->thumbnail;
255         }
256
257         function getAuthor(){
258                 return $this->author;
259         }
260
261         function getAuthorEmail(){
262                 return $this->author_email;
263         }
264
265         function getDescription(){
266                 return $this->description;
267         }
268
269         function getSettings(){
270                 return unserialize($this->settings);
271         }
272
273         function getViews(){
274                 return unserialize($this->views);
275         }
276
277         /** 
278          * Return iframe URL based on the given parameters
279          * @param       int                     owner id
280          * @param       string          avaiable options are 'profile', 'canvas'
281          *                                              http://code.google.com/apis/orkut/docs/orkutdevguide/orkutdevguide-0.8.html#ops_mode
282          * @param       string          extra application parameters
283          * @return      iframe url
284          */
285         function getIframeUrl($oid, $view='profile', $appParams=''){
286                 //let view=profile as default option
287                 if ($view!='profile' && $view!='canvas'){
288                         $view = 'profile';
289                 }
290
291                 $app_settings = $this->getSettings();
292                 $user_settings = $this->getApplicationSettings($_SESSION['member_id']);
293
294                 //retrieve user preferences
295                 foreach ($app_settings as $key => $setting) {
296                         if (! empty($key)) {
297                           $value = isset($user_settings[$key]) ? $user_settings[$key] : (isset($setting->default) ? $setting->default : null);
298                           if (isset($user_settings[$key])) {
299                                 unset($user_settings[$key]);
300                           }
301                           //shindig doesn't like ';', it only takes '&' as of Apr 6th, 2009
302                           //$prefs .= SEP.'up_' . urlencode($key) . '=' . urlencode($value);
303                           $prefs .= '&up_' . urlencode($key) . '=' . urlencode($value);
304                         }
305                 }
306                 foreach ($user_settings as $name => $value) {
307                         // if some keys _are_ set in the db, but not in the gadget metadata, we still parse them on the url
308                         // (the above loop unsets the entries that matched  
309                         if (! empty($value) && ! isset($appParams[$name])) {
310                         //shindig doesn't like ';', it only takes '&' as of Apr 6th, 2009
311                         //$prefs .= SEP.'up_' . urlencode($name) . '=' . urlencode($value);
312                         $prefs .= '&up_' . urlencode($name) . '=' . urlencode($value);
313                         }
314                 }
315
316                 //generate security token
317                 $securityToken = BasicSecurityToken::createFromValues(($oid > 0?$oid:$_SESSION['member_id']), // owner
318                                                 $_SESSION['member_id'], // viewer
319                                                 $this->getId(), // app id
320                                                 'default', // domain key, shindig will check for php/config/<domain>.php for container specific configuration
321                                                 urlencode($this->getUrl()), // app url
322                                                 $this->getModuleId());// mod id
323 //debug($securityToken);
324                 $url = AT_SHINDIG_URL.'/gadgets/ifr?' 
325                         . "synd=default" 
326                         . "&container=default" 
327                         . "&viewer=". $_SESSION['member_id']
328                         . "&owner=" . $oid
329                         . "&aid=" . $this->getId()                      //application id
330                         . "&mid=" . $this->getModuleId()        //not sure what mod_id is
331                         . "&country=US" 
332                         . "&lang=en" 
333                         . "&view=" . $view      //canvas for this big thing, should be a variable
334                         . "&parent=" . urlencode("http://" . $_SERVER['HTTP_HOST']) . $prefs . (isset($appParams) ? '&view-params=' . urlencode($appParams) : '') 
335                         . "&st=" . urlencode(base64_encode($securityToken->toSerialForm())) 
336                         . "&v=" . $this->getVersion()
337                         . "&url=" . urlencode($this->getUrl()) . "#rpctoken=" . rand(0, getrandmax());
338                 return $url;
339         }
340
341         //TO BE IMPLEMENTED
342         function getVersion(){
343                 return '0.1';
344         }
345
346
347         /**
348          * Retrieve all information about this gadget and save it in the object
349          * @private
350          */
351         function getApplicationPrefs(){
352                 global $db;
353
354                 $sql = 'SELECT * FROM '.TABLE_PREFIX.'social_applications WHERE id='.$this->id;
355                 $rs = mysql_query($sql);
356
357                 if ($rs){
358                         $row = mysql_fetch_assoc($rs);
359                         //assign values
360                         $this->url                      = $row['url'];
361                         $this->title            = $row['title'];
362                         $this->height           = $row['height'];
363                         $this->screenshot       = $row['screenshot'];
364                         $this->thumbnail        = $row['thumbnail'];
365                         $this->author           = $row['author'];
366                         $this->author_email     = $row['author_email'];
367                         $this->description      = $row['description'];
368                         $this->settings         = $row['settings'];
369                         $this->views            = $row['views'];
370                         $this->last_updated     = $row['last_updated'];
371                 }
372         }
373
374         /** 
375          * Delete an application
376          */
377         function deleteApplication(){
378                 global $db;
379
380                 //delete application mapping
381                 $sql = 'DELETE FROM '.TABLE_PREFIX.'social_members_applications WHERE application_id='.$this->id.' AND member_id='.$_SESSION['member_id'];
382                 $rs = mysql_query($sql);
383
384                 //delete application data?
385                 $sql = 'DELETE FROM '.TABLE_PREFIX.'social_application_settings WHERE application_id='.$this->id.' AND member_id='.$_SESSION['member_id'];
386                 $rs = mysql_query($sql);
387
388                 //delete application settings
389                 $home_settings = $this->getHomeDisplaySettings();
390                 if (isset($home_settings[$this->id])){                  
391                         unset($home_settings[$this->id]);
392                         $this->setHomeDisplaySettings($home_settings);
393                 }
394
395                 return $rs;
396         }
397 }
398 ?>