Warning: chmod(): Operation not permitted in /var/www/hopeinstoughton_www/wp-content/plugins/simple-universal-google-analytics/main.php on line 8
[0] in function chmod in /var/www/hopeinstoughton_www/wp-content/plugins/simple-universal-google-analytics/main.php on line 8
[1] in function include_once in /var/www/hopeinstoughton_www/wp-settings.php on line 560
[2] in function require_once in /var/www/hopeinstoughton_www/wp-config.php on line 85
[3] in function require_once in /var/www/hopeinstoughton_www/wp-load.php on line 50
[4] in function require_once in /var/www/hopeinstoughton_www/wp-blog-header.php on line 13
[5] in function require in /var/www/hopeinstoughton_www/index.php on line 17
403WebShell
403Webshell
Server IP : 94.177.8.99  /  Your IP : 216.73.217.165
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux aries 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64
User : www-data ( 33)
PHP Version : 8.1.34
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/hopeinstoughton_www/wp-content/plugins/video-archive/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/hopeinstoughton_www/wp-content/plugins/video-archive/video-archive.php
<?php

/*
Plugin Name: Video Archive
Plugin URI: http://hostz.org/
Description: Videos over the last 14 years
Version: 1.0.0
Author: Phil Young
Author URI: http://hostz.org/
License: Whatever
*/

class video_archive_class {

// jsTree 1.0-rc3 has problems with [dicarding] spaces on input fields - with the hotkeys plugin - .bind("keydown", "space", function (e) {
// the latest version, 3.2.1 does not appear to work with our data

    const EXHORT = 364;

	private $x_poster = NULL;

	function __construct() {
		add_action('wp_enqueue_scripts', array($this, 'add_css' ));
		add_action('admin_enqueue_scripts', array($this, 'add_css' ));
		add_shortcode('videoplayer', array($this, '_shortcode_handler' ));
		add_shortcode('video_list', array($this, '_shortcode_handler_list' ));
		add_shortcode('videoduration', array($this, '_shortcode_handler_total' ));
		add_shortcode('currentservice', [$this, '_shortcode_handler_current' ]);
		add_shortcode('memorialservice', [$this, '_shortcode_handler_memorial' ]);

		add_action( 'wp_loaded', array($this, 'check_thumbnail') );
		add_filter( 'wp_video_shortcode', array($this, '_add_cross_origin'), 10, 5);
		add_action( 'wp_ajax_videoarchive', [$this, '__videodetails'] );
		add_action( 'wp_ajax_nopriv_videoarchive', [$this, '__videodetails'] );
		$this->includedir = ABSPATH . 'file_up/inc';
		$this->DATA = NULL;
	}

	// get current sunday service, but if missing locate previous sunday
	static
	public function getLastSundayService($thumb = FALSE) {
		// if today is not a sunday, get last sunday
		$dow = date('w') + 0;
		$sunday = time();
		if ($dow > 0) $sunday -= $dow * 86400;
		$limit = 4;

		do {
			// do we have sunday stuff?
			$date = date('Y.m.d', $sunday);
			$auth = MediaSource::GenerateServiceAuth($date);
				
			$curl = new WP_Http_Curl;
			$args = [
				'redirection' => 5,
				'user-agent' => '',
				'stream' => FALSE,
				'filename' => '',
				'decompress' => TRUE,
				'_redirection' => 5,
			];
			// from the media site, get the names of the names of the vtt, jpeg and mp4 files
			//    and return the json for the specified day
			//	  if we have a xml file, but not a json, convert it
			//  but if it is today, and data missing, return last weeks instead
			$uri = 'https://media.hopeinstoughton.org/service-info/' . $auth;
			$uri .= '?thumb=' . ($thumb ? 1 : 0);
			$response = $curl->request($uri, $args);
			if (is_a($response, 'WP_Error')) {
				$current =  [
					'error' => 'Unable to find display content' ,
					'media' => [],
				];
			} else {
				$current = json_decode($response['body'], TRUE);
			}	
			$limit--;
			$ok = count($current['media'] ?? []);
			if (!$ok) $sunday -= 7 * 86400;
			if ($limit < 0 && !$ok) {
				return FALSE;		// nothing found
			};
		} while (!$ok);
		return [
			'date' => $date,
			'speaker' => $current['speaker'],
			'thumb'	=> 'https://media.hopeinstoughton.org/service/' . $auth . '/' . $date . '.60.jpg',
		];
	}

