<?
// Version 0.3 BETA. by Jonas M Luster <jluster@jluster.org>

// hook_menu. Make me proud, Drupal, and change this to something a little bit
// more 21st century?
function flickr_menu($may_cache) {
  $view = user_access('access content');
  $items = array();
  $items[] = array('path' => 'flickr', 'title' => t('my flickr photosets'),
            'callback' => 'flickr_page', 'access' => $view,
            'weight' => 5);
  $items[] = array('path' => 'flickr/setimages', 'title' => t('a photoset'),
            'callback' => 'flickr_setimages', 'access' => $view,
            'weight' => 5, 'type' => MENU_CALLBACK);
  return $items;
}

// Our filter.
function flickr_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
    case 'list':
      return array(0 => t("Flickrtag Filter"));
    case 'description':
      return t("Turns flickrtags ({{}}) into images.");
    case 'process':
      return flickr_tagify($text);
    default:
      return $text;
  }
}

// Make Flicktrags for Filter
function flickr_makefltag($stri, $size="_m", $linked=1) {
  $url = 'http://www.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key='.variable_get('flickr_apik','bd4441fc9cef3745a18955ffdf91c732').'&photo_id='.$stri;
  $resp = flickr_get_cached_file_contents($url, 'r', 1, variable_get('flickr_cache','/tmp')); 
  $photo = flickr_make_xmltree($resp);
  $purl = "http://www.flickr.com/photos/".variable_get('flickr_uname', 'jluster')."/".$stri;
  if ($linked) {
    $image = '<a href="'.$purl.'"><img class="'.variable_get('flickr_class', 'flickr').'" src="http://photos'.$photo['rsp']['server'].'.flickr.com/'.$stri.'_'.$photo['rsp']['secret'].$size.'.jpg" /></a>';
  } 
  else {
    $image = '<img class="'.variable_get('flickr_class', 'flickr').'" src="http://photos'.$photo['rsp']['server'].'.flickr.com/'.$stri.'_'.$photo['rsp']['secret'].$size.'.jpg" />';
  }
  return $image;
}

// And the filter logic
function flickr_tagify($text) {
  $text = preg_replace("/{{flickr:(.*)}}/e", "flickr_makefltag('\\1', '_m')", $text);
  $text = preg_replace("/{{flickrnl:(.*)}}/e", "flickr_makefltag('\\1', '_m', 0)", $text);
  $text = preg_replace("/{{flickrtn:(.*)}}/e", "flickr_makefltag('\\1', '_s')", $text);
  $text = preg_replace("/{{flickrbig:(.*)}}/e", "flickr_makefltag('\\1', '')", $text);
  return $text;
}

// Help. XXX: TODO: Fill it in.
function flickr_help($section) {
	switch ($section) {
		case 'admin/modules#description':
			return t('Flickr.');
	}
}

function flickr_settings() {
	$output = form_textfield(t('Flickr API Key'),'flickr_apik',variable_get('flickr_apik','bd4441fc9cef3745a18955ffdf91c732'),50,255,t('Your Flickr API Key. The default key is for installation testing only, <a href="http://www.flickr.com/services/api/misc.api_keys.html">Stewart asks you to please get your own key</a>. Continuous usage of this key might result in a deletion of your flickr account.'));
	$output .= form_textfield(t('Flickr User Name'),'flickr_uname',variable_get('flickr_uname','jluster'),50,255,t('Your Flickr Username'));
	$output .= form_textfield(t('Flickr User ID'),'flickr_uid',variable_get('flickr_uid','35034355182@N01'),50,255,t('Your Flickr UID. We could calculate your UID from the username, but to save some computing cycles, simply enter it here. The default UID is Jonas\', and will result in Jonas\' pictures being shown...'));
	$output .= form_textfield(t('Flickr Photo Root'),'flickr_proot',variable_get('flickr_proot','http://www.flickr.com/photos/'),50,255,t('Should be fine the way it is. If Flickr goes to a new photo scheme, change this.'));
	$output .= form_textfield(t('Cache Location'),'flickr_cache',variable_get('flickr_cache','/tmp'),50,255,t('Set this to a directory, your webserver has read and write to. Using /tmp is not advisable in the long run, being this directory might be emptied at any time.'));
	$output .= form_textfield(t('Flickr Image Class'),'flickr_class',variable_get('flickr_class','flickr'),50,255,t('Value for the class="" attribute in generated flickr tags. This setting will go away in 0.4 as soon as theme_ functions are introduced.'));
	return $output;
} 

