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

/system/plugins/flickrsilo/flickrsilo.plugin.php

https://github.com/HabariMag/habarimag-old
PHP | 993 lines | 770 code | 103 blank | 120 comment | 62 complexity | 3bca9c695fd61b63281723963e691ddf MD5 | raw file
Possible License(s): Apache-2.0
  1. <?php
  2. class flickrAPI
  3. {
  4. function __construct()
  5. {
  6. $this->key = 'cd0ae46b1332aa2bd52ba3063f0db41c';
  7. $this->secret = '76cf747f70be9029';
  8. $this->endpoint = 'http://www.flickr.com/services/rest/?';
  9. $this->authendpoint = 'http://www.flickr.com/services/auth/?';
  10. $this->uploadendpoint = 'http://api.flickr.com/services/upload/?';
  11. $this->conntimeout = 20;
  12. }
  13. public function sign( $args )
  14. {
  15. ksort( $args );
  16. unset( $args['photo'] );
  17. $a = '';
  18. foreach( $args as $key => $value ){
  19. $a .= $key . $value;
  20. }
  21. return md5( $this->secret . $a );
  22. }
  23. public function encode( $args )
  24. {
  25. $encoded = array();
  26. foreach ( $args as $key => $value ){
  27. $encoded[] = urlencode( $key ) . '=' . urlencode( $value );
  28. }
  29. return $encoded;
  30. }
  31. function call( $method, $args = array () )
  32. {
  33. $args = array_merge( array ( 'method' => $method,
  34. 'api_key' => $this->key ), $args );
  35. ksort( $args );
  36. $args = array_merge( $args, array ( 'api_sig' => $this->sign( $args ) ) );
  37. ksort( $args );
  38. if ( $method == 'upload' ){
  39. $req = curl_init();
  40. $args['api_key'] = $this->key;
  41. $photo = $args['photo'];
  42. $args['photo'] = '@' . $photo;
  43. curl_setopt( $req, CURLOPT_URL, $this->uploadendpoint );
  44. curl_setopt( $req, CURLOPT_TIMEOUT, 0 );
  45. // curl_setopt($req, CURLOPT_INFILESIZE, filesize($photo));
  46. // Sign and build request parameters
  47. curl_setopt( $req, CURLOPT_POSTFIELDS, $args );
  48. curl_setopt( $req, CURLOPT_CONNECTTIMEOUT, $this->conntimeout );
  49. curl_setopt( $req, CURLOPT_FOLLOWLOCATION, 1 );
  50. curl_setopt( $req, CURLOPT_HEADER, 0 );
  51. curl_setopt( $req, CURLOPT_RETURNTRANSFER, 1 );
  52. $this->_http_body = curl_exec( $req );
  53. if ( curl_errno( $req ) ){
  54. throw new Exception( curl_error( $req ) );
  55. }
  56. curl_close( $req );
  57. $xml = simplexml_load_string( $this->_http_body );
  58. $this->xml = $xml;
  59. return $xml;
  60. }
  61. else{
  62. $url = $this->endpoint . implode( '&', $this->encode( $args ) );
  63. $call = new RemoteRequest( $url );
  64. $call->set_timeout( 5 );
  65. try {
  66. $result = $call->execute();
  67. }
  68. catch ( RemoteRequest_Timeout $t ) {
  69. Session::error( 'Currently unable to connect to Flickr.', 'flickr API' );
  70. return false;
  71. }
  72. catch ( Exception $e ) {
  73. // at the moment we're using the same error message, though this is more catastrophic
  74. Session::error( 'Currently unable to connect to Flickr.', 'flickr API' );
  75. return false;
  76. }
  77. $response = $call->get_response_body();
  78. try{
  79. $xml = new SimpleXMLElement( $response );
  80. return $xml;
  81. }
  82. catch( Exception $e ) {
  83. Session::error( 'Unable to process Flickr response.', 'flickr API' );
  84. return false;
  85. }
  86. }
  87. }
  88. }
  89. class Flickr extends flickrAPI
  90. {
  91. function __construct( $params = array() )
  92. {
  93. parent::__construct( $params );
  94. }
  95. // URL building
  96. function getPhotoURL( $p, $size = 'm', $ext = 'jpg' )
  97. {
  98. return "http://static.flickr.com/{$p['server']}/{$p['id']}_{$p['secret']}_{$size}.{$ext}";
  99. }
  100. // authentication and approval
  101. public function getFrob()
  102. {
  103. $xml = $this->call( 'flickr.auth.getFrob', array() );
  104. return $xml->frob;
  105. }
  106. public function authLink( $frob )
  107. {
  108. $params['api_key'] = $this->key;
  109. $params['frob'] = $frob;
  110. $params['perms'] = 'write';
  111. $params['api_sig'] = md5( $this->secret . 'api_key' . $params['api_key'] . 'frob' . $params['frob'] . 'permswrite' );
  112. $link = $this->authendpoint . implode( '&', $this->encode( $params ) );
  113. return $link;
  114. }
  115. function getToken( $frob )
  116. {
  117. $xml = $this->call( 'flickr.auth.getToken', array( 'frob' => $frob ) );
  118. return $xml;
  119. }
  120. // grab the token from our db.
  121. function cachedToken()
  122. {
  123. $token = Options::get( 'flickr_token_' . User::identify()->id );
  124. return $token;
  125. }
  126. // get publicly available photos
  127. function getPublicPhotos( $nsid, $extras = '', $per_page = '', $page = '' )
  128. {
  129. $params = array( 'user_id' => $nsid );
  130. if ( $extras ){
  131. $params['extras'] = $extras;
  132. }
  133. if ( $per_page ){
  134. $params['per_page'] = $per_page;
  135. }
  136. if ( $page ){
  137. $params['page'] = $page;
  138. }
  139. $xml = $this->call( 'flickr.people.getPublicPhotos' , $params );
  140. foreach( $xml->photos->attributes() as $key => $value ){
  141. $pic[$key] = (string)$value;
  142. }
  143. $i = 0;
  144. foreach( $xml->photos->photo as $photo ){
  145. foreach( $photo->attributes() as $key => $value ){
  146. $pic['photos'][(string)$photo['id']][$key] = (string)$value;
  147. }
  148. $i++;
  149. }
  150. return $pic;
  151. }
  152. // Photosets methods
  153. function photosetsGetList( $nsid = '' )
  154. {
  155. $params = array();
  156. if ( $nsid ){
  157. $params['user_id'] = $nsid;
  158. }
  159. $xml = $this->call( 'flickr.photosets.getList', $params );
  160. if ( Error::is_error( $xml ) ){
  161. throw $xml;
  162. }
  163. return $xml;
  164. }
  165. function photosetsGetInfo( $photoset_id )
  166. {
  167. $params = array( 'photoset_id' => $photoset_id );
  168. $xml = $this->call( 'flickr.photosets.getInfo', $params );
  169. if ( Error::is_error( $xml ) ){
  170. throw $xml;
  171. }
  172. return $xml;
  173. }
  174. function photosetGetPrimary( $p, $size = 'm', $ext = '.jpg' )
  175. {
  176. return 'http://static.flickr.com/' . $p['server'] . '/' . $p['primary'] . '_' . $p['secret'] . '_' . $size . $ext;
  177. }
  178. function photosetsGetPhotos( $photoset_id )
  179. {
  180. $params = array( 'photoset_id' => $photoset_id );
  181. $xml = $this->call( 'flickr.photosets.getPhotos', $params );
  182. if ( Error::is_error( $xml ) ){
  183. throw $xml;
  184. }
  185. return $xml;
  186. }
  187. function photosRecentlyUpdated()
  188. {
  189. $params = array();
  190. if ( $this->cachedToken() ){
  191. $params['auth_token'] = $this->cachedToken();
  192. }
  193. $params['secret'] = $this->secret;
  194. $params['min_date'] = time() - 31536000; // Within the last year
  195. $params['per_page'] = 10;
  196. $xml = $this->call( 'flickr.photos.recentlyUpdated', $params );
  197. if ( Error::is_error( $xml ) ){
  198. throw $xml;
  199. }
  200. return $xml;
  201. }
  202. function mediaSearch( $params = array() )
  203. {
  204. if ( $this->cachedToken() ){
  205. $params['auth_token'] = $this->cachedToken();
  206. }
  207. $params['secret'] = $this->secret;
  208. $params['user_id'] = 'me';
  209. $params['sort'] = 'date-posted-desc';
  210. $params['per_page'] = 20;
  211. $xml = $this->call( 'flickr.photos.search', $params );
  212. if ( Error::is_error( $xml ) ){
  213. throw $xml;
  214. }
  215. return $xml;
  216. }
  217. function photosSearch( $params = array() )
  218. {
  219. if ( $this->cachedToken() ){
  220. $params['auth_token'] = $this->cachedToken();
  221. }
  222. $defaults = array(
  223. 'secret' => $this->secret,
  224. 'user_id' => 'me',
  225. 'sort' => 'date-posted-desc',
  226. 'per_page' => 20,
  227. 'media' => 'photos',
  228. 'extras' => 'original_format',
  229. );
  230. $params = array_merge( $defaults, $params );
  231. $xml = $this->call( 'flickr.photos.search', $params );
  232. if ( Error::is_error( $xml ) ){
  233. throw $xml;
  234. }
  235. return $xml;
  236. }
  237. function videoSearch( $params = array() )
  238. {
  239. if ( $this->cachedToken() ){
  240. $params['auth_token'] = $this->cachedToken();
  241. }
  242. $params['secret'] = $this->secret;
  243. $params['user_id'] = 'me';
  244. $params['sort'] = 'date-posted-desc';
  245. $params['per_page'] = 20;
  246. $params['media'] = 'videos';
  247. $xml = $this->call( 'flickr.photos.search', $params );
  248. if ( Error::is_error( $xml ) ){
  249. throw $xml;
  250. }
  251. return $xml;
  252. }
  253. function tagsGetListUser( $userid = null )
  254. {
  255. $params = array();
  256. if ( isset( $userid ) ) {
  257. $params['user_id'] = $userid;
  258. }
  259. $xml = $this->call( 'flickr.tags.getListUser', $params );
  260. return $xml;
  261. }
  262. function photosGetInfo( $photo_id )
  263. {
  264. $params = array();
  265. if ( $this->cachedToken() ){
  266. $params['auth_token'] = $this->cachedToken();
  267. }
  268. $params['photo_id'] = $photo_id;
  269. $params['secret'] = $this->secret;
  270. $xml = $this->call( 'flickr.photos.getInfo', $params );
  271. if ( Error::is_error( $xml ) ){
  272. throw $xml;
  273. }
  274. return $xml;
  275. }
  276. function upload( $photo, $title = '', $description = '', $tags = '', $perms = '', $async = 1, &$info = null )
  277. {
  278. $store = HABARI_PATH . '/' . Site::get_path( 'user' ) . '/cache';
  279. if ( !is_dir( $store ) ){
  280. mkdir( $store, 0777 );
  281. }
  282. $params = array( 'auth_token' => $this->cachedToken() );
  283. $url = InputFilter::parse_url( 'file://' . $photo );
  284. if ( isset( $url['scheme'] ) ){
  285. $localphoto = fopen( HABARI_PATH . '/' . $photo, 'r' );
  286. $store = tempnam( $store, 'G2F' );
  287. file_put_contents( $store, $localphoto );
  288. fclose( $localphoto );
  289. $params['photo'] = $store;
  290. }
  291. else{
  292. $params['photo'] = $photo;
  293. }
  294. $info = filesize( $params['photo'] );
  295. if ( $title ){
  296. $params['title'] = $title;
  297. }
  298. if ( $description ){
  299. $params['description'] = $description;
  300. }
  301. if ( $tags ){
  302. $params['tags'] = $tags;
  303. }
  304. if ( $perms ){
  305. if ( isset( $perms['is_public'] ) ){
  306. $params['is_public'] = $perms['is_public'];
  307. }
  308. if ( isset( $perms['is_friend'] ) ){
  309. $params['is_friend'] = $perms['is_friend'];
  310. }
  311. if ( isset( $perms['is_family'] ) ){
  312. $params['is_family'] = $perms['is_family'];
  313. }
  314. }
  315. if ( $async ){
  316. $params['async'] = $async;
  317. }
  318. // call the upload method.
  319. $xml = $this->call( 'upload', $params );
  320. if ( $store ){
  321. unlink( $store );
  322. }
  323. if ( Error::is_error( $xml ) ){
  324. throw $xml;
  325. }
  326. if ( $async ){
  327. return( (string)$xml->ticketid );
  328. }
  329. else{
  330. return( (string)$xml->photoid );
  331. }
  332. }
  333. function photosUploadCheckTickets( $tickets )
  334. {
  335. if ( is_array( $tickets ) ){
  336. foreach( $tickets as $key => $value ){
  337. if ( $key ){
  338. $params['tickets'] .= ' ';
  339. }
  340. $params['tickets'] .= $value;
  341. }
  342. }
  343. else{
  344. $params['tickets'] = $tickets;
  345. }
  346. $xml = $this->call( 'flickr.photos.upload.checkTickets', $params );
  347. if ( Error::is_error( $xml ) ){
  348. throw $xml;
  349. }
  350. foreach( $xml->uploader->ticket as $ticket ){
  351. foreach( $ticket->attributes() as $key => $value ){
  352. $uptick[(string)$ticket['id']][$key] = (string)$value;
  353. }
  354. }
  355. return $uptick;
  356. }
  357. function reflectionGetMethods()
  358. {
  359. $params = array();
  360. $xml = $this->call( 'flickr.reflection.getMethods', $params );
  361. if ( !$xml ){
  362. return false;
  363. }
  364. $ret = (array)$xml->methods->method;
  365. return $ret;
  366. }
  367. }
  368. /**
  369. * Flickr Silo
  370. */
  371. class FlickrSilo extends Plugin implements MediaSilo
  372. {
  373. const SILO_NAME = 'Flickr';
  374. static $cache = array();
  375. /**
  376. * Initialize some internal values when plugin initializes
  377. */
  378. public function action_init()
  379. {
  380. }
  381. /**
  382. * Return basic information about this silo
  383. * name- The name of the silo, used as the root directory for media in this silo
  384. * icon- An icon to represent the silo
  385. */
  386. public function silo_info()
  387. {
  388. if ( $this->is_auth() ) {
  389. return array( 'name' => self::SILO_NAME, 'icon' => URL::get_from_filesystem(__FILE__) . '/icon.png' );
  390. }
  391. else {
  392. return array();
  393. }
  394. }
  395. /**
  396. * Return directory contents for the silo path
  397. *
  398. * @param string $path The path to retrieve the contents of
  399. * @return array An array of MediaAssets describing the contents of the directory
  400. */
  401. public function silo_dir( $path )
  402. {
  403. $flickr = new Flickr();
  404. $results = array();
  405. $size = Options::get( 'flickrsilo__flickr_size' );
  406. $section = strtok( $path, '/' );
  407. switch ( $section ) {
  408. case 'attrib-sa':
  409. $xml = $flickr->photosSearch( array( 'user_id' => '', 'license' => '4,5', 'text'=>$_SESSION['flickrsearch'] ) );
  410. foreach( $xml->photos->photo as $photo ) {
  411. $props = array();
  412. foreach( $photo->attributes() as $name => $value ) {
  413. $props[$name] = (string)$value;
  414. }
  415. $props = array_merge( $props, self::element_props( $photo, "http://www.flickr.com/photos/{$photo['owner']}/{$photo['id']}", $size ) );
  416. $results[] = new MediaAsset(
  417. self::SILO_NAME . '/photos/' . $photo['id'],
  418. false,
  419. $props
  420. );
  421. }
  422. break;
  423. case 'search':
  424. $xml = $flickr->photosSearch( array( 'text'=>$_SESSION['flickrsearch'] ) );
  425. foreach( $xml->photos->photo as $photo ) {
  426. $props = array();
  427. foreach( $photo->attributes() as $name => $value ) {
  428. $props[$name] = (string)$value;
  429. }
  430. $props = array_merge( $props, self::element_props( $photo, "http://www.flickr.com/photos/{$_SESSION['nsid']}/{$photo['id']}", $size ) );
  431. $results[] = new MediaAsset(
  432. self::SILO_NAME . '/photos/' . $photo['id'],
  433. false,
  434. $props
  435. );
  436. }
  437. break;
  438. case 'photos':
  439. $xml = $flickr->photosSearch();
  440. foreach( $xml->photos->photo as $photo ) {
  441. $props = array();
  442. foreach( $photo->attributes() as $name => $value ) {
  443. $props[$name] = (string)$value;
  444. }
  445. $props = array_merge( $props, self::element_props( $photo, "http://www.flickr.com/photos/{$_SESSION['nsid']}/{$photo['id']}", $size ) );
  446. $results[] = new MediaAsset(
  447. self::SILO_NAME . '/photos/' . $photo['id'],
  448. false,
  449. $props
  450. );
  451. }
  452. break;
  453. case 'videos':
  454. $xml = $flickr->videoSearch();
  455. foreach( $xml->photos->photo as $photo ) {
  456. $props = array();
  457. foreach( $photo->attributes() as $name => $value ) {
  458. $props[$name] = (string)$value;
  459. }
  460. $props = array_merge( $props, self::element_props( $photo, "http://www.flickr.com/photos/{$_SESSION['nsid']}/{$photo['id']}", $size ) );
  461. $props['filetype'] = 'flickrvideo';
  462. $results[] = new MediaAsset(
  463. self::SILO_NAME . '/photos/' . $photo['id'],
  464. false,
  465. $props
  466. );
  467. }
  468. break;
  469. case 'tags':
  470. $selected_tag = strtok('/');
  471. if ( $selected_tag ) {
  472. $xml = $flickr->photosSearch( array( 'tags'=>$selected_tag ) );
  473. foreach( $xml->photos->photo as $photo ) {
  474. $props = array();
  475. foreach( $photo->attributes() as $name => $value ) {
  476. $props[$name] = (string)$value;
  477. }
  478. $props = array_merge( $props, self::element_props( $photo, "http://www.flickr.com/photos/{$_SESSION['nsid']}/{$photo['id']}", $size ) );
  479. $results[] = new MediaAsset(
  480. self::SILO_NAME . '/photos/' . $photo['id'],
  481. false,
  482. $props
  483. );
  484. }
  485. }
  486. else {
  487. $xml = $flickr->tagsGetListUser( $_SESSION['nsid'] );
  488. foreach( $xml->who->tags->tag as $tag ) {
  489. $results[] = new MediaAsset(
  490. self::SILO_NAME . '/tags/' . (string)$tag,
  491. true,
  492. array( 'title' => (string)$tag )
  493. );
  494. }
  495. }
  496. break;
  497. case 'sets':
  498. $selected_set = strtok('/');
  499. if ( $selected_set ) {
  500. $xml = $flickr->photosetsGetPhotos( $selected_set );
  501. foreach( $xml->photoset->photo as $photo ) {
  502. $props = array();
  503. foreach( $photo->attributes() as $name => $value ) {
  504. $props[$name] = (string)$value;
  505. }
  506. $props = array_merge( $props, self::element_props( $photo, "http://www.flickr.com/photos/{$_SESSION['nsid']}/{$photo['id']}", $size ) );
  507. $results[] = new MediaAsset(
  508. self::SILO_NAME . '/photos/' . $photo['id'],
  509. false,
  510. $props
  511. );
  512. }
  513. }
  514. else {
  515. $xml = $flickr->photosetsGetList( $_SESSION['nsid'] );
  516. foreach( $xml->photosets->photoset as $set ) {
  517. $results[] = new MediaAsset(
  518. self::SILO_NAME . '/sets/' . (string)$set['id'],
  519. true,
  520. array( 'title' => (string)$set->title )
  521. );
  522. }
  523. }
  524. break;
  525. case '$search':
  526. $path = strtok( '/' );
  527. $dosearch = Utils::slugify( $path );
  528. $_SESSION['flickrsearch'] = $path;
  529. $section = $path;
  530. case '':
  531. if ( isset( $_SESSION['flickrsearch'] ) ) {
  532. $results[] = new MediaAsset(
  533. self::SILO_NAME . '/search',
  534. true,
  535. array( 'title' => _t( 'Search' ) )
  536. );
  537. $results[] = new MediaAsset(
  538. self::SILO_NAME . '/attrib-sa',
  539. true,
  540. array( 'title' => _t( 'Search CC' ) )
  541. );
  542. }
  543. $results[] = new MediaAsset(
  544. self::SILO_NAME . '/photos',
  545. true,
  546. array('title' => _t( 'Photos' ) )
  547. );
  548. $results[] = new MediaAsset(
  549. self::SILO_NAME . '/videos',
  550. true,
  551. array('title' => _t( 'Videos' ) )
  552. );
  553. $results[] = new MediaAsset(
  554. self::SILO_NAME . '/tags',
  555. true,
  556. array('title' => _t( 'Tags' ) )
  557. );
  558. $results[] = new MediaAsset(
  559. self::SILO_NAME . '/sets',
  560. true,
  561. array('title' => _t( 'Sets' ) )
  562. );
  563. break;
  564. }
  565. return $results;
  566. }
  567. /**
  568. * Function that populates the element properties for use in the silo.
  569. *
  570. * This is to reduce the amount of duplicate code.
  571. *
  572. * @param array $photo The photo element array
  573. * @param string $url The Flickr URL to link to
  574. * @param string $size The size of the image to display.
  575. * @return array
  576. */
  577. private static function element_props( $photo, $url, $size )
  578. {
  579. $props = array();
  580. $props['url'] = "http://farm{$photo['farm']}.static.flickr.com/{$photo['server']}/{$photo['id']}_{$photo['secret']}{$size}.jpg";
  581. $props['thumbnail_url'] = "http://farm{$photo['farm']}.static.flickr.com/{$photo['server']}/{$photo['id']}_{$photo['secret']}_m.jpg";
  582. $props['flickr_url'] = $url;
  583. $props['filetype'] = 'flickr';
  584. return $props;
  585. }
  586. /**
  587. * Get the file from the specified path
  588. *
  589. * @param string $path The path of the file to retrieve
  590. * @param array $qualities Qualities that specify the version of the file to retrieve.
  591. * @return MediaAsset The requested asset
  592. */
  593. public function silo_get( $path, $qualities = null )
  594. {
  595. $flickr = new Flickr();
  596. $results = array();
  597. $size = Options::get( 'flickrsilo__flickr_size' );
  598. list($unused, $photoid) = explode( '/', $path );
  599. $xml = $flickr->photosGetInfo($photoid);
  600. $photo = $xml->photo;
  601. $props = array();
  602. foreach( $photo->attributes() as $name => $value ) {
  603. $props[$name] = (string)$value;
  604. }
  605. $props = array_merge( $props, self::element_props( $photo, "http://www.flickr.com/photos/{$_SESSION['nsid']}/{$photo['id']}", $size ) );
  606. $result = new MediaAsset(
  607. self::SILO_NAME . '/photos/' . $photo['id'],
  608. false,
  609. $props
  610. );
  611. return $result;
  612. }
  613. /**
  614. * Get the direct URL of the file of the specified path
  615. *
  616. * @param string $path The path of the file to retrieve
  617. * @param array $qualities Qualities that specify the version of the file to retrieve.
  618. * @return string The requested url
  619. */
  620. public function silo_url( $path, $qualities = null )
  621. {
  622. $photo = false;
  623. if ( preg_match( '%^photos/(.+)$%', $path, $matches ) ) {
  624. $id = $matches[1];
  625. $photo = self::$cache[$id];
  626. }
  627. $size = '';
  628. if ( isset( $qualities['size'] ) && $qualities['size'] == 'thumbnail' ) {
  629. $size = '_m';
  630. }
  631. $url = "http://farm{$photo['farm']}.static.flickr.com/{$photo['server']}/{$photo['id']}_{$photo['secret']}{$size}.jpg";
  632. return $url;
  633. }
  634. /**
  635. * Create a new asset instance for the specified path
  636. *
  637. * @param string $path The path of the new file to create
  638. * @return MediaAsset The requested asset
  639. */
  640. public function silo_new( $path )
  641. {
  642. }
  643. /**
  644. * Store the specified media at the specified path
  645. *
  646. * @param string $path The path of the file to retrieve
  647. * @param MediaAsset $ The asset to store
  648. */
  649. public function silo_put( $path, $filedata )
  650. {
  651. }
  652. /**
  653. * Delete the file at the specified path
  654. *
  655. * @param string $path The path of the file to retrieve
  656. */
  657. public function silo_delete( $path )
  658. {
  659. }
  660. /**
  661. * Retrieve a set of highlights from this silo
  662. * This would include things like recently uploaded assets, or top downloads
  663. *
  664. * @return array An array of MediaAssets to highlihgt from this silo
  665. */
  666. public function silo_highlights()
  667. {
  668. }
  669. /**
  670. * Retrieve the permissions for the current user to access the specified path
  671. *
  672. * @param string $path The path to retrieve permissions for
  673. * @return array An array of permissions constants (MediaSilo::PERM_READ, MediaSilo::PERM_WRITE)
  674. */
  675. public function silo_permissions( $path )
  676. {
  677. }
  678. /**
  679. * Return directory contents for the silo path
  680. *
  681. * @param string $path The path to retrieve the contents of
  682. * @return array An array of MediaAssets describing the contents of the directory
  683. */
  684. public function silo_contents()
  685. {
  686. $flickr = new Flickr();
  687. $token = Options::get( 'flickr_token_' . User::identify()->id );
  688. $result = $flickr->call( 'flickr.auth.checkToken',
  689. array( 'api_key' => $flickr->key,
  690. 'auth_token' => $token ) );
  691. $photos = $flickr->GetPublicPhotos( $result->auth->user['nsid'], null, 5 );
  692. foreach( $photos['photos'] as $photo ){
  693. $url = $flickr->getPhotoURL( $photo );
  694. echo '<img src="' . $url . '" width="150px" alt="' . ( isset( $photo['title'] ) ? $photo['title'] : _t('This photo has no title') ) . '">';
  695. }
  696. }
  697. /**
  698. * Add actions to the plugin page for this plugin
  699. * The authorization should probably be done per-user.
  700. *
  701. * @param array $actions An array of actions that apply to this plugin
  702. * @param string $plugin_id The string id of a plugin, generated by the system
  703. * @return array The array of actions to attach to the specified $plugin_id
  704. */
  705. public function filter_plugin_config( $actions, $plugin_id )
  706. {
  707. $flickr_ok = $this->is_auth();
  708. if ( $flickr_ok ){
  709. $actions['deauthorize'] = _t( 'De-Authorize' );
  710. }
  711. else{
  712. $actions['authorize'] = _t( 'Authorize' );
  713. }
  714. $actions['configure'] = _t( 'Configure' );
  715. return $actions;
  716. }
  717. /**
  718. * Respond to the user selecting the authorize action on the plugin page
  719. *
  720. */
  721. public function action_plugin_ui_authorize()
  722. {
  723. if ( $this->is_auth() ){
  724. $deauth_url = URL::get( 'admin', array( 'page' => 'plugins', 'configure' => $this->plugin_id(), 'configaction' => 'deauthorize' ) ) . '#plugin_options';
  725. echo '<p>' . _t( 'You have already successfully authorized Habari to access your Flickr account.') . '</p>';
  726. echo '<p>' . _t( 'Do you want to ') . '<a href="">' . _t( 'revoke authorization' ) . '</a>?</p>';
  727. }
  728. else{
  729. $flickr = new Flickr();
  730. $_SESSION['flickr_frob'] = '' . $flickr->getFrob();
  731. $auth_url = $flickr->authLink( $_SESSION['flickr_frob'] );
  732. $confirm_url = URL::get( 'admin', array( 'page' => 'plugins', 'configure' => $this->plugin_id(), 'configaction' => 'confirm' ) ) . '#plugin_options';
  733. echo '<p>' . _t( 'To use this plugin, you must ') . "<a href=\"{$auth_url}\" target=\"_blank\">" . _t( 'authorize Habari to have access to your Flickr account' ) . '</a>.';
  734. echo '<p>' . _t( 'When you have completed the authorization on Flickr, return here and ') . "<a href=\"$confirm_url\">" . _t( 'confirm that the authorization was successful') . '</a>.';
  735. }
  736. }
  737. /**
  738. * Respond to the user selecting the confirm action
  739. *
  740. */
  741. public function action_plugin_ui_confirm()
  742. {
  743. $flickr = new Flickr();
  744. if ( !isset( $_SESSION['flickr_frob'] ) ){
  745. $auth_url = URL::get( 'admin', array( 'page' => 'plugins', 'configure' => $this->plugin_id(), 'configaction' => 'authorize' ) ) . '#plugin_options';
  746. echo '<p>' . _t( 'Either you have already authorized Habari to access your flickr account, or you have not yet done so. Please ' ). '<a href="' . $auth_url . '">' . _t( 'try again' ) . '</a></p>';
  747. }
  748. else{
  749. $token = $flickr->getToken( $_SESSION['flickr_frob'] );
  750. if ( isset( $token->auth->perms ) ){
  751. Options::set( 'flickr_token_' . User::identify()->id, '' . $token->auth->token );
  752. echo '<p>' . _t( 'Your authorization was set successfully.' ) . '</p>';
  753. }
  754. else{
  755. echo '<p>' . _t( 'There was a problem with your authorization:' ) . '</p>';
  756. echo Utils::htmlspecialchars( $token->asXML() );
  757. }
  758. unset( $_SESSION['flickr_frob'] );
  759. }
  760. }
  761. /**
  762. * Respond to the user selecting the deauthorize action
  763. *
  764. */
  765. public function action_plugin_ui_deauthorize()
  766. {
  767. Options::set( 'flickr_token_' . User::identify()->id );
  768. $reauth_url = URL::get( 'admin', array( 'page' => 'plugins', 'configure' => $this->plugin_id(), 'configaction' => 'authorize' ) ) . '#plugin_options';
  769. echo '<p>' . _t( 'The Flickr Silo Plugin authorization has been deleted.' ) . '<p>';
  770. echo '<p>' . _t( 'Do you want to ' ) . "<a href=\"{$reauth_url}\">" . _t( 're-authorize this plugin' ) . "</a>?<p>";
  771. }
  772. /**
  773. * Respond to the user selecting the configure action
  774. *
  775. */
  776. public function action_plugin_ui_configure()
  777. {
  778. $ui = new FormUI( strtolower( get_class( $this ) ) );
  779. $ui->append( 'select', 'flickr_size','option:flickrsilo__flickr_size', _t( 'Default size for images in Posts:' ) );
  780. $ui->flickr_size->options = array( '_s' => _t( 'Square' ) . ' (75x75)', '_t' => _t( 'Thumbnail' ) . ' (100px)', '_m' => _t( 'Small' ) . ' (240px)', '' => _t( 'Medium' ) . ' (500px)', '_b' => _t( 'Large') . ' (1024px)', '_o' => _t( 'Original Size' ) );
  781. $ui->append('submit', 'save', _t( 'Save' ) );
  782. $ui->set_option('success_message', _t( 'Options saved' ) );
  783. $ui->out();
  784. }
  785. public function action_admin_footer( $theme )
  786. {
  787. if ( Controller::get_var( 'page' ) == 'publish' ) {
  788. $size = Options::get( 'flickrsilo__flickr_size' );
  789. switch ( $size ) {
  790. case '_s':
  791. $vsizex = 75;
  792. break;
  793. case '_t':
  794. $vsizex = 100;
  795. break;
  796. case '_m':
  797. $vsizex = 240;
  798. break;
  799. case '':
  800. $vsizex = 500;
  801. break;
  802. case '_b':
  803. $vsizex = 1024;
  804. break;
  805. case '_o':
  806. $vsizex = 400;
  807. break;
  808. }
  809. $vsizey = intval( $vsizex/4*3 );
  810. echo <<< FLICKR
  811. <script type="text/javascript">
  812. habari.media.output.flickr = {
  813. embed_photo: function(fileindex, fileobj) {
  814. habari.editor.insertSelection('<a href="' + fileobj.flickr_url + '"><img alt="' + fileobj.title + '" src="' + fileobj.url + '"></a>');
  815. }
  816. }
  817. habari.media.output.flickrvideo = {
  818. embed_video: function(fileindex, fileobj) {
  819. habari.editor.insertSelection('<object type="application/x-shockwave-flash" width="{$vsizex}" height="{$vsizey}" data="http://www.flickr.com/apps/video/stewart.swf?v=49235" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param name="flashvars" value="intl_lang=en-us&amp;photo_secret=' + fileobj.secret + '&amp;photo_id=' + fileobj.id + '&amp;show_info_box=true"></param> <param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=49235"></param> <param name="bgcolor" value="#000000"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=49235" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&amp;photo_secret=' + fileobj.secret + '&amp;photo_id=' + fileobj.id + '&amp;flickr_show_info_box=true" height="{$vsizey}" width="{$vsizex}"></embed></object>');
  820. },
  821. thumbnail: function(fileindex, fileobj) {
  822. habari.editor.insertSelection('<a href="' + fileobj.flickr_url + '"><img alt="' + fileobj.title + '" src="' + fileobj.url + '"></a>');
  823. }
  824. }
  825. habari.media.preview.flickr = function(fileindex, fileobj) {
  826. var stats = '';
  827. return '<div class="mediatitle"><a href="' + fileobj.flickr_url + '" class="medialink" onclick="$(this).attr(\'target\',\'_blank\');" title="Open in new window">media</a>' + fileobj.title + '</div><img src="' + fileobj.thumbnail_url + '"><div class="mediastats"> ' + stats + '</div>';
  828. }
  829. habari.media.preview.flickrvideo = function(fileindex, fileobj) {
  830. var stats = '';
  831. return '<div class="mediatitle"><a href="' + fileobj.flickr_url + '" class="medialink" onclick="$(this).attr(\'target\',\'_blank\');"title="Open in new window" >media</a>' + fileobj.title + '</div><img src="' + fileobj.thumbnail_url + '"><div class="mediastats"> ' + stats + '</div>';
  832. }
  833. </script>
  834. FLICKR;
  835. }
  836. }
  837. private function is_auth()
  838. {
  839. static $flickr_ok = null;
  840. if ( isset( $flickr_ok ) ){
  841. return $flickr_ok;
  842. }
  843. $flickr_ok = false;
  844. $token = Options::get( 'flickr_token_' . User::identify()->id );
  845. if ( $token != '' ){
  846. $flickr = new Flickr();
  847. $result = $flickr->call( 'flickr.auth.checkToken', array( 'api_key' => $flickr->key, 'auth_token' => $token ) );
  848. if ( isset( $result->auth->perms ) ){
  849. $flickr_ok = true;
  850. $_SESSION['nsid'] = (string)$result->auth->user['nsid'];
  851. }
  852. else{
  853. Options::set( 'flickr_token_' . User::identify()->id );
  854. unset( $_SESSION['flickr_token'] );
  855. }
  856. }
  857. return $flickr_ok;
  858. }
  859. /**
  860. * Provide controls for the media control bar
  861. *
  862. * @param array $controls Incoming controls from other plugins
  863. * @param MediaSilo $silo An instance of a MediaSilo
  864. * @param string $path The path to get controls for
  865. * @param string $panelname The name of the requested panel, if none then emptystring
  866. * @return array The altered $controls array with new (or removed) controls
  867. *
  868. * @todo This should really use FormUI, but FormUI needs a way to submit forms via ajax
  869. */
  870. public function filter_media_controls( $controls, $silo, $path, $panelname )
  871. {
  872. $class = __CLASS__;
  873. if ( $silo instanceof $class ) {
  874. unset( $controls['root'] );
  875. $search_criteria = isset( $_SESSION['flickrsearch'] ) ? htmlentities( $_SESSION['flickrsearch'] ) : '';
  876. $controls['search']= '<label for="flickrsearch" class="incontent">' ._t( 'Search' ) . '</label><input type="search" id="flickrsearch" placeholder="'. _t( 'Search for photos' ) .'" value="'.$search_criteria.'">
  877. <script type="text/javascript">
  878. $(\'#flickrsearch\').keypress(function(e){
  879. if (e.which == 13){
  880. habari.media.fullReload();
  881. habari.media.showdir(\''.FlickrSilo::SILO_NAME.'/$search/\' + $(this).val());
  882. return false;
  883. }
  884. });
  885. </script>';
  886. }
  887. return $controls;
  888. }
  889. }
  890. ?>