	function _add_cross_origin( $html, $atts, $video, $post_id, $library ) {
		$html = str_replace('<video', '<video crossorigin="anonymous"', $html);
		if (strpos($html, 'http://localhost/') !== FALSE) {			// 
			$html = str_replace('http://localhost/', $this->x_poster, $html);
		}
		return $html;
	}
	
	function _loaddata() {
		if ($this->DATA === NULL) {
			$this->DATA = $this->_getClips();
		}
	}

	function check_thumbnail() {
		$cache = $_SERVER['REQUEST_URI'];
		if (preg_match('~^/thumbnail/(\d+)[:_-](\d+)$~', $cache, $matches)) {
			$name = substr($matches[1], 0, 4) . '.' . substr($matches[1], 4, 2) . '.' . substr($matches[1], 6, 2);
			$this->DisplayThumbnail($name . '_' . $matches[2]);
			exit;
		}
		if (preg_match('~^/thumbnail/(\d+)\.(\d+)\.(\d+)[:_-](\d+)$~', $cache, $matches)) {
			$name = $matches[1] . '.' . $matches[2] . '.' . $matches[3];
			$this->DisplayThumbnail($name . '_' . $matches[4]);
			exit;
		}
	}
	
	function DisplayThumbnail($filename) {
		$filename = $this->includedir . '/../media/' . $filename . '.jpg';
		if (!file_exists($filename)) {
			header('Content-type: text/plain');
			echo "Thumbnail not available - $filename\n";
			return;
		}

		header('Content-type: image/jpeg');
		readfile($filename);
	}

	function _shortcode_handler($atts) {
		$this->_loaddata();
		$output = '';
		$filename = isset($atts['file']) ? trim($atts['file']) : '';
		$poster = isset($atts['poster']) ? trim($atts['poster']) : '';
		$src = isset($atts['src']) ? trim($atts['src']) : '';
		$title = isset($atts['title']) ? trim($atts['title']) : '';
		$width = isset($atts['width']) ? intval($atts['width']) : 0;
		$height = isset($atts['height']) ? intval($atts['height']) : 0;
		$order = isset($atts['order']) ? strtolower(trim($atts['order'])) : '';
        $cc = empty($atts['cc']) ? '' : $atts['cc'];
		if (!$width) $width = 720;
		if (!$height) $height = 480;
		$this->order = $order;		// remember the setting for the video_list 
		
		if ($title != '') $output .= '<h3>' . $title . '</h3>';
		$xfilename = str_replace(array('/', '.'), '-', $filename);
		$date = preg_match('~\d{4}-\d{2}-\d{2}~', $xfilename, $match) ? $match[0] : '';
		if ($date != '') {
			$dt = strtotime($date);
			$date = date('l, F j, Y', $dt);
		}
		if ($order == 'date') {
			$this->PrepareDateOrder();
			return $this->display_archive_item($width, $height);
		}
		if ($order == 'speaker') {
			$this->PrepareSpeakerOrder();
			return $this->display_archive_item($width, $height);
		}

		$prefix = (($p = strpos($filename, '/')) !== FALSE) ? substr($filename, 0, $p) : '';
		if ($prefix == 'exhort' || $prefix == 'classes' || $prefix == 'current' || $prefix == 'other') {
			$base = '/av/' . dirname($filename);
		} else {
			$base = "https://biblealive.us/video/$prefix";		// this does not exist
		}
		$filename = rawurlencode(basename($filename));
        if ($cc != '') {
			$cc = str_replace('*', $base, $cc);
            $content = '<track srclang="en" label="English" kind="subtitles" src="' . $cc .'" />';
        } else {
            $content = '';
        }
        if ($poster == '') $poster = "$base/{$filename}.jpg";
        if ($src == '') $src = "$base/{$filename}.mp4";
		$attr = [
			'width'  => $width,
			'height' => $height,
			'mp4'    => $src,
			'poster' => $poster,
		];
		$output .= wp_video_shortcode($attr, $content);
		
		if ($date != '') $output .= "<p>$date</p>";
		return $output;
	}
    
