id = $id; // Ensure some default settings are specified. $settings += array( 'filter_markup' => TRUE, 'process_attributes' => FALSE, ); $this->settings = $settings; } /** * {@inheritdoc} */ public function setId($value, $reset = TRUE) { if ($reset || empty($this->id)) { $this->id = $value; return TRUE; } return FALSE; } /** * {@inheritdoc} */ public function getId() { return $this->id; } /** * {@inheritdoc} */ public function addImage($src_data = array(), $title = '', $caption = '', $filter_markup = NULL, $override_id = NULL, $offset = NULL) { // If we are anticipating an override, but there is nothing to override, // don't do anything. Also, override_id and offset are mutually exclusive. if (isset($override_id) && (empty($this->images[$override_id]) || isset($offset))) { return FALSE; } // Make sure we have sufficient image data to work with. If legacy attribute // names are supported in the configuration then some names may be coming in // different formats (image_url vs. imageURL). In this case we need a // canonical form for validation. $src_data_canonical = !empty($this->settings['process_attributes']) ? $this->processAttributes($src_data) : $src_data; if (!isset($src_data_canonical['imageURL']) || !isset($src_data_canonical['thumbURL'])) { return FALSE; } // Add image to gallery, overriding if necessary. $addition = array( 'src_data' => $src_data, 'title' => $title, 'caption' => $caption, 'filter_markup' => $filter_markup, ); if (isset($override_id)) { $this->images[$override_id] = $addition; } elseif (isset($offset)) { array_splice($this->images, $offset, 0, array($addition)); } else { $this->images[] = $addition; } return TRUE; } /** * {@inheritdoc} */ public function updateImage($image_id, $src_data = array(), $title = '', $caption = '', $filter = TRUE) { // Updating can be accomplished with addImage(), so just pass-through the // needed params. return $this->addImage($src_data, $title, $caption, $filter, $image_id); } /** * {@inheritdoc} */ public function getImages($filtered = FALSE) { $images = $this->images; // If we are not returning the raw input data we need to apply any output // processing that may be specified in the object configuration. if ($filtered) { foreach ($images as &$image) { $image['title'] = !empty($this->settings['filter_markup']) ? $this->filterMarkup($image['title']) : $image['title']; $image['caption'] = !empty($this->settings['filter_markup']) ? $this->filterMarkup($image['caption']) : $image['caption']; $image['src_data'] = !empty($this->settings['process_attributes']) ? $this->processAttributes($image['src_data']) : $image['src_data']; // Also derive linkURL and linkTarget values if they are not explicitly // set. if (!isset($image['src_data']['linkURL'])) { $image['src_data']['linkURL'] = $image['src_data']['imageURL']; } if (!isset($image['src_data']['linkTarget'])) { $image['src_data']['linkTarget'] = '_blank'; } } } return $images; } /** * {@inheritdoc} */ public function removeImage($id) { if (!empty($this->images[$id])) { unset($this->images[$id]); return TRUE; } return FALSE; } /** * {@inheritdoc} */ public function addOption($option_name, $option_value, $override = TRUE) { // Always use lowercase keys to allow for future lookups. $option_name = strtolower($option_name); if (!empty($this->options[$option_name]) && !$override) { return FALSE; } // Add option, $this->options[$option_name] = $option_value; return TRUE; } /** * {@inheritdoc} */ public function getOptions($filtered = FALSE) { $options = $this->options; // If we are not returning the raw input data we need to apply any output // processing that may be specified in the object configuration. if ($filtered) { $options = !empty($this->settings['process_attributes']) ? $this->processAttributes($options) : $options; } return $options; } /** * {@inheritdoc} */ public function removeOption($option_name) { $option_name = strtolower($option_name); if (!empty($this->options[$option_name])) { unset($this->options[$option_name]); return TRUE; } return FALSE; } /** * {@inheritdoc} */ public function getChecksum() { return md5(json_encode($this->images) . json_encode($this->options)); } /** * {@inheritdoc} */ public function renderXml($embed_wrap_id = NULL) { // We use DOMDocument instead of a SimpleXMLElement to build the XML as it's // much more flexible (CDATA is supported, etc.). $dom = new DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = TRUE; $juicebox = $dom->appendChild($dom->createElement('juicebox')); // Get filtered attributes. $gallery_attributes = $this->getOptions(TRUE); foreach ($gallery_attributes as $attribute => $value) { $juicebox->setAttribute($attribute, $value); } // Get filtered image data. $gallery_images = $this->getImages(TRUE); foreach ($gallery_images as $image) { $juicebox_image = $juicebox->appendChild($dom->createElement('image')); foreach ($image['src_data'] as $attribute => $value) { $juicebox_image->setAttribute($attribute, $value); } $juicebox_image_title = $juicebox_image->appendChild($dom->createElement('title')); $juicebox_image_title->appendChild($dom->createCDATASection($image['title'])); $juicebox_image_caption = $juicebox_image->appendChild($dom->createElement('caption')); $juicebox_image_caption->appendChild($dom->createCDATASection($image['caption'])); } $prefix = $suffix = ''; if ($embed_wrap_id) { $prefix = ''; } return $prefix . $dom->saveXML() . $suffix; } /** * {@inheritdoc} */ public function renderEmbed() { $output = ''; $output .= '
, making any * block-level elements they contain invalid. This filter accommodates for * this and is meant to be applied AFTER any external filters. Note that this * process does NOT do any sanitization. * * @param string $markup * The markup to be filtered after it has been processed externally. * @return string * Valid filtered markup ready for display in a Juicebox gallery. */ protected function filterMarkup($markup) { // Set inline html5 elements that are safe in a Juicebox gallery. Ref: // http://www.w3.org/html/wg/drafts/html/master/single-page.html#phrasing-content $valid_elements = "