function flickr_page() {
  if (user_access("access content")) {
    $flickr_api_key = variable_get('flickr_apik','bd4441fc9cef3745a18955ffdf91c732');
    $flickr_uid     = variable_get('flickr_uid','35034355182@N01');
    
    $url = "http://www.flickr.com/services/rest/?method=flickr.photosets.getList&api_key=$flickr_api_key&user_id=$flickr_uid";
    $resp = flickr_get_cached_file_contents($url, 'r', 600, variable_get('flickr_cache','/tmp'));
    $settree = flickr_make_xmltree($resp);

    if (!empty($top_level_tree['rsp']['err']) || empty($settree))
    {
      $output = "<h2>An error occurred</h2> Somehow we were unable to parse the response. Please contact the site owner for investigation.";
    } 
    else {
      $i = 0;
      foreach ($settree['rsp']['photosets'] as $album_id => $album_details) {
        $thumbnail = variable_get('flickr_proot','http://www.flickr.com/photos/').$album_details['primary']."_".$album_details['secret']."_s.jpg";
        $output .= "<div style='float: right;'><img src='".$thumbnail."' alt='".$album_details['title']."' class='kontent'></div>";
        $output .= "<h2><a class=\"title\" href=\"". variable_get('flickr_proot','http://www.flickr.com/photos/').variable_get('flickr_uname','jluster')."/sets/". $album_id ."/\"";   
        $output .= "title=\"".$album_details['title']."\">".$album_details['title']."</a></h2>";
        $output .= "<p>". format_plural($album_details['photos'], '1 photo', '%count photos') ." in this album (<a href='/flickr/setimages/$album_id'>view locally</a> - click title to view on Flickr).</p>";
        $output .= "<p>".$album_details['description']."</p>";
      }
    }
    $output .= "<div style='font-size: 90%; text-align: center;'>flickr.module BETA.3, by <a href='http://www.jluster.org/'>Jonas M Luster</a></div>";
    print theme('page', $output, "Flickr Sets");
  } 
  else {
    $output = theme("box", t("Access denied"),  message_access());
    theme("page", $output, t("Access denied"));
  }
}

function flickr_setimages() 
{
  if (user_access("access content")) {
    $setid = arg(2);
    $flickr_api_key = variable_get('flickr_apik','bd4441fc9cef3745a18955ffdf91c732');
    $flickr_uid     = variable_get('flickr_uid','35034355182@N01');
    $url = "http://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key=$flickr_api_key&user_id=$flickr_uid&photoset_id=$setid";
    $resp = flickr_get_cached_file_contents($url, 'r', 600, variable_get('flickr_cache','/tmp')); 
    $settree = flickr_make_xmltree($resp);
    
    if (!empty($settree['rsp']['err']) || empty($settree))
    {
      $output = "<h2>An error occurred</h2> Somehow we were unable to parse the response. Please contact the site owner for investigation.";
    } 
    else {
      unset($settree['rsp'][$setid]['primary']);
		  unset($settree['rsp'][$setid]['secret']);
		  unset($settree['rsp'][$setid]['photos']);
		  $output = "<div style='text-align: center'>";
      foreach ($settree['rsp'][$setid] as $photo_id => $photo_details) {
        $image = "http://photos".$photo_details['server'].".flickr.com/".$photo_id."_".$photo_details['secret']."_m.jpg";
        $output .= "<a href=\"". variable_get('flickr_proot', 'http://www.flickr.com/photos/').variable_get('flickr_uname', 'jluster')."/$photo_id\"><img src=\"$image\" class='kontent'/></a>";
      }
      $output .= "</div>";
    }
    print theme('page', $output, "Flickr Set Photos");
  } 
  else {
    $output = theme("box", t("Access denied"),  message_access());
    theme("page", $output, t("Access denied"));
  }
}