    private function __AsSpeaker($item) {
        $value = trim($item->ms_lastname . ', ' . $item->ms_firstname);
        if (!empty($item->ms_suffix)) $value .= ', ' . $item->ms_suffix;
        return $value;
    }

	function display_archive_item($width, $height) {
		if (!empty($_GET['video-id'])) {		// this will only accepts items of type 'ex'
			$this->CURRENT = $_GET['video-id'];
			$mediaitem = media_manager_class::Load($_GET['video-id']);
			if (is_object($mediaitem) && $mediaitem->mi_type != 'ex') {
				$mediaitem = NULL;
			}
		} else {
			// is this from the new system?
			$mediaitem = media_manager_class::Load($this->CURRENT);
		}
		$active = $this->AsSpeaker($this->CURRENT, 1);		// full version - with speaker deets
		$thmb = str_replace(':', '-', $active['g']);
		$attr = [
			'width' => $width,
			'height' => $height,
			'mp4' => "https://media.hopeinstoughton.org/av/exhort/video/{$active['f']}",
			'poster' => "/thumbnail/{$thmb}",
		];
        if (is_object($mediaitem)) {
            $mi_id = $mediaitem->mi_id;
            $attr['poster'] = apply_filters('mm_generate_link', '', $mi_id, $mi_id. '.jpg', $mediaitem->present_jpg);
            $attr['mp4'] = apply_filters('mm_generate_link', '', $mi_id, $mi_id. '.mp4', $mediaitem->present_mp4);
            if ($mediaitem->present_vtt) {
                $active['v'] = apply_filters('mm_generate_link', '', $mi_id, $mi_id. '.vtt', $mediaitem->present_vtt);
                $active['cc'] = 1;
                if (strpos($active['v'], '?') === FALSE) {
                    $active['v'] .= '?short=1';
                } else {
                    $active['v'] .= '&short=1';
                }

            }
            // $active['s'] is the summary - speaker, date, duration, qrcode
			// $active['sh']  is the shareable barcode
        }
        $content = '';
        if ($active['cc']) {		// closed captions present
            $content = '<track srclang="en" label="English" kind="subtitles" src="' . $active['v'] .'" />';
        }
		$video = wp_video_shortcode($attr, $content);
		return <<<BLOCK
{$video}
<div class="video-table">
	<div class="video-row">
		<div class="video-column col1">
		{$active['s']}
		</div>
		<div class="video-column col2">
			<div class="videoupdate-container">
			{$active['sh']}
			</div>
		</div>
	</div>
</div>
<div class="xp-transcript" style="display:none;margin-bottom:30px">
<h3>Transcript</h3>
<span id="transcription"></span>
</div>

BLOCK;

	}

	function add_css() {
		wp_enqueue_style('video_archive', plugins_url('video-archive.css', __FILE__), [], '1.1'); 

		// add .js files
		wp_enqueue_script('video_archive_3', plugins_url('video-archive.js', __FILE__), ['jquery'], '1.0.7' );
		wp_enqueue_script('video_archive_4', plugins_url('jquery.cookie.js', __FILE__), [], '' );
//		wp_enqueue_script('video_archive_5', plugins_url('jquery.hotkeys.js', __FILE__), [], '' );
		wp_enqueue_script('video_archive_6', plugins_url('jquery.jstree.js', __FILE__), [], '3.2.1' );
		wp_localize_script('video_archive_3', 
		  'video_archive',
		  array(
			'ajaxurl' => admin_url('admin-ajax.php'),
		  )
		);
	}

	function PrepareDateOrder() {
		uasort($this->DATA, [$this, 'descendingsort']);
		$this->TREE = []; 
		$last = -1;
		$this->CURRENT = NULL;
		foreach($this->DATA as $key => $item) {
			list($tyy, $tmm, $tdd) = explode('.', $item['date']);
			$yy = intval($tyy, 10); $mm = intval($tmm, 10);
			$this->TREE[$yy][$mm][] = $key;
			$current = $yy * 12 + $mm;
			if ($current > $last) {	// make a note of the last speaker
				$last = $current;
				$this->CURRENT = $key;
			}
		}

	}

