PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/attachmentlist.php

https://github.com/Br3nda/laconica
PHP | 357 lines | 198 code | 43 blank | 116 comment | 22 complexity | a681d1a9f98e21da168adf62324b1ec4 MD5 | raw file
Possible License(s): AGPL-3.0
  1. <?php
  2. /**
  3. * Laconica, the distributed open-source microblogging tool
  4. *
  5. * widget for displaying a list of notice attachments
  6. *
  7. * PHP version 5
  8. *
  9. * LICENCE: This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * @category UI
  23. * @package Laconica
  24. * @author Evan Prodromou <evan@controlyourself.ca>
  25. * @author Sarven Capadisli <csarven@controlyourself.ca>
  26. * @copyright 2008 Control Yourself, Inc.
  27. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  28. * @link http://laconi.ca/
  29. */
  30. if (!defined('LACONICA')) {
  31. exit(1);
  32. }
  33. /**
  34. * widget for displaying a list of notice attachments
  35. *
  36. * There are a number of actions that display a list of notices, in
  37. * reverse chronological order. This widget abstracts out most of the
  38. * code for UI for notice lists. It's overridden to hide some
  39. * data for e.g. the profile page.
  40. *
  41. * @category UI
  42. * @package Laconica
  43. * @author Evan Prodromou <evan@controlyourself.ca>
  44. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  45. * @link http://laconi.ca/
  46. * @see Notice
  47. * @see NoticeListItem
  48. * @see ProfileNoticeList
  49. */
  50. class AttachmentList extends Widget
  51. {
  52. /** the current stream of notices being displayed. */
  53. var $notice = null;
  54. /**
  55. * constructor
  56. *
  57. * @param Notice $notice stream of notices from DB_DataObject
  58. */
  59. function __construct($notice, $out=null)
  60. {
  61. parent::__construct($out);
  62. $this->notice = $notice;
  63. }
  64. /**
  65. * show the list of notices
  66. *
  67. * "Uses up" the stream by looping through it. So, probably can't
  68. * be called twice on the same list.
  69. *
  70. * @return int count of notices listed.
  71. */
  72. function show()
  73. {
  74. $atts = new File;
  75. $att = $atts->getAttachments($this->notice->id);
  76. if (empty($att)) return 0;
  77. $this->out->elementStart('dl', array('id' =>'attachments',
  78. 'class' => 'entry-content'));
  79. $this->out->element('dt', null, _('Attachments'));
  80. $this->out->elementStart('dd');
  81. $this->out->elementStart('ol', array('class' => 'attachments'));
  82. foreach ($att as $n=>$attachment) {
  83. $item = $this->newListItem($attachment);
  84. $item->show();
  85. }
  86. $this->out->elementEnd('dd');
  87. $this->out->elementEnd('ol');
  88. $this->out->elementEnd('dl');
  89. return count($att);
  90. }
  91. /**
  92. * returns a new list item for the current notice
  93. *
  94. * Recipe (factory?) method; overridden by sub-classes to give
  95. * a different list item class.
  96. *
  97. * @param Notice $notice the current notice
  98. *
  99. * @return NoticeListItem a list item for displaying the notice
  100. */
  101. function newListItem($attachment)
  102. {
  103. return new AttachmentListItem($attachment, $this->out);
  104. }
  105. }
  106. /**
  107. * widget for displaying a single notice
  108. *
  109. * This widget has the core smarts for showing a single notice: what to display,
  110. * where, and under which circumstances. Its key method is show(); this is a recipe
  111. * that calls all the other show*() methods to build up a single notice. The
  112. * ProfileNoticeListItem subclass, for example, overrides showAuthor() to skip
  113. * author info (since that's implicit by the data in the page).
  114. *
  115. * @category UI
  116. * @package Laconica
  117. * @author Evan Prodromou <evan@controlyourself.ca>
  118. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  119. * @link http://laconi.ca/
  120. * @see NoticeList
  121. * @see ProfileNoticeListItem
  122. */
  123. class AttachmentListItem extends Widget
  124. {
  125. /** The attachment this item will show. */
  126. var $attachment = null;
  127. var $oembed = null;
  128. /**
  129. * constructor
  130. *
  131. * Also initializes the profile attribute.
  132. *
  133. * @param Notice $notice The notice we'll display
  134. */
  135. function __construct($attachment, $out=null)
  136. {
  137. parent::__construct($out);
  138. $this->attachment = $attachment;
  139. $this->oembed = File_oembed::staticGet('file_id', $this->attachment->id);
  140. }
  141. function title() {
  142. if (empty($this->attachment->title)) {
  143. if (empty($this->oembed->title)) {
  144. $title = $this->attachment->url;
  145. } else {
  146. $title = $this->oembed->title;
  147. }
  148. } else {
  149. $title = $this->attachment->title;
  150. }
  151. return $title;
  152. }
  153. function linkTitle() {
  154. return $this->title();
  155. }
  156. /**
  157. * recipe function for displaying a single notice.
  158. *
  159. * This uses all the other methods to correctly display a notice. Override
  160. * it or one of the others to fine-tune the output.
  161. *
  162. * @return void
  163. */
  164. function show()
  165. {
  166. $this->showStart();
  167. $this->showNoticeAttachment();
  168. $this->showEnd();
  169. }
  170. function linkAttr() {
  171. return array('class' => 'attachment', 'href' => $this->attachment->url, 'id' => 'attachment-' . $this->attachment->id);
  172. }
  173. function showLink() {
  174. $this->out->elementStart('a', $this->linkAttr());
  175. $this->out->element('span', null, $this->linkTitle());
  176. $this->showRepresentation();
  177. $this->out->elementEnd('a');
  178. }
  179. function showNoticeAttachment()
  180. {
  181. $this->showLink();
  182. }
  183. function showRepresentation() {
  184. $thumbnail = File_thumbnail::staticGet('file_id', $this->attachment->id);
  185. if (!empty($thumbnail)) {
  186. $this->out->element('img', array('alt' => '', 'src' => $thumbnail->url, 'width' => $thumbnail->width, 'height' => $thumbnail->height));
  187. }
  188. }
  189. /**
  190. * start a single notice.
  191. *
  192. * @return void
  193. */
  194. function showStart()
  195. {
  196. // XXX: RDFa
  197. // TODO: add notice_type class e.g., notice_video, notice_image
  198. $this->out->elementStart('li');
  199. }
  200. /**
  201. * finish the notice
  202. *
  203. * Close the last elements in the notice list item
  204. *
  205. * @return void
  206. */
  207. function showEnd()
  208. {
  209. $this->out->elementEnd('li');
  210. }
  211. }
  212. class Attachment extends AttachmentListItem
  213. {
  214. function showLink() {
  215. $this->out->elementStart('div', array('id' => 'attachment_view',
  216. 'class' => 'hentry'));
  217. $this->out->elementStart('div', 'entry-title');
  218. $this->out->elementStart('a', $this->linkAttr());
  219. $this->out->element('span', null, $this->linkTitle());
  220. $this->out->elementEnd('a');
  221. $this->out->elementEnd('div');
  222. $this->out->elementStart('div', 'entry-content');
  223. $this->showRepresentation();
  224. $this->out->elementEnd('div');
  225. if (!empty($this->oembed->author_name) || !empty($this->oembed->provider)) {
  226. $this->out->elementStart('div', array('id' => 'oembed_info',
  227. 'class' => 'entry-content'));
  228. if (!empty($this->oembed->author_name)) {
  229. $this->out->elementStart('dl', 'vcard author');
  230. $this->out->element('dt', null, _('Author'));
  231. $this->out->elementStart('dd', 'fn');
  232. if (empty($this->oembed->author_url)) {
  233. $this->out->text($this->oembed->author_name);
  234. } else {
  235. $this->out->element('a', array('href' => $this->oembed->author_url,
  236. 'class' => 'url'), $this->oembed->author_name);
  237. }
  238. $this->out->elementEnd('dd');
  239. $this->out->elementEnd('dl');
  240. }
  241. if (!empty($this->oembed->provider)) {
  242. $this->out->elementStart('dl', 'vcard');
  243. $this->out->element('dt', null, _('Provider'));
  244. $this->out->elementStart('dd', 'fn');
  245. if (empty($this->oembed->provider_url)) {
  246. $this->out->text($this->oembed->provider);
  247. } else {
  248. $this->out->element('a', array('href' => $this->oembed->provider_url,
  249. 'class' => 'url'), $this->oembed->provider);
  250. }
  251. $this->out->elementEnd('dd');
  252. $this->out->elementEnd('dl');
  253. }
  254. $this->out->elementEnd('div');
  255. }
  256. $this->out->elementEnd('div');
  257. }
  258. function show() {
  259. $this->showNoticeAttachment();
  260. }
  261. function linkAttr() {
  262. return array('class' => 'external', 'href' => $this->attachment->url);
  263. }
  264. function linkTitle() {
  265. return $this->attachment->url;
  266. }
  267. function showRepresentation() {
  268. if (empty($this->oembed->type)) {
  269. if (empty($this->attachment->mimetype)) {
  270. $this->out->element('pre', null, 'oh well... not sure how to handle the following: ' . print_r($this->attachment, true));
  271. } else {
  272. switch ($this->attachment->mimetype) {
  273. case 'image/gif':
  274. case 'image/png':
  275. case 'image/jpg':
  276. case 'image/jpeg':
  277. $this->out->element('img', array('src' => $this->attachment->url, 'alt' => 'alt'));
  278. break;
  279. case 'application/ogg':
  280. case 'audio/x-speex':
  281. case 'video/mpeg':
  282. case 'audio/mpeg':
  283. case 'video/mp4':
  284. case 'video/quicktime':
  285. $arr = array('type' => $this->attachment->mimetype,
  286. 'data' => $this->attachment->url,
  287. 'width' => 320,
  288. 'height' => 240
  289. );
  290. $this->out->elementStart('object', $arr);
  291. $this->out->element('param', array('name' => 'src', 'value' => $this->attachment->url));
  292. $this->out->element('param', array('name' => 'autoStart', 'value' => 1));
  293. $this->out->elementEnd('object');
  294. break;
  295. }
  296. }
  297. } else {
  298. switch ($this->oembed->type) {
  299. case 'rich':
  300. case 'video':
  301. case 'link':
  302. if (!empty($this->oembed->html)) {
  303. $this->out->raw($this->oembed->html);
  304. }
  305. break;
  306. case 'photo':
  307. $this->out->element('img', array('src' => $this->oembed->url, 'width' => $this->oembed->width, 'height' => $this->oembed->height, 'alt' => 'alt'));
  308. break;
  309. default:
  310. $this->out->element('pre', null, 'oh well... not sure how to handle the following oembed: ' . print_r($this->oembed, true));
  311. }
  312. }
  313. }
  314. }