Show more links work with AJAX-retrieved HTML
[statusnet:gnu-social.git] / plugins / Oembed / OembedPlugin.php
1 <?php
2
3 class OembedPlugin extends Plugin
4 {
5     public function onCheckSchema()
6     {
7         $schema = Schema::get();
8         $schema->ensureTable('file_oembed', File_oembed::schemaDef());
9         return true;
10     }
11
12     public function onRouterInitialized(URLMapper $m)
13     {
14         $m->connect('main/oembed', array('action' => 'oembed'));
15     }
16
17     public function onEndShowHeadElements(Action $action)
18     {
19         switch ($action->getActionName()) {
20         case 'attachment':
21             $action->element('link',array('rel'=>'alternate',
22                 'type'=>'application/json+oembed',
23                 'href'=>common_local_url(
24                     'oembed',
25                     array(),
26                     array('format'=>'json', 'url'=>
27                         common_local_url('attachment',
28                             array('attachment' => $action->attachment->id)))),
29                 'title'=>'oEmbed'),null);
30             $action->element('link',array('rel'=>'alternate',
31                 'type'=>'text/xml+oembed',
32                 'href'=>common_local_url(
33                     'oembed',
34                     array(),
35                     array('format'=>'xml','url'=>
36                         common_local_url('attachment',
37                             array('attachment' => $action->attachment->id)))),
38                 'title'=>'oEmbed'),null);
39             break;
40         case 'shownotice':
41             try {
42                 $action->element('link',array('rel'=>'alternate',
43                     'type'=>'application/json+oembed',
44                     'href'=>common_local_url(
45                         'oembed',
46                         array(),
47                         array('format'=>'json','url'=>$action->notice->getUrl())),
48                     'title'=>'oEmbed'),null);
49                 $action->element('link',array('rel'=>'alternate',
50                     'type'=>'text/xml+oembed',
51                     'href'=>common_local_url(
52                         'oembed',
53                         array(),
54                         array('format'=>'xml','url'=>$action->notice->getUrl())),
55                     'title'=>'oEmbed'),null);
56             } catch (InvalidUrlException $e) {
57                 // The notice is probably a share or similar, which don't
58                 // have a representational URL of their own.
59             }
60             break;
61         }
62
63         return true;
64     }
65
66     /**
67      * Save embedding information for a File, if applicable.
68      *
69      * Normally this event is called through File::saveNew()
70      *
71      * @param File   $file       The newly inserted File object.
72      * @param array  $redir_data lookup data eg from File_redirection::where()
73      * @param string $given_url
74      *
75      * @return boolean success
76      */
77     public function onEndFileSaveNew(File $file, array $redir_data, $given_url)
78     {
79         $fo = File_oembed::getKV('file_id', $file->id);
80         if ($fo instanceof File_oembed) {
81             common_log(LOG_WARNING, "Strangely, a File_oembed object exists for new file $file_id", __FILE__);
82              return true;
83         }
84
85         if (isset($redir_data['oembed']['json'])
86                 && !empty($redir_data['oembed']['json'])) {
87             File_oembed::saveNew($redir_data['oembed']['json'], $file->id);
88         } elseif (isset($redir_data['type'])
89                 && (('text/html' === substr($redir_data['type'], 0, 9)
90                 || 'application/xhtml+xml' === substr($redir_data['type'], 0, 21)))) {
91
92             try {
93                 $oembed_data = File_oembed::_getOembed($given_url);
94                 if ($oembed_data === false) {
95                     throw new Exception('Did not get oEmbed data from URL');
96                 }
97             } catch (Exception $e) {
98                 return true;
99             }
100
101             File_oembed::saveNew($oembed_data, $file->id);
102         }
103         return true;
104     }
105
106     public function onEndShowAttachmentLink(HTMLOutputter $out, File $file)
107     {
108         $oembed = File_oembed::getKV('file_id', $file->id);
109         if (empty($oembed->author_name) && empty($oembed->provider)) {
110             return true;
111         }
112         $out->elementStart('div', array('id'=>'oembed_info', 'class'=>'entry-content'));
113         if (!empty($oembed->author_name)) {
114             $out->elementStart('div', 'fn vcard author');
115             if (empty($oembed->author_url)) {
116                 $out->text($oembed->author_name);
117             } else {
118                 $out->element('a', array('href' => $oembed->author_url,
119                                          'class' => 'url'),
120                                 $oembed->author_name);
121             }
122         }
123         if (!empty($oembed->provider)) {
124             $out->elementStart('div', 'fn vcard');
125             if (empty($oembed->provider_url)) {
126                 $out->text($oembed->provider);
127             } else {
128                 $out->element('a', array('href' => $oembed->provider_url,
129                                          'class' => 'url'),
130                                 $oembed->provider);
131             }
132         }
133         $out->elementEnd('div');
134     }
135
136     public function onFileEnclosureMetadata(File $file, &$enclosure)
137     {
138         // Never treat generic HTML links as an enclosure type!
139         // But if we have oEmbed info, we'll consider it golden.
140         $oembed = File_oembed::getKV('file_id', $file->id);
141         if (!$oembed instanceof File_oembed || !in_array($oembed->type, array('photo', 'video'))) {
142             return true;
143         }
144
145         foreach (array('mimetype', 'url', 'title', 'modified') as $key) {
146             if (!empty($oembed->{$key})) {
147                 $enclosure->{$key} = $oembed->{$key};
148             }
149         }
150         return true;
151     }
152     
153     public function onStartShowAttachmentRepresentation(HTMLOutputter $out, File $file)
154     {
155         $oembed = File_oembed::getKV('file_id', $file->id);
156         if (empty($oembed->type)) {
157             return true;
158         }
159         switch ($oembed->type) {
160         case 'rich':
161         case 'video':
162         case 'link':
163             if (!empty($oembed->html)
164                     && (StatusNet::isAjax() || common_config('attachments', 'show_html'))) {
165                 require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
166                 $config = array(
167                     'safe'=>1,
168                     'elements'=>'*+object+embed');
169                 $out->raw(htmLawed($oembed->html,$config));
170             }
171             break;
172
173         case 'photo':
174             $out->element('img', array('src' => $oembed->url, 'width' => $oembed->width, 'height' => $oembed->height, 'alt' => 'alt'));
175             break;
176
177         default:
178             Event::handle('ShowUnsupportedAttachmentRepresentation', array($out, $file));
179         }
180     }
181
182     public function onPluginVersion(array &$versions)
183     {
184         $versions[] = array('name' => 'Oembed',
185                             'version' => GNUSOCIAL_VERSION,
186                             'author' => 'Mikael Nordfeldth',
187                             'homepage' => 'http://gnu.io/',
188                             'description' =>
189                             // TRANS: Plugin description.
190                             _m('Plugin for using and representing Oembed data.'));
191         return true;
192     }
193 }