	function PrepareSpeakerOrder() {
		uasort($this->DATA, [$this, 'descendingsort']);
		$this->TREE = array(); 
		$last = -1;
		$this->CURRENT = NULL;
		foreach($this->DATA as $key => $item) {
			$item = $this->DATA[$key];
			$name = trim($item['n']);
			$this->TREE[$name][] = $key;
		}
		ksort($this->TREE);
// get first one
		reset($this->TREE);
		$name = key($this->TREE);
		$this->CURRENT = $this->TREE[$name][0];
	}
	
	function _shortcode_handler_list($atts) {
		$this->_loaddata();
		$order = $this->order ?? '';
		if ($order == '') {
			return '';
		} elseif ($order == 'date' || $order == 'speaker') {
			$ly = ''; $lm = 0;
			$active = array('y' => '', 'm' => '', 'f' => '', 's' => '<span id="summary"></span>');
			if ($this->order == 'date') {
				$treehtml = $this->GenerateTree($active);
			} else {
				$treehtml = $this->GenerateTree_Speaker($active);
			}
			$first = '"' . $active['y'] . '", "' . $active['m'] . '"';
			$javascript = <<<BLOCK
<script type="text/javascript">
	let $ = jQuery.noConflict();
	$('#vidnav').jstree({
		"types" : { 
			"types" : { 
				"default" : { 
					"select_node" : function(e) {
										this.toggle_node(e);
										return false;
									} 
				}
			} 
		 },
		 "themes": {
			"theme": "default",
			"url":"/wp-content/plugins/video-archive/style.css",
		},
		 // the `plugins` array allows you to configure the active plugins on this instance
		"plugins" : ["themes","html_data","types","ui","crrm"],
		"core" : { "initially_open" : [ $first ], html_titles : true }
	});
	videoarchive_service();
</script>
BLOCK;

			return $treehtml. $javascript;
//		"plugins" : ["themes","html_data","types","ui","crrm","hotkeys"],
		}		
		return '(unknown)';
	}
	
	function descendingsort($a, $b) {
        return strcasecmp($b['date'], $a['date']);
	}

	function AsSpeaker($entry, $full = 0) {
		global $SHAREABLE, $MEDIASEARCH;
		$item = $this->DATA[$entry];		// $entry => hash
		list($tyy, $tmm, $tdd) = explode('.', $item['date']);
//        $event = $item['e'];
		
		$base = rawurlencode($item['base']);
		$cc = empty($item['cc']) ? '' : ' ccap';
		$dname = htmlspecialchars($item['n']);
		$param = "class=\"videoselect$cc\"";

        $dentry = isset($item['id']) ? $item['id'] : $entry;
		if ($full == 2) {
			$dt = strtotime("$tyy-$tmm-$tdd 12:00");
			$desc = date('F j, Y', $dt);
			return "<li id=\"$dentry\"><a href=\"#\" $param>{$desc}</a></li>";
		}
		if ($full) {
			
			$first = [];
			$first['cc'] = $item['cc'];
			$first['f'] = $base . '.mp4';
			$first['g'] = $entry;
//			$first['v'] = "/av/exhort/vtt/{$base}.vtt";
			$first['sh'] = '';
			$first['s'] = <<<BLOCK
<span id="summary">Speaker: <b>{$dname}</b><br>
Date: <b>$tmm/$tdd/$tyy</b><br>
Duration: <b>{$item['len']}</b><br>
	<span class="bind-service" data-dt="{$item['date']}" data-dt="{$item['date']}"  data-tp="{$item['e']}"></span>
</span>

BLOCK;
//Audio: <a href="https://media.hopeinstoughton.org/av/exhort/audio/{$base}.mp3">download mp3</a></span>
            if (isset($SHAREABLE) && is_object($SHAREABLE)) {
                $node = [
                    'date' => '',
                    'e' => 0,
                    'id' => $item['id'],
                ];
                $first['sh'] = $SHAREABLE->asQRcode($node);
            }
			if (isset($MEDIASEARCH) && is_object($MEDIASEARCH)) {
				$MEDIASEARCH->ActiveHash($entry);
			}

			return $first;
		}
		return "<li id=\"{$dentry}\"><a href=\"#\" $param>$tdd. {$item['n']}</a></li>";
	}
	