function flickr_get_cached_file_contents($file, $file_mode, $cache_timeout = 600, $cache_path = '../', $debug = false)
{
	clearstatcache();
	$cache_filename = $cache_path . "/" . urlencode($file) .".cached"; // Path to cached file
	if (( @file_exists($cache_filename) && (( @filemtime($cache_filename) + $cache_timeout) > ( time())))) 
	{
	  // do nothing. XXX: Add stats code here.
	}
	else {
		$f  = fopen($file,"r");
		$f2 = fopen($cache_filename,"w+");
		while ($r = fread($f,8192))
		{
			fwrite($f2,$r);
		}
		fclose($f2);
		fclose($f);
	}
	return file_get_contents ($cache_filename); // Return the file contents from the cache
}

function flickr_make_xmltree ($data)
{
  // Yes, I know, this is slightly inflexible. This is a modified version of the WordPress FlickrXML parser. A new
  // logic will be in 0.4.
	$output = array();
	$parser = xml_parser_create();
	xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
	xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
	xml_parse_into_struct($parser, $data, $values, $tags);
	xml_parser_free($parser);
	$hash_stack = array();
	foreach ($values as $key => $val) 
	{
		switch ($val['type'])
		{
			case 'open':
				switch ($val['tag'])
				{
					case 'photoset': // Grab photoset attributes
						array_push($hash_stack, $val['attributes']['id']);
						array_push($hash_stack, 'primary');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['primary']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'secret');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['secret']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'photos');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['photos']}\";");
						array_pop($hash_stack);
						break;
					case 'photo':
  					array_push($hash_stack, $val['tag']);
  					array_pop($hash_stack);
  					array_push($hash_stack, 'secret');						
  					eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['secret']}\";");
  					array_pop($hash_stack);
  					array_push($hash_stack, 'server');						
  					eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['server']}\";");
  					array_pop($hash_stack);
  					break;
					default:
						array_push($hash_stack, $val['tag']);
						break;
				}
				break;

			case 'close':
				array_pop($hash_stack);
				break;

			case 'complete':
				switch ($val['tag'])
				{
					case 'photo': // Grab photo attributes
						array_push($hash_stack, $val['attributes']['id']);
						array_push($hash_stack, 'secret');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['secret']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'isprimary');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['isprimary']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'server');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['server']}\";");
						array_pop($hash_stack);
						array_pop($hash_stack);
						break;
					case 'note': // Grab note attributes
						array_push($hash_stack, $val['attributes']['id']);
						array_push($hash_stack, 'author');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['author']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'secret');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['secret']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'authorname');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['authorname']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'x');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['x']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'y');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['y']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'w');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['w']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'h');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['h']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'value');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['value']}\";");
						array_pop($hash_stack);
						array_pop($hash_stack);
						break;
					case 'tag': // Grab tag attributes
						array_push($hash_stack, $val['attributes']['id']);
						array_push($hash_stack, 'author');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['author']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'value');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['value']}\";");
						array_pop($hash_stack);
						array_pop($hash_stack);
						break;
					case 'err': // Grab error attributes
						array_push($hash_stack, $val['tag']);
						array_push($hash_stack, 'code');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['code']}\";");
						array_pop($hash_stack);
						array_push($hash_stack, 'msg');
						eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['msg']}\";");
						array_pop($hash_stack);
						array_pop($hash_stack);
						break;
					default:
						array_push($hash_stack, $val['tag']);
						@eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['value']}\";");
						array_pop($hash_stack);
						break;
				}
		}
	}
	return $output;
}

?>
