PluginProbe
PowerPress Podcasting plugin by Blubrry / trunk
PowerPress Podcasting plugin by Blubrry vtrunk
11.17.9 11.17.8 11.17.7 11.17.6 11.17.4 11.17.3 11.17.2 11.17.1 11.17 11.16.11 11.16.10 11.16.9 11.16.8 11.16.7 11.16.6 11.16.5 11.16.4 11.16.3 11.16.2 11.16.1 11.9.13 11.9.14 11.9.15 11.9.16 11.9.17 All 383 releases
powerpress / admin / programs.php

programs.php in PowerPress Podcasting plugin by Blubrry trunk, at admin/programs.php

449 lines 24.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // ======
3 // INIT
4 // ======
5
6 $networkID = get_option('powerpress_network_id');
7 $networkObj = $GLOBALS['ppn_object'];
8
9 $networkShowSearchResults = false;
10 $networkShowSearchValue = false;
11 $networkShowSearchCount = 0;
12 if(!empty($_POST) && isset($_POST['search'])){
13 if($networkID){
14 $requestUrl = '/2/powerpress/network/' . $networkID . '/programs/search/';
15 $searchValue = htmlspecialchars($_POST['search']);
16 $result = $networkObj->requestAPI($requestUrl, true, $_POST);
17
18 // check result before access
19 if (!empty($result['error'])) {
20 powerpress_page_message_add_error(__('Error: ', 'powerpress') . $result['error']);
21 } else if ($result) {
22 $networkShowSearchResults = $result['programs'];
23 $networkShowSearchValue = $searchValue;
24 $networkShowSearchCount = $result['num_results'];
25 }
26 }
27 }
28
29 $accountShowsNotInNetwork = false;
30 $accountShowsNotInNetworkCount = 0;
31 if($networkID){
32 // find internal shows not in network
33 $requestUrl = '/2/powerpress/network/' . $networkID . '/not-in-network/';
34 $result = $networkObj->requestAPI($requestUrl, true, $_POST);
35
36 // check result before access
37 if (!empty($result['error'])) {
38 powerpress_page_message_add_error(__('Error: ', 'powerpress') . $result['error']);
39 } else if ($result){
40 $accountShowsNotInNetwork = $result['programs'];
41 $accountShowsNotInNetworkCount = $result['num_results'];
42 }
43
44 // refresh shows in network
45 $requestUrl = '/2/powerpress/network/' . $networkID . '/programs/';
46 $props = $networkObj->requestAPI($requestUrl, true, $_POST);
47
48 // check result before access
49 if (!empty($props['error']) || !is_array($props)) {
50 $props = [];
51 }
52 }
53
54 if (empty($props))
55 $props = [];
56
57 // pre-group by internal/external
58 $groups = ['internal' => [], 'external' => []];
59 $inNetworkIds = [];
60 foreach ($props as $program) {
61 if (empty($program['program_id'])) continue; // skip entries w/o valid program_id
62
63 $bucket = !empty($program['internal']) ? 'internal' : 'external';
64 $groups[$bucket][] = $program;
65
66 $inNetworkIds[$program['program_id']] = true;
67 }
68
69 // =================
70 // HOMEPAGE BUTTON
71 // =================
72
73 // toggle between create and edit based on page existence
74 $homepageMap = get_option('powerpress_network_map', []);
75 $homepageExists = false;
76 $homepageId = null;
77 if (!empty($homepageMap['Homepage'])) {
78 $hpId = $homepageMap['Homepage'];
79 if (get_post_status($hpId) == 'publish') {
80 $homepageExists = true;
81 $homepageId = $hpId;
82 }
83 }
84 ?>
85
86 <!-- =============
87 PAGE HEADER
88 ============= -->
89
90 <div class="ppn-section-header">
91 <h2 class="ppn-manage__section-title">
92 <?php echo esc_html(get_option('powerpress_network_title')); ?>
93 <span id="return-to-shows-list" style="display: <?php echo ($networkShowSearchResults ? 'inline-block' : 'none'); ?>;">
94 | <a href="<?php echo esc_url(admin_url("admin.php?page=" . urlencode(powerpress_admin_get_page()))); ?>" style="color: #1976D2; font-size: 14px;"><?php esc_html_e('Return to shows list', 'powerpress'); ?></a>
95 </span>
96 </h2>
97 <div class="d-flex gap-sm">
98 <form method="POST" action="<?php echo esc_url(admin_url("admin.php?page=" . urlencode(powerpress_admin_get_page()))); ?>" onsubmit="return confirm('<?php echo esc_js(sprintf(__('Are you sure you want to unlink %s?', 'powerpress'), get_option('powerpress_network_title'))); ?>')">
99 <input type="hidden" name="ppn-action" value="unset-network-id" />
100 <?php wp_nonce_field('powerpress', '_ppn_nonce'); ?>
101 <button type="submit" class="button ppn-button-danger"><?php esc_html_e('Unlink Network', 'powerpress');?></button>
102 </form>
103
104 <!-- CREATE/EDIT HOMEPAGE BUTTON-->
105 <?php if ($homepageExists): ?>
106 <a id="ppn-homepage-btn" class="button" href="<?php echo esc_url(get_edit_post_link($homepageId)); ?>" target="_blank"
107 style="display: <?php echo ($networkShowSearchResults ? 'none' : ''); ?>;">
108 <?php esc_html_e('Edit Home Page', 'powerpress'); ?>
109 </a>
110 <?php else: ?>
111 <button id="ppn-homepage-btn" type="button" class="button"
112 style="display: <?php echo ($networkShowSearchResults ? 'none' : ''); ?>;"
113 data-ppn-action="ppnPageAction" data-mode="singleton"
114 data-target="Homepage"
115 data-title="<?php echo esc_attr(get_option('powerpress_network_title')); ?>"
116 data-edit-label="<?php esc_attr_e('Edit Home Page', 'powerpress'); ?>">
117 <?php esc_html_e('Add Home Page', 'powerpress'); ?>
118 </button>
119 <?php endif; ?>
120
121 <button id="display-network-search" type="button" class="button" onclick="displayNetworkSearch();"
122 style="display: <?php echo ($networkShowSearchResults ? 'none' : 'block'); ?>;" >
123 <?php esc_html_e('Add Shows to Network', 'powerpress-network');?>
124 </button>
125 </div>
126 </div>
127
128 <!-- ============
129 SHOWS LIST
130 ============ -->
131
132 <div id="network-shows-list" style="display: <?php echo ($networkShowSearchResults ? 'none' : 'block'); ?>;">
133 <?php if(!empty($groups['internal']) || !empty($groups['external'])){ ?>
134 <div class="ppn-search">
135 <input type="text" class="ppn-search__input" placeholder="<?php esc_attr_e('Filter shows...', 'powerpress'); ?>"
136 data-ppn-action="filterList" data-ppn-target="ppn-programs-list">
137 <i class="material-icons-outlined ppn-search__icon">search</i>
138 </div>
139 <?php } ?>
140
141 <div class="ppn-list" id="ppn-programs-list">
142 <div class="ppn-list__header row">
143 <div class="col-8"><?php esc_html_e('Show', 'powerpress'); ?></div>
144 <div class="col-2"><?php esc_html_e('Show Page', 'powerpress'); ?></div>
145 <div class="col-2"><?php esc_html_e('Manage', 'powerpress'); ?></div>
146 </div>
147 <?php
148 $option = get_option('powerpress_network_map');
149 $list_props = $secondary_props;
150
151 $render_program = function($program) use ($option) {
152 $title = $program['program_title'] ?? 'n/a';
153 $programId = $program['program_id'] ?? 0;
154 $key = "p-{$programId}";
155 $link = (isset($option[$key]) && get_post_status($option[$key]) === 'publish') ? get_permalink($option[$key]) : null;
156 $pageMissing = isset($option[$key]) && !$link;
157 ?>
158 <div class="ppn-list__row row" data-title="<?php echo esc_attr(strtolower($title)); ?>">
159 <div class="col-8">
160 <?php echo esc_html($title); ?>
161 </div>
162 <div class="col-2">
163 <span class="ppn-list__label"><?php esc_html_e('Page', 'powerpress'); ?></span>
164 <?php if ($pageMissing){ // linked page no longer published (draft/trash) ?>
165 <span class="ppn-page-status">
166 <button type="button"
167 class="ppn-page-status--action"
168 data-ppn-action="ppnPageAction"
169 data-mode="list"
170 data-target="Program"
171 data-id="<?php echo esc_attr($programId); ?>"
172 data-title="<?php echo esc_attr($title); ?>">
173 <?php esc_html_e('Create Page', 'powerpress');?>
174 </button>
175 </span>
176 <?php } else if ($link === null){ // no page ever created ?>
177 <span class="ppn-page-status">
178 <button type="button"
179 class="ppn-page-status--action"
180 data-ppn-action="ppnPageAction"
181 data-mode="list"
182 data-target="Program"
183 data-id="<?php echo esc_attr($programId); ?>"
184 data-title="<?php echo esc_attr($title); ?>">
185 <?php esc_html_e('Create Page', 'powerpress');?>
186 </button>
187 </span>
188 <?php } else { ?>
189 <span class="ppn-page-status"><a class="ppn-page-status--linked" target="_blank" href="<?php echo esc_url($link);?>"><?php esc_html_e('View Page', 'powerpress');?></a></span>
190 <?php } ?>
191 </div>
192 <div class="col-2">
193 <?php if ($link !== null){ ?>
194 <button type="button" class="ppn-icon-btn" title="<?php esc_html_e('Change Page', 'powerpress');?>" data-ppn-action="editPageForProgram" data-program-id="<?php echo esc_attr($programId); ?>" data-program-title="<?php echo esc_attr($title); ?>" data-link-page="<?php echo esc_attr($option[$key]); ?>" data-ppn-dialog="selectPageBox"><i class="material-icons-outlined">edit</i></button>
195 <form method="POST" style="display:contents">
196 <input type="hidden" name="target" value="Program" />
197 <input type="hidden" name="targetId" value="<?php echo esc_attr($programId); ?>" />
198 <input type="hidden" name="redirectUrl" value="false" />
199 <input type="hidden" name="pageAction" value="unlink" />
200 <button type="button" class="ppn-icon-btn" title="<?php esc_html_e('Unlink Page', 'powerpress');?>" data-ppn-action="ppnAction" data-tab="programs" data-confirm="<?php echo esc_attr("Are you sure you want to unlink this page from {$title}?"); ?>"><i class="material-icons-outlined">link_off</i></button>
201 </form>
202 <?php } else { ?>
203 <button type="button" class="ppn-icon-btn" title="<?php esc_html_e('Link to Existing Page', 'powerpress');?>" data-ppn-action="editPageForProgram" data-program-id="<?php echo esc_attr($programId); ?>" data-program-title="<?php echo esc_attr($title); ?>" data-link-page="" data-ppn-dialog="selectPageBox"><i class="material-icons-outlined">edit</i></button>
204 <?php } ?>
205 <button type="button" class="ppn-icon-btn" title="<?php esc_html_e('Add to Group', 'powerpress');?>" data-ppn-action="addToGroup" data-program-id="<?php echo esc_attr($programId); ?>" data-ppn-dialog="addToGroup"><i class="material-icons-outlined">library_add</i></button>
206 <form method="POST" style="display:contents">
207 <input type="hidden" name="target" value="program" />
208 <input type="hidden" name="targetId" value="<?php echo esc_attr($programId); ?>" />
209 <input type="hidden" name="requestAction" value="delete" />
210 <input type="hidden" name="redirectUrl" value="false" />
211 <input type="hidden" name="changeOrCreate" value="true" />
212 <input type="hidden" name="pageAction" value="clearSiteCache" />
213 <input type="hidden" name="clearSiteCache" value="true" />
214 <button type="button" class="ppn-icon-btn" title="<?php esc_html_e('Delete Program', 'powerpress');?>" data-ppn-action="ppnAction" data-tab="programs" data-confirm="<?php echo esc_attr("Are you sure you want to remove '{$title}'?"); ?>"><i class="material-icons-outlined">delete</i></button>
215 </form>
216 </div>
217 </div>
218 <?php
219 };
220
221 if (!empty($groups['internal']) || !empty($groups['external'])) {
222 powerpress_render_list_section('internal', __('Internal Shows', 'powerpress'), $groups['internal'], $render_program);
223 powerpress_render_list_section('external', __('External Shows', 'powerpress'), $groups['external'], $render_program, false, __('No external shows yet.', 'powerpress'));
224 } else { ?>
225 <div class="row justify-content-center mt-4">
226 <h1 class="ppn-page-title"><?php esc_html_e('This Network is Empty', 'powerpress'); ?></h1>
227 </div>
228
229 <div class="row justify-content-center" style="margin-left: 20%; margin-right: 20%;">
230 <p><?php esc_html_e('A podcast network is a collection of shows managed under one umbrella, with shared branding, purpose, and often a unified strategy. While many organizations are starting to dip their toes into podcasting with a single show, networks offer flexibility, growth, and audience segmentation. With PowerPress you can host multiple shows under one account. Centralized control makes it simple to oversee multiple podcasts from one dashboard.', 'powerpress'); ?></p>
231 </div>
232
233 <div class="row justify-content-center mb-4">
234 <button id="display-network-search" type="button" class="button" onclick="displayNetworkSearch();">
235 <?php esc_html_e('Add Shows to Network', 'powerpress');?>
236 </button>
237 </div>
238 <?php } ?>
239 </div>
240
241 <!-- form lives outside dialog so values persist -->
242 <form method="POST" id="addForm">
243 <input id="add-program-to-group" name="program" type="hidden" />
244 <input id="group-for-program-add" name="list_id" type="hidden" />
245 <input name="requestAction" value="add" type="hidden">
246 </form>
247 </div>
248
249 <div id="network-search-for-shows" style="display: <?php echo ($networkShowSearchResults ? 'block' : 'none'); ?>;">
250 <form id="network-show-search-form" method="POST" action="<?php echo esc_url(admin_url("admin.php?page=" . urlencode(powerpress_admin_get_page()))); ?>">
251 <?php wp_nonce_field('powerpress', '_ppn_nonce'); ?>
252
253 <input type="hidden" name="networkId" value="<?php echo esc_attr($networkID); ?>"/>
254 <div class="ppn-network-search">
255 <div class="ppn-search ppn-network-search__bar">
256 <label for="network-show-search-input"></label>
257 <input id="network-show-search-input" type="text" class="ppn-search__input" name="search" value="<?php echo esc_attr($networkShowSearchValue); ?>"
258 placeholder="<?php esc_attr_e('Search for shows...', 'powerpress'); ?>">
259 <i id="network-show-search-submit" class="material-icons-outlined ppn-search__icon" style="cursor: pointer; pointer-events: auto;" onclick="submitNetworkShowSearch();">search</i>
260 </div>
261 <a href="<?php echo esc_url(admin_url("admin.php?page=" . urlencode(powerpress_admin_get_page()))); ?>" class="ppn-network-search__close">&times;</a>
262 </div>
263 </form>
264
265 <!-- =================================
266 SEARCH RESULTS / SUGGESTED SHOWS
267 ================================= -->
268 <div class="ppn-list p-4">
269 <?php if(empty($networkShowSearchResults) && empty($accountShowsNotInNetwork)){ ?>
270 <div class="ppn-empty-state">
271 <i class="material-icons-outlined ppn-empty-state__icon">podcasts</i>
272 <p class="ppn-empty-state__text"><?php esc_html_e('Search the Blubrry directory to find and add shows to your network.', 'powerpress'); ?></p>
273 </div>
274 <?php } ?>
275
276 <?php if(!empty($networkShowSearchResults) && !empty($searchValue)){ ?>
277 <h4 class="ppn-page-subtitle mb-3">SEARCH RESULTS: <?php echo esc_html($searchValue); ?></h4>
278
279 <div class="row">
280 <?php foreach($networkShowSearchResults as $show){
281 $title = htmlspecialchars($show['program_title']);
282 $name = htmlspecialchars($show['talent_name']);
283 $website = htmlspecialchars($show['program_htmlurl']);
284
285 $artwork = 'https://assets.blubrry.com/coverart/90/' . htmlspecialchars($show['program_itunes_image']);
286 $fallback = esc_url(powerpress_get_root_url() . 'images/pts_cover.jpg');
287 ?>
288
289 <div class="col-12 col-lg-6 mb-3">
290 <div class="row align-items-center">
291 <div class="col-1">
292 <img data-ppn-action="addProgramToNetwork"
293 data-program-id="<?php echo $show['program_id']; ?>"
294 data-network-id="<?php echo $networkID; ?>"
295 data-updated-src="<?php echo powerpress_get_root_url(); ?>images/circlecheck_blue.png"
296 data-title="<?php echo esc_attr($show['program_title']); ?>"
297 id="add-program-<?php echo $show['program_id']; ?>"
298 class="circle-add-to-network"
299 alt="Add to Network" src="<?php echo powerpress_get_root_url() . (isset($inNetworkIds[$show['program_id']]) ? 'images/circlecheck_blue.png' : 'images/circleplus.png'); ?>">
300 </div>
301
302 <div class="col-1 pr-0 pl-0">
303 <img class="results-coverart" src="<?php echo esc_url($artwork); ?>" onerror="this.onerror=null; this.src='<?php echo $fallback; ?>';" alt="Show Coverart">
304 </div>
305
306 <div class="col-10">
307 <div class="row pl-2">
308 <h3 class="m-0"><?php echo $title; ?></h3>
309 </div>
310 <div class="row pl-2">
311 <?php if($name){ ?>
312 <h4 class="m-0"><?php echo $name; ?></h4>
313 <?php } ?>
314 <?php if($website){ ?>
315 <a class="website-link" href="<?php echo $website; ?>" target="_blank"><?php echo $website; ?></a>
316 <?php } ?>
317 </div>
318 </div>
319 </div>
320 </div>
321 <?php } ?>
322 </div>
323 <?php } ?>
324
325
326 <?php if(!empty($accountShowsNotInNetwork)){ ?>
327 <h4 class="ppn-page-subtitle mb-3 mt-3">SUGGESTED SHOWS</h4>
328
329 <div class="row">
330 <?php foreach($accountShowsNotInNetwork as $show){
331 $title = htmlspecialchars($show['program_title']);
332 $name = htmlspecialchars($show['talent_name']);
333 $website = htmlspecialchars($show['program_htmlurl']);
334
335 $artwork = 'https://assets.blubrry.com/coverart/90/' . htmlspecialchars($show['program_itunes_image']);
336 $fallback = esc_url(powerpress_get_root_url() . 'images/pts_cover.jpg');
337 ?>
338
339 <div class="col-12 col-lg-6 mb-3">
340 <div class="row align-items-center">
341 <div class="col-1">
342 <img data-ppn-action="addProgramToNetwork"
343 data-program-id="<?php echo $show['program_id']; ?>"
344 data-network-id="<?php echo $networkID; ?>"
345 data-updated-src="<?php echo powerpress_get_root_url(); ?>images/circlecheck_blue.png"
346 data-title="<?php echo esc_attr($show['program_title']); ?>"
347 id="add-program-<?php echo $show['program_id']; ?>"
348 class="circle-add-to-network"
349 alt="Add to Network" src="<?php echo powerpress_get_root_url() . (isset($inNetworkIds[$show['program_id']]) ? 'images/circlecheck_blue.png' : 'images/circleplus.png'); ?>">
350 </div>
351
352 <div class="col-1 pr-0 pl-0">
353 <img class="results-coverart" src="<?php echo esc_url($artwork); ?>" onerror="this.onerror=null; this.src='<?php echo $fallback; ?>';" alt="Show Coverart">
354 </div>
355
356 <div class="col-10">
357 <div class="row pl-2">
358 <h3 class="m-0"><?php echo $title; ?></h3>
359 </div>
360 <div class="row pl-2">
361 <?php if($name){ ?>
362 <h4 class="m-0"><?php echo $name; ?></h4>
363 <?php } ?>
364 <?php if($website){ ?>
365 <a class="website-link" href="<?php echo $website; ?>" target="_blank"><?php echo $website; ?></a>
366 <?php } ?>
367 </div>
368 </div>
369 </div>
370 </div>
371 <?php } ?>
372 </div>
373 <?php } ?>
374 </div>
375 </div>
376
377 <!-- ====================
378 ADD TO GROUP DIALOG
379 ==================== -->
380
381 <dialog id="addToGroup" class="ppn-dialog ppn-dialog--sm">
382 <button type="button" class="ppn-dialog__close" data-ppn-action="ppnDialogClose" aria-label="<?php esc_attr_e('Close', 'powerpress'); ?>"><i class="material-icons-outlined">close</i></button>
383 <h4 class="ppn-manage__field-label" style="margin-top: 0;"><?php esc_html_e('Select a Group', 'powerpress'); ?></h4>
384 <?php if (empty($list_props)) { ?>
385 <p class="description"><?php esc_html_e('No groups yet. Create a group first.', 'powerpress'); ?></p>
386 <?php } else { ?>
387 <?php foreach ($list_props as $list) { ?>
388 <div class="ppn-group-pick">
389 <a href="" data-ppn-action="ppnAction" data-form="addForm" data-tab="programs" data-set-field="group-for-program-add" data-set-value="<?php echo esc_attr($list['list_id']); ?>" data-change="true"><?php echo esc_html($list['list_title']); ?></a>
390 </div>
391 <?php } ?>
392 <?php } ?>
393 <div class="ppn-dialog__actions">
394 <button type="button" class="button" data-ppn-action="ppnDialogClose"><?php esc_html_e('Cancel', 'powerpress'); ?></button>
395 </div>
396 </dialog>
397
398 <script>
399 function displayNetworkSearch(){
400 let networkShowsList = document.getElementById('network-shows-list');
401 let networkSearchForShows = document.getElementById('network-search-for-shows');
402 let addShowsToNetworkBtn = document.getElementById('display-network-search');
403 let returnLink = document.getElementById('return-to-shows-list');
404 let homepageBtn = document.getElementById('ppn-homepage-btn');
405
406 if(networkShowsList.style.display !== 'none'){ // if shows list is displayed
407 // hide shows list, and display network search
408 networkShowsList.style.display = 'none';
409 networkSearchForShows.style.display = 'block';
410 addShowsToNetworkBtn.style.display = 'none';
411 if (homepageBtn) homepageBtn.style.display = 'none';
412 returnLink.style.display = 'inline-block';
413
414 } else { // if network search is displayed
415 // hide network search, and display shows list
416 networkSearchForShows.style.display = 'none';
417 networkShowsList.style.display = 'block';
418 addShowsToNetworkBtn.style.display = 'block';
419 if (homepageBtn) homepageBtn.style.display = '';
420 returnLink.style.display = 'none';
421 }
422 }
423
424 function submitNetworkShowSearch(){
425 let searchForm = document.getElementById('network-show-search-form');
426 let searchValue = document.getElementById('network-show-search-input');
427
428 if(searchValue.value !== ''){
429 searchForm.submit();
430 }
431 }
432 </script>
433
434 <!-- ====================
435 PAGE SELECT DIALOG
436 ==================== -->
437
438 <?php
439 $availablePages = get_pages();
440 powerpress_render_network_page_select([
441 'form_id' => 'changeForm',
442 'select_id' => 'page-select-ppn',
443 'shortcode_id' => 'ppn-program-shortcode',
444 'target' => 'Program',
445 'target_id_attr' => 'select-page-target-id',
446 'pages' => $availablePages,
447 ]);
448 ?>
449