	function GenerateTree(&$first) {
		$monthnames = array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
		$output = '';
		foreach($this->TREE as $year => $yeardata) {
			$yeartext = '';
			$yearcount = 0;
			foreach($yeardata as $month => $monthdata) {
				$monthtext = '';
				$monthcount = 0;
				foreach($monthdata as $entry) {
					$line = $this->AsSpeaker($entry, 0);
					$monthtext .= $line;
					$yearcount++; $monthcount++;
				}
				$temp = $monthnames[$month - 1];
				$monthtext = "<li id=\"y$year.$month\" style=\"display:none\"><a href=\"#\">$temp <span>($monthcount)</span></a><ul>" . $monthtext . "</ul></li>";
				if ($first['m'] == '') $first['m'] = "y$year.$month";
				$yeartext .= $monthtext;
			}
			$output .= "<li id=\"y$year\"><a href=\"#\">$year <span>($yearcount)</span></a><ul>" . $yeartext . "</ul></li>";
			if ($first['y'] == '') $first['y'] = "y$year";
		}
		return "<div id=\"vidnav\"><ul>{$output}</ul></div>";
	}

	function GenerateTree_Speaker(&$first) {
		$output = '';
		foreach($this->TREE as $speaker => $entries) {
			$speakertext = '';
			foreach($entries as $entry) {
				$line = $this->AsSpeaker($entry, 2);
				$speakertext .= $line;
			}
			$count = count($entries);
			$dspeaker = htmlspecialchars($speaker);
			$m = crc32($speaker);
			$output .= "<li id=\"y$m\"><a href=\"#\">$dspeaker <span>($count)</span></a><ul>" . $speakertext . "</ul></li>";
			if ($first['y'] == '') $first['y'] = "y$m";
		}
		return "<div id=\"vidnav\"><ul>{$output}</ul></div>";
	}
	
	private function _videodetails_programEntry($program, $type) {
		foreach($program as $item) {
			if ($item['type'] == $type) return $item;
		}
		return NULL;
	}

    static
    private function asHMS($duration) {
		$hours = floor($duration / 3600);
		$duration %= 3600;
		$duration = sprintf('%d:%02d:%02d', $hours, floor($duration / 60), $duration % 60);
        return $duration;
    }

	public function __videodetails() {
		global $wpdb;
		$service = trim($_POST['service'] ?? '');
		$id =  trim($_POST['id'] ?? '');

		$node = [];
		if ($service != '') {

			$auth = MediaSource::GenerateServiceAuth($service);
			$curl = new WP_Http_Curl;
			$args = [
				'redirection' => 5,
				'user-agent' => '',
				'stream' => FALSE,
				'filename' => '',
				'decompress' => TRUE,
				'_redirection' => 5,
			];
			// from the media site, get the names of the names of the vtt, jpeg and mp4 files
			//    and return the json for the specified day
			//	  if we have a xml file, but not a json, convert it
			//  but if it is today, and data missing, return last weeks instead
			$uri = 'https://media.hopeinstoughton.org/service-info/' . $auth;
			$response = $curl->request($uri, $args);
			if (is_a($response, 'WP_Error')) {
				$node['error'] = 'Unable to find display content';
			} else {
				$current = json_decode($response['body'], TRUE);
				if (isset($current['media'])) {
					$media = $current['media'];
					$mp4 = $media['mp4'] ?? '';
					
					$program = $current['program'];
					$entry = $this->_videodetails_programEntry($program, 30);
					if (!is_null($entry)) {		// add reading
						$node['ref'] = $entry['title'];
						$node['ref_start'] = static::asHMS($entry['mark_in']);
					}
					if ($mp4 == $service . '.mp4') {
						$node['link'] = '/members/memorial-service/?date=' . $service;
						// add reading link
					}
				}
				$tp = intval($_POST['e'] ?? '0');
				if ($tp && isset($current['transcript'][$tp])) {
						// add transcription
					$node['transcript'] = $current['transcript'][$tp];
				}
			}
			
		} elseif ($id != '') {

			$info = $this->_getClips($id);
			reset($info);
			$id = key($info);
			$node = $info[$id];

			$mediaitem = media_manager_class::Load($id);
			if (is_object($mediaitem)) {
				$mi_id = $mediaitem->mi_id;
				$node['poster'] = apply_filters('mm_generate_link', '', $mi_id, $mi_id. '.jpg', $mediaitem->present_jpg);
				$node['mp4'] = apply_filters('mm_generate_link', '', $mi_id, $mi_id. '.mp4', $mediaitem->present_mp4);
				if ($mediaitem->present_vtt) {
					$node['cap'] = apply_filters('mm_generate_link', '', $mi_id, $mi_id. '.vtt', $mediaitem->present_vtt);
					$node['cc'] = empty($node['cap']) ? 0 : 1;
					if (strpos($node['cap'], '?') === FALSE) {
						$node['cap'] .= '?short=1';
					} else {
						$node['cap'] .= '&short=1';
					}

				}
				$dt = str_replace('.', '', $node['date']);
				$node['type'] = $mediaitem->mixe_sequence == $dt ? 60 : 100;
			}
	//		$node['sql'] = $sql;
			unset($node['dur']);
		}
		
		header('Content-type: application/json');
		die(json_encode($node,  JSON_UNESCAPED_SLASHES));
	}

