| 1 |
<?php |
| 2 |
|
| 3 |
namespace Photonic_Plugin\Layouts; |
| 4 |
|
| 5 |
use Photonic_Plugin\Components\Header; |
| 6 |
use Photonic_Plugin\Components\Single_Photo; |
| 7 |
use Photonic_Plugin\Core\Photonic; |
| 8 |
use Photonic_Plugin\Platforms\Base; |
| 9 |
|
| 10 |
/** |
| 11 |
* Layout Manager to generate the grid layouts and the "Justified Grid" layout, all of which use the same markup. The Justified Grid layout is |
| 12 |
* modified by JS on the front-end, however the base markup for it is similar to the square and circular thumbnails layout. |
| 13 |
* |
| 14 |
* All other layout managers extend this, and might implement their own versions of generate_level_1_gallery and generate_level_2_gallery |
| 15 |
*/ |
| 16 |
abstract class Core_Layout { |
| 17 |
protected ?string $library; |
| 18 |
protected array $common_parameters = []; |
| 19 |
protected string $prompt_title; |
| 20 |
protected string $prompt_submit; |
| 21 |
protected string $prompt_text; |
| 22 |
|
| 23 |
protected function __construct() { |
| 24 |
$this->library = esc_attr(Photonic::$library); |
| 25 |
|
| 26 |
$this->prompt_title = esc_attr__('Protected Content', 'photonic'); |
| 27 |
$this->prompt_submit = esc_attr__('Access', 'photonic'); |
| 28 |
$this->prompt_text = esc_attr__('This album is password-protected. Please provide a valid password.', 'photonic'); |
| 29 |
} |
| 30 |
|
| 31 |
final public static function get_instance() { |
| 32 |
static $instances = array(); |
| 33 |
$called_class = get_called_class(); |
| 34 |
|
| 35 |
if (!isset($instances[$called_class])) { |
| 36 |
$instances[$called_class] = new $called_class(); |
| 37 |
} |
| 38 |
return $instances[$called_class]; |
| 39 |
} |
| 40 |
|
| 41 |
/** |
| 42 |
* Generates the markup for a single photo. |
| 43 |
* |
| 44 |
* @param Single_Photo $photo Pertinent pieces of information about the photo - the source (src), the photo page (href), title and caption. |
| 45 |
* @param Base $module The object calling this. A CSS class is created in the header, photonic-single-<code>$module->provider</code>-photo-header. |
| 46 |
* @return string |
| 47 |
*/ |
| 48 |
public function generate_single_photo_markup(Single_Photo $photo, Base $module): string { |
| 49 |
$module->push_to_stack('Generate single photo markup'); |
| 50 |
$ret = ''; |
| 51 |
|
| 52 |
if (empty($photo->src)) { |
| 53 |
$module->pop_from_stack(); |
| 54 |
return $ret; |
| 55 |
} |
| 56 |
|
| 57 |
global $photonic_external_links_in_new_tab; |
| 58 |
if (!empty($photo->title)) { |
| 59 |
$ret .= "\t" . '<h3 class="photonic-single-photo-header photonic-single-' . $module->provider . '-photo-header">' . $photo->title . "</h3>\n"; |
| 60 |
} |
| 61 |
|
| 62 |
$img = '<img src="' . esc_url($photo->src) . '" alt="' . esc_attr($photo->caption ?: $photo->title) . '" loading="eager"/>'; |
| 63 |
if (!empty($photo->href)) { |
| 64 |
$img = '<a href="' . esc_url($photo->href) . '" title="' . esc_attr($photo->caption ?: $photo->title) . '" ' . |
| 65 |
(!empty($photonic_external_links_in_new_tab) ? ' target="_blank" ' : '') . '>' . $img . '</a>'; |
| 66 |
} |
| 67 |
|
| 68 |
if (!empty($photo->caption)) { |
| 69 |
$ret .= "\t" . '<div class="wp-caption">' . "\n\t\t" . $img . "\n\t\t" . '<div class="wp-caption-text">' . wp_kses_post($photo->caption) . "</div>\n\t</div><!-- .wp-caption -->\n"; |
| 70 |
} |
| 71 |
else { |
| 72 |
$ret .= $img; |
| 73 |
} |
| 74 |
|
| 75 |
$module->pop_from_stack(); |
| 76 |
return $ret; |
| 77 |
} |
| 78 |
|
| 79 |
/** |
| 80 |
* Generates the markup for a <code>Header</code> element. A header typically consists of a thumbnail, a title and some |
| 81 |
* information about the child counts. |
| 82 |
* |
| 83 |
* @param Header $header |
| 84 |
* @param Base $module |
| 85 |
* @return string |
| 86 |
*/ |
| 87 |
public function generate_header_markup(Header $header, Base $module): string { |
| 88 |
if ('lightbox' === $header->display_location || $this instanceof Slideshow) { |
| 89 |
return ''; |
| 90 |
} |
| 91 |
|
| 92 |
$ret = ''; |
| 93 |
global $photonic_gallery_template_page, $photonic_page_content; |
| 94 |
|
| 95 |
if (!empty($photonic_gallery_template_page) && is_page($photonic_gallery_template_page) && in_array($photonic_page_content, ['replace-if-available', 'append-if-available'], true)) { |
| 96 |
$ret = wptexturize(wp_kses_post($header->description)); |
| 97 |
} |
| 98 |
elseif ((empty($photonic_gallery_template_page) || |
| 99 |
!is_page() || |
| 100 |
(is_page() && !empty($photonic_gallery_template_page) && !is_page($photonic_gallery_template_page))) && |
| 101 |
!empty($header->title)) { |
| 102 |
global $photonic_external_links_in_new_tab; |
| 103 |
$title = esc_attr($header->title); |
| 104 |
|
| 105 |
if (!empty($photonic_external_links_in_new_tab)) { |
| 106 |
$target = ' target="_blank" '; |
| 107 |
} |
| 108 |
else { |
| 109 |
$target = ''; |
| 110 |
} |
| 111 |
|
| 112 |
$anchor = ''; |
| 113 |
if (!empty($header->thumb_url)) { |
| 114 |
$image = '<img src="' . esc_url($header->thumb_url) . '" alt="' . $title . '" />'; |
| 115 |
|
| 116 |
if ($header->enable_link) { |
| 117 |
$anchor = "<a href='" . esc_url($header->page_url) . "' class='photonic-header-thumb photonic-{$module->provider}-{$header->header_for}-solo-thumb' title='" . $title . "' $target>" . $image . "</a>"; |
| 118 |
} |
| 119 |
else { |
| 120 |
$anchor = "<div class='photonic-header-thumb photonic-{$module->provider}-{$header->header_for}-solo-thumb'>$image</div>"; |
| 121 |
} |
| 122 |
} |
| 123 |
|
| 124 |
if (empty($header->hidden_elements['thumbnail']) || empty($header->hidden_elements['title']) || empty($header->hidden_elements['counter']) || empty($header->iterate_level_3)) { |
| 125 |
$popup_header_class = ''; |
| 126 |
if ('modal' === $header->display_location) { |
| 127 |
$popup_header_class = 'photonic-panel-header'; |
| 128 |
} |
| 129 |
$ret .= "<header class='photonic-object-header photonic-{$module->provider}-{$header->header_for} $popup_header_class'>"; |
| 130 |
|
| 131 |
if (empty($header->hidden_elements['thumbnail'])) { |
| 132 |
$ret .= $anchor; |
| 133 |
} |
| 134 |
if (empty($header->hidden_elements['title']) || empty($header->hidden_elements['counter']) || empty($header->iterate_level_3)) { |
| 135 |
$ret .= "<div class='photonic-header-details photonic-{$header->header_for}-details'>"; |
| 136 |
if (empty($header->hidden_elements['title']) || empty($header->iterate_level_3)) { |
| 137 |
$expand = empty($header->iterate_level_3) ? '<a href="#" title="' . esc_attr__('Show', 'photonic') . '" class="photonic-level-3-expand photonic-level-3-expand-plus" data-photonic-level-3="' . $module->provider . '-' . $header->header_for . '-' . $header->id . '" data-photonic-layout="' . $header->layout . '"> </a>' : ''; |
| 138 |
|
| 139 |
if ($header->enable_link) { |
| 140 |
$ret .= "<div class='photonic-header-title photonic-{$header->header_for}-title'><a href='" . esc_url($header->page_url) . "' $target>" . wptexturize($title) . '</a>' . $expand . '</div>'; |
| 141 |
} |
| 142 |
else { |
| 143 |
$ret .= "<div class='photonic-header-title photonic-{$header->header_for}-title'>" . wptexturize($title) . $expand . '</div>'; |
| 144 |
} |
| 145 |
} |
| 146 |
|
| 147 |
if (empty($header->hidden_elements['counter'])) { |
| 148 |
$counter_texts = []; |
| 149 |
if (!empty($header->counters['groups'])) { |
| 150 |
$counter_texts[] = esc_html(sprintf(_n('%s group', '%s groups', $header->counters['groups'], 'photonic'), $header->counters['groups'])); |
| 151 |
} |
| 152 |
if (!empty($header->counters['sets'])) { |
| 153 |
$counter_texts[] = esc_html(sprintf(_n('%s set', '%s sets', $header->counters['sets'], 'photonic'), $header->counters['sets'])); |
| 154 |
} |
| 155 |
if (!empty($header->counters['photos'])) { |
| 156 |
$counter_texts[] = esc_html(sprintf(_n('%s photo', '%s photos', $header->counters['photos'], 'photonic'), $header->counters['photos'])); |
| 157 |
} |
| 158 |
if (!empty($header->counters['videos'])) { |
| 159 |
$counter_texts[] = esc_html(sprintf(_n('%s video', '%s videos', $header->counters['videos'], 'photonic'), $header->counters['videos'])); |
| 160 |
} |
| 161 |
|
| 162 |
apply_filters('photonic_modify_counter_texts', $counter_texts, $header->counters); |
| 163 |
|
| 164 |
if (!empty($counter_texts)) { |
| 165 |
$ret .= "<span class='photonic-header-info photonic-{$header->header_for}-photos'>" . implode(', ', $counter_texts) . '</span>'; |
| 166 |
} |
| 167 |
} |
| 168 |
|
| 169 |
$ret .= "</div><!-- .photonic-{$header->header_for}-details -->"; |
| 170 |
} |
| 171 |
$ret .= "</header>"; |
| 172 |
} |
| 173 |
} |
| 174 |
return $ret; |
| 175 |
} |
| 176 |
|
| 177 |
/** |
| 178 |
* @return string|void |
| 179 |
*/ |
| 180 |
public function get_library(): string { |
| 181 |
return $this->library; |
| 182 |
} |
| 183 |
|
| 184 |
public function get_title($title, $titles = [], $short_code = []): string { |
| 185 |
if (empty($short_code['caption']) || 'none' === $short_code['caption']) { |
| 186 |
return ''; |
| 187 |
} |
| 188 |
else { |
| 189 |
$priority = explode('-', $short_code['caption']); |
| 190 |
if (count($priority) === 1) { |
| 191 |
return $titles[$priority[0]] ?? ''; |
| 192 |
} |
| 193 |
else { |
| 194 |
foreach ($priority as $p) { |
| 195 |
if (!empty($titles[$p])) { |
| 196 |
return $titles[$p]; |
| 197 |
} |
| 198 |
} |
| 199 |
} |
| 200 |
} |
| 201 |
|
| 202 |
return $title; |
| 203 |
} |
| 204 |
} |
| 205 |
|