/**
  * Returns the rendered template of an image browser display
  *
  * @param C_Displayed_Gallery
  * @param array $picture_list
  * @return string Rendered HTML (probably)
  */
 function render_image_browser($displayed_gallery, $picture_list)
 {
     $display_settings = $displayed_gallery->display_settings;
     $storage = $this->object->get_registry()->get_utility('I_Gallery_Storage');
     $imap = $this->object->get_registry()->get_utility('I_Image_Mapper');
     $application = $this->object->get_registry()->get_utility('I_Router')->get_routed_app();
     // the pid may be a slug so we must track it & the slug target's database id
     $pid = $this->object->param('pid');
     $numeric_pid = NULL;
     // makes the upcoming which-image-am-I loop easier
     $picture_array = array();
     foreach ($picture_list as $picture) {
         $picture_array[] = $picture->{$imap->get_primary_key_column()};
     }
     // Determine which image in the list we need to display
     if (!empty($pid)) {
         if (is_numeric($pid) && !empty($picture_list[$pid])) {
             $numeric_pid = intval($pid);
         } else {
             // in the case it's a slug we need to search for the pid
             foreach ($picture_list as $key => $picture) {
                 if ($picture->image_slug == $pid) {
                     $numeric_pid = $key;
                     break;
                 }
             }
         }
     } else {
         reset($picture_array);
         $numeric_pid = current($picture_array);
     }
     // get ids to the next and previous images
     $total = count($picture_array);
     $key = array_search($numeric_pid, $picture_array);
     if (!$key) {
         $numeric_pid = reset($picture_array);
         $key = key($picture_array);
     }
     // for "viewing image #13 of $total"
     $picture_list_pos = $key + 1;
     // our image to display
     $picture = new C_Image_Wrapper($imap->find($numeric_pid), $displayed_gallery, TRUE);
     $picture = apply_filters('ngg_image_object', $picture, $numeric_pid);
     // determine URI to the next & previous images
     $back_pid = $key >= 1 ? $picture_array[$key - 1] : end($picture_array);
     // 'show' is set when using the imagebrowser as an alternate view to a thumbnail or slideshow
     // for which the basic-gallery module will rewrite the show parameter into existence as long as 'image'
     // is set. We remove 'show' here so navigation appears fluid.
     $current_url = $application->get_routed_url(TRUE);
     if ($this->object->param('ajax_pagination_referrer')) {
         $current_url = $this->object->param('ajax_pagination_referrer');
     }
     $prev_image_link = $this->object->set_param_for($current_url, 'pid', $picture_list[$back_pid]->image_slug);
     $prev_image_link = $this->object->remove_param_for($prev_image_link, 'show', $displayed_gallery->id());
     $next_pid = $key < $total - 1 ? $picture_array[$key + 1] : reset($picture_array);
     $next_image_link = $this->object->set_param_for($current_url, 'pid', $picture_list[$next_pid]->image_slug);
     $next_image_link = $this->object->remove_param_for($next_image_link, 'show', $displayed_gallery->id());
     // css class
     $anchor = 'ngg-imagebrowser-' . $displayed_gallery->id() . '-' . (get_the_ID() == false ? 0 : get_the_ID());
     // try to read EXIF data, but fallback to the db presets
     $meta = new C_NextGen_Metadata($picture);
     $meta->sanitize();
     $meta_results = array('exif' => $meta->get_EXIF(), 'iptc' => $meta->get_IPTC(), 'xmp' => $meta->get_XMP(), 'db' => $meta->get_saved_meta());
     $meta_results['exif'] = $meta_results['exif'] == false ? $meta_results['db'] : $meta_results['exif'];
     // disable triggers IF we're rendering inside of an ajax-pagination request; var set in common.js
     if (!empty($_POST['ajax_referrer'])) {
         $displayed_gallery->display_settings['ngg_triggers_display'] = 'never';
     }
     if (!empty($display_settings['template'])) {
         $this->object->add_mixin('Mixin_NextGen_Basic_Templates');
         $picture->href_link = $picture->get_href_link();
         $picture->previous_image_link = $prev_image_link;
         $picture->previous_pid = $back_pid;
         $picture->next_image_link = $next_image_link;
         $picture->next_pid = $next_pid;
         $picture->number = $picture_list_pos;
         $picture->total = $total;
         $picture->anchor = $anchor;
         return $this->object->legacy_render($display_settings['template'], array('image' => $picture, 'meta' => $meta, 'exif' => $meta_results['exif'], 'iptc' => $meta_results['iptc'], 'xmp' => $meta_results['xmp'], 'db' => $meta_results['db']), TRUE, 'imagebrowser');
     } else {
         $params = $display_settings;
         $params['anchor'] = $anchor;
         $params['image'] = $picture;
         $params['storage'] =& $storage;
         $params['previous_pid'] = $back_pid;
         $params['next_pid'] = $next_pid;
         $params['number'] = $picture_list_pos;
         $params['total'] = $total;
         $params['previous_image_link'] = $prev_image_link;
         $params['next_image_link'] = $next_image_link;
         $params['effect_code'] = $this->object->get_effect_code($displayed_gallery);
         $params = $this->object->prepare_display_parameters($displayed_gallery, $params);
         return $this->object->render_partial('photocrati-nextgen_basic_imagebrowser#nextgen_basic_imagebrowser', $params, TRUE);
     }
 }
 /**
  * Recover image from backup copy and reprocess it
  *
  * @param int|stdClass|C_Image $image
  * @return string result code
  */
 function recover_image($image)
 {
     if (is_numeric($image)) {
         $image = $this->object->_image_mapper->find($image);
     }
     if (isset($image->meta_data)) {
         $orig_metadata = $image->meta_data;
     }
     $path = $this->object->get_registry()->get_utility('I_Gallery_Storage')->get_image_abspath($image);
     if (!is_object($image)) {
         return __("Could not find image", 'nggallery');
     }
     if (!is_writable($path) && !is_writable(dirname($path))) {
         return ' <strong>' . esc_html($image->filename) . __(' is not writeable', 'nggallery') . '</strong>';
     }
     if (!@file_exists($path . '_backup')) {
         return ' <strong>' . __('Backup file does not exist', 'nggallery') . '</strong>';
     }
     if (!@copy($path . '_backup', $path)) {
         return ' <strong>' . __("Could not restore original image", 'nggallery') . '</strong>';
     }
     if (isset($orig_metadata)) {
         $NextGen_Metadata = new C_NextGen_Metadata($image);
         $new_metadata = $NextGen_Metadata->get_common_meta();
         $image->meta_data = array_merge((array) $orig_metadata, (array) $new_metadata);
         $this->object->_image_mapper->save($image);
     }
     return '1';
 }