	function _shortcode_handler_total($atts) {
		$this->_loaddata();
		$totalduration = 0;
		foreach($this->DATA as $key => $item) {
			$totalduration += $item['dur'];
		}
		$hours = intval(($totalduration / 60 / 60) * 10) / 10;
		return $hours;
	}

	// display specific service
	public function _shortcode_handler_memorial($atts) {
		$date = $_GET['date'] ?? '';
		if ($date == '') {
			// get the last sunday, or today, if it is a sunday
			$now = time();
			[$yy, $mm, $dd, $dow] = explode(',', date('Y,n,j,w', $now));
		} else {
			if (strpos($date, '.') === FALSE) {
				$now = $date * 86400 + 43200;
			} else {
				[$yy, $mm, $dd] = explode('.', $date);
				$now = mktime(12, 0, 0, intval($mm, 10), intval($dd, 10), $yy);
			}
			$dow = date('w', $now);
			if ($dow) {
				echo "<hr style=\"margin-top:60px\"><h4>Invalid Date Specified</h4><hr style=\"margin-bottom:60px\">";
				return;
			}
		
		}
		
		$now -= $dow * 86400;
		$date = date('Y.m.d', $now);
		$dow = date('w', $now);
		// create an authentication code
		$auth = MediaSource::GenerateServiceAuth($date);
		
		$curl = new WP_Http_Curl;
		$args = [
			'redirection' => 5,
			'user-agent' => '',
			'stream' => FALSE,
			'filename' => '',
			'decompress' => TRUE,
			'_redirection' => 5,
		];
		// from the media site, get the names of the names of the vtt, jpeg and mp4 files
		//    and return the json for the specified day
		//	  if we have a xml file, but not a json, convert it
		//  but if it is today, and data missing, return last weeks instead
		$uri = 'https://media.hopeinstoughton.org/service-info/' . $auth;
		$response = $curl->request($uri, $args);
		if (is_a($response, 'WP_Error')) {
			echo "<p>Unable to display content</p>";
			return;
		}
		// thumbnail and cc timeout = 60s;  mp4 = 1.5hr
		$current = json_decode($response['body'], TRUE);
//		echo '<pre>' . htmlspecialchars(var_export($current, 1)) . '</pre>';

		$url = "https://media.hopeinstoughton.org/service/{$auth}/";
		$title = date('F j, Y', $current['date']) . ': ' . $current['speaker'];
		$current['title'] = $title;
		
		$param = [
			'src'  => $url . $current['media']['mp4'],
			'title' => $title,
			'width' => 900,
			'height' => 506,
		];
		$sourcevtt = $current['media']['vtt'] ?? '';
		if ($sourcevtt != '') {
			$param['cc'] = $url . $sourcevtt;
		}
		$sourcevtt = $current['media']['jpg'] ?? '';
		$this->x_poster = NULL;
		if ($sourcevtt != '') {
			$param['poster'] = $url . $sourcevtt;
		} elseif (isset($current['thumb'])) {
			$param['poster'] = 'http://localhost/';
			$this->x_poster = 'data:image/jpeg;base64,' . $current['thumb'];
		}
		$player = $this->_shortcode_handler($param) 
				. $this->_current_footer_text($current);
		echo $player;
	}
	
