'Video Title', 'value' => 'v.title' ), array( 'text' => 'Video Description', 'value' => 'v.description' ), array( 'text' => 'Channel Name', 'value' => 'c.name' ), array( 'text' => 'Channel Description', 'value' => 'c.description' ), array( 'text' => 'Video ID', 'value' => 'v.id' ), array( 'text' => 'Video Filename', 'value' => 'v.filename' ), ); public function getTags() { return array( PluginTags::$RECOMMENDED, PluginTags::$FREE ); } public function getDescription() { return "Finetune the layout and helpers"; } public function getName() { return "Layout"; } public function getPluginVersion() { return "1.1"; } public function getUUID() { return "layout84-8f5a-4d1b-b912-172c608bf9e3"; } public function getEmptyDataObject() { global $global; $obj = new stdClass(); /* $variablesFile = $global['systemRootPath'] . 'plugin/Customize/sass/variables.scss'; $subject = file_get_contents($variablesFile); $o = new stdClass(); $o->type = "textarea"; $o->value = $subject; $obj->colorsVariables = $o; $obj->showCustomCSS = true; * */ //$obj->showButtonNotification = false; $obj->showSearchOptionsBelowNavbar = false; $obj->categoriesTopButtons = false; $obj->categoriesTopButtonsShowOnlyOnFirstPage = true; $obj->categoriesTopButtonsShowVideosCount = false; $obj->categoriesTopButtonsFluid = true; $obj->categoriesTopLeftMenu = true; $obj->enableAccessibility = false; $obj->canToogleDarkAndLightMode = false; $o = new stdClass(); $o->type = array(0 => '-- ' . ("Random")) + self::getLoadersArray(); $o->value = 'avideo'; $obj->pageLoader = $o; return $obj; } static function getLoadersArray() { $files = Layout::getLoadersFiles(); $response = array(); foreach ($files as $key => $value) { $response[$value['name']] = ucfirst($value['name']); } return $response; } static function getLoadersFiles() { global $global; $files = _glob($global['systemRootPath'] . 'plugin/Layout/loaders/', '/.*html/'); $response = array(); foreach ($files as $key => $value) { $name = str_replace('.html', '', basename($value)); $response[$name] = array('path' => $value, 'name' => $name); } return $response; } static public function getLoader($file) { global $global; $files = self::getLoadersFiles(); $name = ''; if (!empty($file)) { foreach ($files as $key => $value) { if ($file == $value['name']) { $name = $value['name']; break; } } } if (empty($name)) { $rand_key = array_rand($files); $name = $files[$rand_key]['name']; } $content = file_get_contents($global['systemRootPath'] . 'plugin/Layout/loaders/' . $name . '.html'); return trim(preg_replace('/\s+/', ' ', str_replace('lds-', 'lds-' . uniqid(), $content))); } static function getLoaderDefault() { global $_getLoaderDefault; if (!isset($_getLoaderDefault)) { $obj = AVideoPlugin::getObjectData('Layout'); $loader = Layout::getLoader($obj->pageLoader->value); //$loader = Layout::getLoader('spinner'); $parts = explode('', $loader); if (preg_match('/style/', $parts[0])) { $parts[0] .= ''; } $_getLoaderDefault = array('css' => $parts[0], 'html' => $parts[1]); } return $_getLoaderDefault; } static function getBGAnimationFiles() { global $global; $files = _glob($global['systemRootPath'] . 'plugin/Layout/animatedBackGrounds/', '/.*php/'); $response = array(); foreach ($files as $key => $value) { $name = basename($value); if ($name === 'index.php') { continue; } $name = str_replace('.php', '', $name); $response[$name] = array('path' => $value, 'name' => $name); } return $response; } static function includeBGAnimationFile($file) { if (empty($file)) { return false; } $files = self::getBGAnimationFiles(); if ($file == 1) { $f = $files[array_rand($files)]; echo ''; include $f['path']; } foreach ($files as $key => $value) { if ($file == $value['name']) { include $value['path']; break; } } return true; } public function getPluginMenu() { global $global; return ""; $filename = $global['systemRootPath'] . 'plugin/Customize/pluginMenu.html'; return file_get_contents($filename); } public function getHeadCode() { global $global; $loaderParts = self::getLoaderDefault(); echo $loaderParts['css']; echo ""; return false; } static function getIconsList() { global $global; include $global['systemRootPath'] . 'plugin/Layout/fontAwesomeFAB.php'; // Fetch variables scss file in variable $font_vars = file_get_contents($global['systemRootPath'] . 'node_modules/fontawesome-free/scss/_variables.scss'); // Find the position of first $fa-var , as all icon class names start after that $pos = strpos($font_vars, '$fa-var'); // Filter the string and return only the icon class names $font_vars = substr($font_vars, $pos); // Create an array of lines $lines = explode("\n", $font_vars); $fonts_list = array(); foreach ($lines as $line) { // Discard any black line or anything without : if (strpos($line, ':') !== false) { // Icon names and their Unicode Private Use Area values are separated with : and hence, explode them. $t = explode(":", $line); // Remove the $fa-var with fa, to use as css class names. $className = str_replace('$fa-var-', '', $t[0]); if (!in_array($className, $font_awesome_brands)) { $classNameFull = "fa fa-{$className}"; } else { $classNameFull = "fab fa-{$className}"; } $fonts_list[$className] = array($className, $classNameFull, $t[1]); } } return $fonts_list; } static function getSelectSearchable($optionsArray, $name, $selected, $id = "", $class = "", $placeholder = false, $templatePlaceholder = '') { global $global, $nonCriticalCSS; if (empty($id)) { $id = $name; } $html = ""; if (empty($global['getSelectSearchable'])) { $html .= ''; $html .= ''; } if (empty($class)) { $class = "js-select-search"; } $html .= ''; // this is just to display something before load the select2 if (empty($templatePlaceholder)) { $html .= ''; } else { $html .= $templatePlaceholder; } $html .= ''; $global['getSelectSearchable'] = 1; return $html; } private static function getSearch2Code($id) { $code = ''; return $code; } static function getSelectSearchableHTML($optionsArray, $name, $selected, $id = "", $class = "", $placeholder = false, $templatePlaceholder = '') { global $global; if (empty($id)) { $id = $name; } $html = self::getSelectSearchable($optionsArray, $name, $selected, $id, $class, $placeholder, $templatePlaceholder); $html .= self::getSearch2Code($id); return $html; } static function getIconsSelect($name, $selected = "", $id = "", $class = "") { global $getIconsSelect; $getIconsSelect = 1; $icons = self::getIconsList(); if (empty($id)) { $id = uniqid(); } $html = self::getSearch2Code($id); self::addFooterCode($html); return self::getSelectSearchable($icons, $name, $selected, $id, $class . " iconSelect", true); } static function getAvailableFlags() { global $global; $flags = array(); include_once $global['systemRootPath'] . 'objects/bcp47.php'; $files = _glob("{$global['systemRootPath']}locale", '/^[a-z]{2}(_.*)?.php$/'); foreach ($files as $filename) { $filename = basename($filename); $fileEx = basename($filename, ".php"); $name = $global['bcp47'][$fileEx]['label']; $flag = $global['bcp47'][$fileEx]['flag']; $flags[$fileEx] = array(json_encode(array('text' => $name, 'icon' => "flagstrap-icon flagstrap-{$flag}")), $fileEx, 'val3-' . $name); } return $flags; } static function getAllFlags() { global $global; if (empty($global)) { $global = []; } $flags = array(); include_once $global['systemRootPath'] . 'objects/bcp47.php'; /** * @var array $global */ foreach ($global['bcp47'] as $key => $filename) { $name = $filename['label']; $flag = $filename['flag']; $flags[$key] = array(json_encode(array('text' => $name, 'icon' => "flagstrap-icon flagstrap-{$flag}")), $key, 'val3-' . $name); } return $flags; } static function getLangsSelect($name, $selected = "", $id = "", $class = "navbar-btn", $flagsOnly = false, $getAll = false) { global $getLangsSelect, $sortedFlagsCache; $getLangsSelect = 1; // Determine whether to get all flags or available flags if ($getAll) { $flags = self::getAllFlags(); } else { $flags = self::getAvailableFlags(); } // Cache sorted flags to avoid repeated sorting on each request if (!isset($sortedFlagsCache)) { // Sort flags alphabetically based on the 'text' field uasort($flags, function ($a, $b) { $infoA = json_decode($a[0]); $infoB = json_decode($b[0]); return strcmp($infoA->text, $infoB->text); // Compare language names alphabetically }); $sortedFlagsCache = $flags; // Cache the sorted flags } else { $flags = $sortedFlagsCache; // Use cached sorted flags } if (empty($id)) { $id = uniqid(); } if ($selected == 'us') { $selected = 'en_US'; } $selected = revertLangString($selected); // Determine the selected flag's icon (if available) if (!empty($flags[$selected])) { $selectedJson = json_decode($flags[$selected][0]); $selectedJsonIcon = $selectedJson->icon; } else { $selectedJsonIcon = ''; } // Build the HTML for the dropdown $html = '
'; return $html; } static function getUserSelect($name, $users_id_list, $selected = "", $id = "", $class = "") { $elements = array(); foreach ($users_id_list as $users_id) { $name = User::getNameIdentificationById($users_id); $photo = User::getPhoto($users_id); $elements[$users_id] = htmlentities(" {$name}"); if ($users_id == User::getId()) { $elements[$users_id] .= " (Me)"; } } if (empty($id)) { $id = uniqid(); } $html = self::getSearch2Code($id); self::addFooterCode($html); return self::getSelectSearchable($elements, $name, $selected, $id, $class, true); } static function getCategorySelect($name, $selected = "", $id = "", $class = "") { $parentsOnly = @$_GET['parentsOnly']; unset($_GET['parentsOnly']); $rows = Category::getAllCategories(true, false); $_GET['parentsOnly'] = $parentsOnly; //var_dump($rows);exit; //array_multisort(array_column($rows, 'hierarchyAndName'), SORT_ASC, $rows); $cats = array(); foreach ($rows as $value) { $cats[$value['id']] = htmlentities(" " . $value['hierarchyAndName']); } if (empty($id)) { $id = uniqid(); } $html = self::getSearch2Code($id); self::addFooterCode($html); return self::getSelectSearchable($cats, $name, $selected, $id, $class, true); } static function getUserGroupsSelect($name, $selected = "", $id = "", $class = "") { $rows = UserGroups::getAllUsersGroupsArray(); if (empty($id)) { $id = uniqid(); } $html = self::getSearch2Code($id); self::addFooterCode($html); return self::getSelectSearchable($rows, $name, $selected, $id, $class, true); } public function getFooterCode() { global $global; $obj = $this->getDataObject(); $content = ''; if (!empty($global['getSelectSearchable'])) { $content .= ''; } if (!empty($obj->enableAccessibility)) { $file = $global['systemRootPath'] . 'plugin/Layout/accessibility/accessibility.php'; $content .= getIncludeFileContent($file); } $content .= self::_getFooterCode(); return $content; } private static function addFooterCode($code) { global $LayoutaddFooterCode; if (!isset($LayoutaddFooterCode)) { $LayoutaddFooterCode = array(); } $LayoutaddFooterCode[] = $code; } private static function _getFooterCode() { global $LayoutaddFooterCode; if (!isset($LayoutaddFooterCode)) { return ""; } $LayoutaddFooterCode = array_unique($LayoutaddFooterCode); return implode(PHP_EOL, $LayoutaddFooterCode); } public function getHTMLMenuRight() { global $global; $obj = $this->getDataObject(); if (empty($obj->showButtonNotification)) { return false; } include $global['systemRootPath'] . 'plugin/Layout/menuRight.php'; } public function navBarAfter() { global $global; $obj = $this->getDataObject(); $content = ''; if (!AVideoPlugin::isEnabledByName('YouPHPFlix2') && !empty($obj->categoriesTopButtons)) { if (empty($obj->categoriesTopButtonsShowOnlyOnFirstPage) || isFirstPage()) { $content .= getIncludeFileContent($global['systemRootPath'] . 'plugin/Layout/categoriesTopButtons.php'); } } if (!empty($obj->showSearchOptionsBelowNavbar) && isFirstPage()) { $content .= getIncludeFileContent($global['systemRootPath'] . 'plugin/Layout/searchOptions.php'); } return $content; } static function getPlaylistAutocomplete($default_Playlists_id = 0, $id = '', $parameters = array(), $jsFunctionForSelectCallback = '') { global $global; $default_Playlists_id = intval($default_Playlists_id); if (empty($id)) { $id = 'getPlaylistAutocomplete_' . uniqid(); } include $global['systemRootPath'] . 'plugin/Layout/playlistAutocomplete.php'; return "updatePlaylistAutocomplete{$id}();"; } static function getUserAutocomplete($default_users_id = 0, $id = '', $parameters = array(), $jsFunctionForSelectCallback = '') { global $global; $default_users_id = intval($default_users_id); if (empty($id)) { $id = 'getUserAutocomplete_' . uniqid(); } include $global['systemRootPath'] . 'plugin/Layout/userAutocomplete.php'; return "updateUserAutocomplete{$id}();"; } static function getVideoAutocomplete($default_videos_id = 0, $id = '', $parameters = array(), $jsFunctionForSelectCallback = '') { global $global; $default_videos_id = intval($default_videos_id); if (empty($id)) { $id = 'getVideoAutocomplete_' . uniqid(); } include $global['systemRootPath'] . 'plugin/Layout/videoAutocomplete.php'; return "updateVideoAutocomplete{$id}();"; } static function organizeHTML($html) { global $global; // add socket twice on live page //return $html; /* if (isBot()) { //var_dump('doNOTOrganizeHTML');exit; return $html . PHP_EOL . ''; } */ if (!empty($global['doNOTOrganizeHTML'])) { //var_dump('doNOTOrganizeHTML');exit; return $html . PHP_EOL . ''; } if (!empty($_REQUEST['debug'])) { //var_dump('doNOTOrganizeHTML');exit; return $html . PHP_EOL . ''; } self::$tags = array(); //return $html; //var_dump($html);exit; $html = self::getTagsLinkCSS($html); $html = self::getTagsScript($html); $html = self::separeteTag($html, 'style'); $html = self::separeteTag($html, 'script'); //$html = preg_replace('/<\/script>/i', '', $html); //return $html; //var_dump(self::$tags['script']);exit; //var_dump(self::$tags['tagscript']);exit; if (!empty(self::$tags['tagcss'])) { self::$tags['tagcss'] = self::removeDuplicated(self::$tags['tagcss']); usort(self::$tags['tagcss'], "_sortCSS"); $html = str_replace('', PHP_EOL . implode(PHP_EOL, array_unique(self::$tags['tagcss'])) . '', $html); } //return $html; if (!empty(self::$tags['style'])) { $html = str_replace('', '', $html); } if (!empty(self::$tags['tagscript'])) { self::$tags['tagscript'] = self::removeDuplicated(self::$tags['tagscript']); usort(self::$tags['tagscript'], "_sortJS"); $html = str_replace('', PHP_EOL . implode(PHP_EOL, array_unique(self::$tags['tagscript'])) . '', $html); } if (!empty(self::$tags['script'])) { $html = str_replace('', '', $html); } $html = self::removeExtraSpacesFromHead($html); $html = self::removeExtraSpacesFromScript($html); //echo $html;exit; return $html; } private static function tryToReplace($search, $replace, $subject) { if (true || self::codeIsValid($subject)) { $newSubject = str_replace($search, $replace, $subject, $count); return ['newSubject' => $newSubject, 'success' => $count]; } else { _error_log('organizeHTML: Invalid code: ' . $subject); return ['newSubject' => $subject, 'success' => false]; } } private static function codeIsValid($string) { $len = strlen($string); $stack = array(); for ($i = 0; $i < $len; $i++) { switch ($string[$i]) { case '{': array_push($stack, 0); break; case '}': if (array_pop($stack) !== 0) return false; break; case '(': array_push($stack, 0); break; case ')': if (array_pop($stack) !== 0) return false; break; case '[': array_push($stack, 1); break; case ']': if (array_pop($stack) !== 1) return false; break; default: break; } } return (empty($stack)); } static function removeExtraSpacesFromHead($html) { preg_match('/()/Usi', $html, $matches); $str = preg_replace('/[ \t]+/', ' ', $matches[0]); $str = preg_replace('/\n\s*\n+/', PHP_EOL, $matches[0]); //var_dump($str);exit; $html = str_replace($matches[0], $str, $html); return $html; } static function removeExtraSpacesFromScript($html) { preg_match_all('/(]*>.+<\/script>)/Usi', $html, $matches); foreach ($matches as $value) { $str = preg_replace('/ +/', ' ', $value); $html = str_replace($value, $str, $html); } return $html; } static function getTagsLinkCSS($html) { $nonCriticalCSS = ' rel="preload" media="print" as="style" onload="this.media=\'all\'" '; preg_match_all('/]+href=[^>]+>/Usi', $html, $matches); if (!empty($matches)) { foreach ($matches[0] as $value) { $response = self::tryToReplace($value, '', $html); if ($response['success']) { if (strpos($value, 'rel="preload"') === false) { $containsCritical = false; foreach (self::$criticalCSS as $crit) { if (strpos($value, $crit) !== false) { $containsCritical = true; break; } } if (!$containsCritical) { $value = str_replace('type="text/css"', 'type="text/css" ' . $nonCriticalCSS, $value); } } self::addTag('tagcss', $value); $html = $response['newSubject']; } } } return $html; } static function getTagsScript($html) { preg_match_all('//Usi', $html, $matches); if (!empty($matches)) { foreach ($matches[0] as $key => $value) { // ignore google analitics if (!self::shouldIgnoreJS($value)) { $response = self::tryToReplace($value, '', $html); if ($response['success']) { self::addTag('tagscript', $value); $html = $response['newSubject']; } } } } return $html; } static function separeteTag($html, $tag) { $reg = '/<' . $tag . '[^>]*>(.*)<\/' . $tag . '>/Usi'; //var_dump($reg, $html); preg_match_all($reg, $html, $matches); //var_dump($matches);exit; if (!empty($matches)) { foreach ($matches[0] as $key => $value) { if (!self::shouldIgnoreJS($value)) { $response = self::tryToReplace($value, '', $html); if ($response['success']) { self::addTag($tag, $matches[1][$key]); $html = $response['newSubject']; } } } } return $html; } static function shouldIgnoreJS($tag) { if ( preg_match('/application.+json/i', $tag) || preg_match('/function gtag\(/i', $tag) || preg_match('/ $value) { if (strpos($a, $value) !== false) $aIndexFirst = $index; if (strpos($b, $value) !== false) $bIndexFirst = $index; } // Check if $a and $b are in $lastOrder foreach ($lastOrder as $index => $value) { if (strpos($a, $value) !== false) $aIndexLast = $index; if (strpos($b, $value) !== false) $bIndexLast = $index; } // Handle case when $a and $b are in $firstOrder if ($aIndexFirst !== null && $bIndexFirst !== null) { return $aIndexFirst - $bIndexFirst; // order by position in $firstOrder } if ($aIndexFirst !== null) { return -1; // $a in $firstOrder, $b not } if ($bIndexFirst !== null) { return 1; // $b in $firstOrder, $a not } // Handle case when $a and $b are in $lastOrder if ($aIndexLast !== null && $bIndexLast !== null) { return $aIndexLast - $bIndexLast; // order by position in $lastOrder } if ($aIndexLast !== null) { return 1; // $a in $lastOrder, $b not } if ($bIndexLast !== null) { return -1; // $b in $lastOrder, $a not } // If none of the above conditions met, order doesn't matter return 0; } function _sortJS($a, $b) { $firstOrder = [ "jquery.min.js", "jquery-ui", "js/bootstrap.min.js", "js.cookie.js", "node_modules/video.js/dist/video", "videojs-contrib-ads", "videojs-ima", "moment.min.js", "moment-timezone.min.js", "moment-timezone-with-data.min.js", "moment/locale/", "jquery.lazy.min.js", "jquery.lazy.plugins.min.js", "flickity.pkgd.min.js", "flickity-bg-lazyload/bg-lazyload.js", "@fullcalendar/core/index.global.min.js", ]; $lastOrder = [ "js/script.js", "/plugin/", ]; return compareOrder($a, $b, $firstOrder, $lastOrder); } function _sortCSS($a, $b) { $firstOrder = array( 'view/bootstrap/css/bootstrap.min.css', 'view/css/custom', 'videos/cache/custom.css', 'view/css/navbar.css', 'plugin/Gallery/style.css', 'node_modules/animate.css/animate', 'view/css/main.css', ); $lastOrder = array( 'node_modules/video.js/dist/video-js.min.css', 'videojs', 'plugin/PlayerSkins/player.css', 'plugin/PlayerSkins/skins/', );; return compareOrder($a, $b, $firstOrder, $lastOrder); }