	private function _current_footer_text($current) {
		$program = $extras = $player = '';
		foreach($current['program'] as $item) {
			if (empty($item['category'])) continue;
			$line = "<a href=\"#\" class=\"audio-waypoint\" data-ts=\"{$item['mark_in']}\">{$item['title']}</a>";
			if ($item['category'] == 'X') {
				if (!empty($item['subtitle'])) {
					$line .= '<em> — ' . $item['subtitle'] . '</em>';
				}
				$extras .= '<li class="notag">' . $line . '</li>';
			} elseif ($item['category'] != 'P') {
				if (!empty($item['subtitle'])) {
					$line .= '<em> — ' . $item['subtitle'] . '</em>';
				} elseif (!empty($item['first'])) {
					$line .= '<em> — "' . $item['first'] . '"</em>';
				}
				$program .= '<li class="notag">' . $line . '</li>';
			}
		}
		$player .= <<<BLOCK
<h3>Program</h3>
<ul>$program</ul>

BLOCK;
		if ($extras != '') {
			$player .= <<<BLOCK
<h3>Extras</h3>
<ul>$extras</ul>

BLOCK;
		}
		return $player;

	}

	// display current service
	public function _shortcode_handler_current($atts) {
		$x = static::getLastSundayService();
		if ($x !== FALSE) {
			$_GET['date'] = $x['date'];
			return $this->_shortcode_handler_memorial($atts);
		}
		return '';
	}

	private function _getClips($id = NULL) {
		global $wpdb;
        $num = static::EXHORT;
        if (is_null($id)) {
            $where = "mi_type=\"ex\" and mixe_event=$num";
        } else {
            $did = '"' . esc_sql($id) . '"';
            $where = "mi_id=$did";
        }
        
        $sql = <<<BLOCK
select mixe_item,mi_date,mixe_sequence,
    present_vtt,
    ms_firstname,ms_lastname,ms_suffix,
    max(m.mm_duration) as duration,
    max(m.mm_filesize) as filesize,
    max(m.mm_framesize) as framesize
  from `mm_item_x_event` as x
    inner join `mm_item` as i on x.mixe_item = i.mi_id
    left join mm_speaker as s on s.ms_id = i.mi_speaker
    left join mm_media as m on m.mm_hash = x.mixe_item and m.mm_type="mp4"
where not m.mm_source is NULL and $where
group by x.mixe_item

BLOCK;
		$result = [];
        $items = $wpdb->get_results($sql);
        foreach($items as $item) {
            $this_node = $this->_node($item);
            $result[$item->mixe_item] = $this_node;
        }
		return $result;
	}

	private function _node($item) {
		global $SHAREABLE;

        $item->x_date = str_replace('-', '.', $item->mi_date);
        unset($item->mi_other);
        list($yy,$mm,$dd) = explode('.', $item->x_date);
        $yy = intval($yy);
        $mm = intval($mm, 10);
        $dd = intval($dd, 10);
        $sequence = $yy * 10000 + $mm * 100 + $dd;
        $e = ($item->mixe_sequence == $sequence) ? 60 : 100;
        
        $date = $item->x_date;
        $dur = empty($item->duration) ? 0 : $item->duration;

        $name = trim($item->ms_firstname . ' ' . $item->ms_lastname);
        if (!empty($item->ms_suffix)) {
            $name .= ' ' . ucfirst($item->ms_suffix);
        }
        $node = [
            'id' => $item->mixe_item,
            'e' => $e,
            'date' => $date,
            'n' => $this->__AsSpeaker($item),
            'cc' => (int) $item->present_vtt ? 1 : 0,
            'dim' => empty($item->framesize) ? '1280x720' : $item->framesize,
            'dur' => (int) $dur,
            'len' => intval($dur / 60) . ':' . sprintf('%02d', ($dur % 60)),
            'base' => "{$date} {$name}",
        ];

		// if the Shareable module is loaded, create the shareable hashes
        if (isset($SHAREABLE) && is_object($SHAREABLE)) {
            $node['hash'] = $SHAREABLE->AddHash($node);
        }
		//}
		return $node;
	}
    
}

new video_archive_class();

Youez - 2016 - github.com/yon3zu
LinuXploit