diff --git a/source/community.applications/usr/local/emhttp/plugins/community.applications/ca.md5 b/source/community.applications/usr/local/emhttp/plugins/community.applications/ca.md5 index ebcc581b..32c8078e 100644 --- a/source/community.applications/usr/local/emhttp/plugins/community.applications/ca.md5 +++ b/source/community.applications/usr/local/emhttp/plugins/community.applications/ca.md5 @@ -2,8 +2,8 @@ 4e55f7483b661af21a25b677179baffe ./CA_notices.page 4c5d4598e1bafa46bd90c27cbe302122 ./ca_settings.page e8d29607ec792ddf9f6832b10ee70fdc ./default.cfg -9a5b45bd22ee24f7a7eed98e377a8501 ./include/exec.php -ec64fc40aa10ccf2b98907e3081053f5 ./include/helpers.php +2ea430441b1f4e63a6e7eab4dd39ba9b ./include/exec.php +9441e82a241d88d6cdbee4e910a5cdda ./include/helpers.php 116042a918060278e77379b0dd73482c ./include/paths.php 532fffdf939594c143e679da02bd841e ./javascript/libraries.js 71f911a818d88d3d567f8a2898094ee2 ./README.md @@ -22,4 +22,4 @@ da3b4f9b73c5c3bf65be6c42d68b51f9 ./scripts/showStatistics.php 34554a56611dfe625889c82afd5138de ./scripts/updatePluginSupport.php 25bdaed6f62ac73f9ef7c3ce0c125ef7 ./skins/Narrow/css.php 7eb021a105e2f7a15675ec8a14e6f05e ./skins/Narrow/skin.html -c0061be734e2f9896c4f981958da0354 ./skins/Narrow/skin.php +614f249640c329d4167a72a3f6fda0c5 ./skins/Narrow/skin.php diff --git a/source/community.applications/usr/local/emhttp/plugins/community.applications/include/exec.php b/source/community.applications/usr/local/emhttp/plugins/community.applications/include/exec.php index b7e9d086..8548bbed 100644 --- a/source/community.applications/usr/local/emhttp/plugins/community.applications/include/exec.php +++ b/source/community.applications/usr/local/emhttp/plugins/community.applications/include/exec.php @@ -662,7 +662,7 @@ function displayRepositories() { $fav['RepoName'] = $repoName; $fav['SortName'] = $repoName; } else { - if ( $repositories[$repoName]['bio'] ) { + if ( isset($repositories[$repoName]['bio']) ) { $bio[$repoName] = $repositories[$repoName]; $bio[$repoName] = $repositories[$repoName]; $bio[$repoName]['RepositoryTemplate'] = true; @@ -679,9 +679,9 @@ function displayRepositories() { usort($bio,"mySort"); usort($allRepos,"mySort"); $allRepos = array_merge($bio,$allRepos); - if ( $fav ) + if ( isset($fav) ) array_unshift($allRepos,$fav); - $file['community'] = $allRepos; + $file['community'] = addMissingVars($allRepos); writeJsonFile($caPaths['repositoriesDisplayed'],$file); } @@ -924,7 +924,7 @@ function get_content() { $display[] = $template; } if ( $filter ) { - if ( is_array($searchResults['nameHit']) ) { + if ( isset($searchResults['nameHit']) ) { usort($searchResults['nameHit'],"mySort"); if ( ! strpos($filter," Repository") ) { if ( $caSettings['favourite'] && $caSettings['favourite'] !== "none" ) { @@ -1394,7 +1394,10 @@ function pinApp() { $repository = getPost("repository","oops"); $name = getPost("name","oops"); $pinnedApps = readJsonFile($caPaths['pinnedV2']); - $pinnedApps["$repository&$name"] = $pinnedApps["$repository&$name"] ? false : "$repository&$name"; + if (isset($pinnedApps["$repository&$name"]) ) + $pinnedApps["$repository&$name"] = false; + else + $pinnedApps["$repository&$name"] = "$repository&$name"; $pinnedApps = array_filter($pinnedApps); writeJsonFile($caPaths['pinnedV2'],$pinnedApps); postReturn(['status' => in_array(true,$pinnedApps)]); @@ -1457,7 +1460,7 @@ function pinnedApps() { $displayedApplications['community'] = $displayed; $displayedApplications['pinnedFlag'] = true; writeJsonFile($caPaths['community-templates-displayed'],$displayedApplications); - postReturn(["status"=>"ok","script"=>$script]); + postReturn(["status"=>"ok","script"=>$script ?? ""]); } ################################################ @@ -1915,14 +1918,18 @@ function createXML() { if ( is_array($config['@attributes']) ) { if ( $config['@attributes']['Type'] == "Path" ) { $defaultReferenced = array_values(array_filter(explode("/",$config['@attributes']['Default']))); - - if ( $defaultReferenced[0] == "mnt" && $defaultReferenced[1] && ! in_array($defaultReferenced[1],$disksPresent) ) - $config['@attributes']['Default'] = str_replace("/mnt/{$defaultReferenced[1]}/","/mnt/{$disksPresent[0]}/",$config['@attributes']['Default']); + + if ( isset($defaultReferenced[0]) && isset($defaultReferenced[1]) ) { + if ( $defaultReferenced[0] == "mnt" && $defaultReferenced[1] && ! in_array($defaultReferenced[1],$disksPresent) ) + $config['@attributes']['Default'] = str_replace("/mnt/{$defaultReferenced[1]}/","/mnt/{$disksPresent[0]}/",$config['@attributes']['Default']); + } $valueReferenced = array_values(array_filter(explode("/",$config['value']))); - if ( $valueReferenced[0] == "mnt" && $valueReferenced[1] && ! in_array($valueReferenced[1],$disksPresent) ) - $config['value'] = str_replace("/mnt/{$valueReferenced[1]}/","/mnt/{$disksPresent[0]}/",$config['value']); - + if ( isset($valueReferenced[0]) && isset($valueReferenced[1]) ) { + if ( $valueReferenced[0] == "mnt" && $valueReferenced[1] && ! in_array($valueReferenced[1],$disksPresent) ) + $config['value'] = str_replace("/mnt/{$valueReferenced[1]}/","/mnt/{$disksPresent[0]}/",$config['value']); + } + // Check for pre-existing folders only differing by "case" and adjust accordingly // Default path @@ -1993,7 +2000,7 @@ function createXML() { @mkdir(dirname($xmlFile)); file_put_contents($xmlFile,$xml); } - postReturn(["status"=>"ok","cache"=>$cacheVolume]); + postReturn(["status"=>"ok","cache"=>$cacheVolume ?? ""]); } ######################## @@ -2248,7 +2255,7 @@ function search_dockerhub() { $searchName = str_replace("docker-","",$o['Name']); $searchName = str_replace("-docker","",$searchName); - $dockerResults[$i] = $o; + $dockerResults[$i] = addMissingVars($o); $i=++$i; } $dockerFile['num_pages'] = $num_pages; @@ -2265,6 +2272,7 @@ function getLastUpdate($ID) { global $caPaths; $count = 0; + $registry_json = null; while ( $count < 5 ) { $templates = &$GLOBALS['templates']; if ( $templates ) break; @@ -2306,7 +2314,7 @@ function getLastUpdate($ID) { return; } - + $registry_json['last_updated'] = $registry_json['last_updated'] ?? false; $lastUpdated = $registry_json['last_updated'] ? tr(date("M j, Y",strtotime($registry_json['last_updated'])),0) : "Unknown"; return $lastUpdated; diff --git a/source/community.applications/usr/local/emhttp/plugins/community.applications/include/helpers.php b/source/community.applications/usr/local/emhttp/plugins/community.applications/include/helpers.php index 8209ca5a..f1c0ac68 100644 --- a/source/community.applications/usr/local/emhttp/plugins/community.applications/include/helpers.php +++ b/source/community.applications/usr/local/emhttp/plugins/community.applications/include/helpers.php @@ -251,7 +251,7 @@ function fixTemplates($template) { ############################################### function makeXML($template) { # ensure its a v2 template if the Config entries exist - if ( $template['Config'] && ! $template['@attributes'] ) + if ( isset($template['Config']) && ! isset($template['@attributes']) ) $template['@attributes'] = ["version"=>2]; if ($template['Overview']) $template['Description'] = $template['Overview']; @@ -260,8 +260,10 @@ function makeXML($template) { fixAttributes($template,"Config"); # Sanitize the Requires entry if there is any CA links within it - preg_match_all("/\/\/(.*?)\/m",$template['Requires'],$searchMatches); - if ( count($searchMatches[1]) ) { + if ($template['Requires'] && $searchMatches) + preg_match_all("/\/\/(.*?)\/m",$template['Requires'],$searchMatches); + + if ( isset($searchMatches[1]) && count($searchMatches[1]) ) { foreach ($searchMatches[1] as $searchResult) { $template['Requires'] = str_replace("//$searchResult\\\\",$searchResult,$template['Requires']); } @@ -275,7 +277,7 @@ function makeXML($template) { ################################################################################# function fixAttributes(&$template,$attribute) { if ( ! is_array($template[$attribute]) ) return; - if ( $template[$attribute]['@attributes'] ) { + if ( isset($template[$attribute]['@attributes']) ) { $template[$attribute][0]['@attributes'] = $template[$attribute]['@attributes']; if ( $template[$attribute]['value']) $template[$attribute][0]['value'] = $template[$attribute]['value']; @@ -318,7 +320,7 @@ function versionCheck($template) { function readXmlFile($xmlfile,$generic=false,$stats=true) { global $statistics; - if ( ! is_file($xmlfile) ) return false; + if ( $xmlfile && ! is_file($xmlfile) ) return false; $xml = file_get_contents($xmlfile); $o = TypeConverter::xmlToArray($xml,TypeConverter::XML_GROUP); $o = addMissingVars($o); @@ -670,14 +672,15 @@ function debug($str) { # Gets the default ports in a template # ######################################## function portsUsed($template) { - if ( $template['Network'] !== "bridge") + if ( ($template['Network'] ?? "whatever") !== "bridge") return; $portsUsed = []; - if ( $template['Config']['@attributes'] ) + if ( isset($template['Config']['@attributes']) ) $template['Config'] = ['@attributes'=>$template['Config']]; if ( is_array($template['Config']) ) { foreach ($template['Config'] as $config) { - if ( $config['@attributes']['Type'] !== "Port" ) continue; + if ( $config['@attributes']['Type'] !== "Port" ) + continue; $portsUsed[] = $config['value'] ?: $config['@attributes']['Default']; } } @@ -688,7 +691,6 @@ function portsUsed($template) { # Get the ports in use # ######################## function getPortsInUse() { - return []; global $var, $caPaths; $addr = null; @@ -812,7 +814,11 @@ function addMissingVars($o) { 'stars', 'LanguageURL', 'LastUpdate', - 'RecommendedWho' + 'RecommendedWho', + 'RepoName', + 'SortName', + 'ca_fav', + 'Pinned' ]; @@ -1435,7 +1441,7 @@ class Array2XML { // after we are done with all the keys in the array (if it is one) // we check if it has any text value, if yes, append it. if(!is_array($arr)) { - $node->appendChild($xml->createTextNode(self::bool2str($arr))); + $node->appendChild($xml->createTextNode(self::bool2str($arr ?? ""))); } return $node; } diff --git a/source/community.applications/usr/local/emhttp/plugins/community.applications/skins/Narrow/skin.php b/source/community.applications/usr/local/emhttp/plugins/community.applications/skins/Narrow/skin.php index 0416c5ec..bf6b0c59 100644 --- a/source/community.applications/usr/local/emhttp/plugins/community.applications/skins/Narrow/skin.php +++ b/source/community.applications/usr/local/emhttp/plugins/community.applications/skins/Narrow/skin.php @@ -86,19 +86,20 @@ function my_display_apps($file,$pageNumber=1,$selectedApps=false,$startup=false) # Create entries for skins. foreach ($displayedTemplates as $template) { - if ( ! $template['Blacklist'] ) { - if ( isset($extraBlacklist[$template['Repository']]) ) { - $template['Blacklist'] = true; - $template['ModeratorComment'] = $extraBlacklist[$template['Repository']]; + if ( ! $template['RepositoryTemplate'] ) { + if ( ! $template['Blacklist'] ) { + if ( isset($extraBlacklist[$template['Repository']]) ) { + $template['Blacklist'] = true; + $template['ModeratorComment'] = $extraBlacklist[$template['Repository']]; + } + } + if ( ! $template['Deprecated'] && isset($extraDeprecated[$template['Repository']]) ) { + $template['Deprecated'] = true; + $template['ModeratorComment'] = $extraDeprecated[$template['Repository']]; } } - if ( ! $template['Deprecated'] && isset($extraDeprecated[$template['Repository']]) ) { - $template['Deprecated'] = true; - $template['ModeratorComment'] = $extraDeprecated[$template['Repository']]; - } - if ( $template['RepositoryTemplate'] ) { - $template['Icon'] = $template['icon'] ?: "/plugins/dynamix.docker.manager/images/question.png"; + $template['Icon'] = $template['icon'] ?? "/plugins/dynamix.docker.manager/images/question.png"; if ( ! $template['bio'] ) $template['CardDescription'] = tr("No description present"); @@ -187,7 +188,7 @@ function my_display_apps($file,$pageNumber=1,$selectedApps=false,$startup=false) } $actionsContext[] = ["icon"=>"ca_fa-delete","text"=>tr("Remove from Previous Apps"),"alternate"=>tr("Remove"),"action"=>"removeApp('{$template['InstallPath']}','{$template['Name']}');"]; } else { - if ( ! $template['BranchID'] ) { + if ( ! ($template['BranchID'] ?? null) ) { if ( is_file("{$caPaths['dockerManTemplates']}/my-{$template['Name']}.xml") ) { $test = readXmlFile("{$caPaths['dockerManTemplates']}/my-{$template['Name']}.xml",true); if ( $template['Repository'] == $test['Repository'] ) { @@ -453,6 +454,7 @@ function getPopupDescriptionSkin($appNumber) { $extraBlacklist = readJsonFile($caPaths['extraBlacklist']); $extraDeprecated = readJsonFile($caPaths['extraDeprecated']); $templateDescription = ""; + $selected = null; $pinnedApps = readJsonFile($caPaths['pinnedV2']); @@ -664,7 +666,7 @@ function getPopupDescriptionSkin($appNumber) { if ( ! $template['Blacklist'] ) { if ( ( $template['Compatible'] || $caSettings['hideIncompatible'] !== "true" ) ) { if ( !$template['Deprecated'] || $caSettings['hideDeprecated'] !== "true" ) { - if ( ! $template['BranchID'] ) { + if ( ! isset($template['BranchID']) ) { $actionsContext[] = ["icon"=>"ca_fa-install","text"=>tr("Install"),"action"=>"popupInstallXML('".addslashes($template['Path'])."','default','','".portsUsed($template)."');"]; } else { $actionsContext[] = ["icon"=>"ca_fa-install","text"=>tr("Install"),"action"=>"displayTags('{$template['ID']}',false,'','".portsUsed($template)."');"]; @@ -852,10 +854,10 @@ function getRepoDescriptionSkin($repository) { $repo['bio'] = $repo['bio'] ? markdown($repo['bio']) : "
".tr("No description present"); $favRepoClass = ($caSettings['favourite'] == $repository) ? "fav" : "nonfav"; - $totalApps = $totalPlugins = $totalDocker = $totalDownloads = 0; + $totalApps = $totalLanguage = $totalPlugins = $totalDocker = $totalDownloads = $downloadDockerCount = 0; foreach ($templates as $template) { if ( $template['RepoName'] !== $repository ) continue; - if ( $template['BranchID'] ) continue; + if ( isset($template['BranchID']) ) continue; if ( $template['Blacklist'] ) continue; if ( $template['Deprecated'] && $caSettings['hideDeprecated'] !== "false" ) continue; @@ -893,7 +895,7 @@ function getRepoDescriptionSkin($repository) {

".strip_tags($repo['bio'])."
"; - if ( $repo['DonateLink'] ) { + if ( isset($repo['DonateLink']) ) { $t .= "
{$repo['DonateText']}
@@ -901,9 +903,9 @@ function getRepoDescriptionSkin($repository) {
"; } - if ( $repo['Photo'] || $repo['Video']) { + if ( isset($repo['Photo']) || isset($repo['Video']) ) { $t .= "
"; - if ( $repo['Photo'] ) { + if ( isset($repo['Photo']) ) { $photos = is_array($repo['Photo']) ? $repo['Photo'] : [$repo['Photo']]; $t .= "
"; foreach ($photos as $shot) { @@ -911,8 +913,8 @@ function getRepoDescriptionSkin($repository) { } $t .= "
"; } - if ( $repo['Video'] ) { - if ( $repo['Photo'] ) + if ( isset($repo['Video']) ) { + if ( isset($repo['Photo']) ) $t .= "

"; $videos = is_array($repo['Video']) ? $repo['Video'] : [$repo['Video']]; @@ -935,19 +937,19 @@ function getRepoDescriptionSkin($repository) { $t .= "
"; - if ( $repo['WebPage'] ) + if ( isset($repo['WebPage']) ) $t .= " ".tr("Web Page").""; - if ( $repo['Forum'] ) + if ( isset($repo['Forum']) ) $t .= " ".tr("Forum").""; - if ( $repo['profile'] ) + if ( isset($repo['profile']) ) $t .= " ".tr("Forum Profile").""; - if ( $repo['Facebook'] ) + if ( isset($repo['Facebook']) ) $t .= " ".tr("Facebook").""; - if ( $repo['Reddit'] ) + if ( isset($repo['Reddit']) ) $t .= " ".tr("Reddit").""; - if ( $repo['Twitter'] ) + if ( isset($repo['Twitter']) ) $t .= " ".tr("Twitter").""; - if ( $repo['Discord'] ) + if ( isset($repo['Discord']) ) $t .= " ".tr("Discord").""; $t .= " @@ -962,7 +964,7 @@ function getRepoDescriptionSkin($repository) { ".tr("Total Docker Applications")."$totalDocker ".tr("Total Plugin Applications")."$totalPlugins "; - if ( $totalLanguage ) + if ( isset($totalLanguage) ) $t .= " ".tr("Total Languages")."$totalLanguage "; @@ -1003,9 +1005,9 @@ function displaySearchResults($pageNumber) { $tempFile = readJsonFile($caPaths['dockerSearchResults']); $num_pages = $tempFile['num_pages']; $file = $tempFile['results']; -// $templates = readJsonFile($caPaths['community-templates-info']); $templates = &$GLOBALS['templates']; - + $count = 0; + $ct = "
".tr("NOTE You must visit the dockerHub page to gather the information required to install correctly")."Show CA templates


"; $ct .= "
"; @@ -1045,25 +1047,33 @@ function displayCard($template) { $appName = str_replace("-"," ",$template['display_dockerName'] ?? ""); $holderClass = ""; $card = ""; - - $popupType = $template['RepositoryTemplate'] ? "ca_repoPopup" : "ca_appPopup"; + + if ( $template['RepositoryTemplate'] ) + $template['DockerHub'] = false; + if ( $template['DockerHub'] ) $popupType = null; + else { + $popupType = $template['RepositoryTemplate'] ? "ca_repoPopup" : "ca_appPopup"; - if ($template['Language']) { - $language = "{$template['Language']}"; - $language .= $template['LanguageLocal'] ? " - {$template['LanguageLocal']}" : ""; - $template['Category'] = ""; + if (! $template['RepositoryTemplate'] && $template['Language']) { + $language = "{$template['Language']}"; + $language .= $template['LanguageLocal'] ? " - {$template['LanguageLocal']}" : ""; + $template['Category'] = ""; + } } - + extract($template); $class = "spotlightHome"; - $appType = $Plugin ? "appPlugin" : "appDocker"; - $appType = $Language ? "appLanguage": $appType; - $appType = (strpos($Category,"Drivers") !== false) && $Plugin ? "appDriver" : $appType; - $appType = $RepositoryTemplate ? "appRepository" : $appType; + if ( $RepositoryTemplate ) + $appType = "appRepository"; + else { + $appType = $Plugin ? "appPlugin" : "appDocker"; + $appType = $Language ? "appLanguage": $appType; + $appType = (strpos($Category,"Drivers") !== false) && $Plugin ? "appDriver" : $appType; + } switch ($appType) { case "appPlugin": $typeTitle = tr("This application is a plugin"); @@ -1077,10 +1087,14 @@ function displayCard($template) { case "appDriver": $typeTitle = tr("This application is a driver (plugin)"); break; + default: + $typeTitle = ""; + break; } if ($InstallPath ?? false) $Path = $InstallPath; - + + $Category = $Category ?? ""; $Category = explode(" ",$Category)[0]; $Category = explode(":",$Category)[0]; @@ -1109,29 +1123,29 @@ function displayCard($template) { $supportContext[] = ["icon"=>"ca_discord","link"=>$Discord,"text"=>tr("Discord")]; if ( $Support ) $supportContext[] = ["icon"=>"ca_fa-support","link"=>$Support,"text"=> $SupportLanguage ?: tr("Support Forum")]; - } else { $holderClass='repositoryCard'; $cardClass = "ca_repoinfo"; $ID = str_replace(" ","",$RepoName); $supportContext = []; - if ( $profile ) + if ( $profile ?? false ) $supportContext[] = ["icon"=>"ca_profile","link"=>$profile,"text"=>tr("Profile")]; - if ( $Forum ) + if ( $Forum ?? false) $supportContext[] = ["icon"=>"ca_forum","link"=>$Forum,"text"=>tr("Forum")]; - if ( $Twitter ) + if ( $Twitter ?? false) $supportContext[] = ["icon"=>"ca_twitter","link"=>$Twitter,"text"=>tr("Twitter")]; - if ( $Reddit ) + if ( $Reddit ?? false) $supportContext[] = ["icon"=>"ca_reddit","link"=>$Reddit,"text"=>tr("Reddit")]; - if ( $Facebook ) + if ( $Facebook ?? false) $supportContext[] = ["icon"=>"ca_facebook","link"=>$Facebook,"text"=>tr("Facebook")]; - if ( $WebPage ) + if ( $WebPage ?? false) $supportContext[] = ["icon"=>"ca_webpage","link"=>$WebPage,"text"=>tr("Web Page")]; $Name = str_replace(["' Repository","'s Repository"," Repository"],"",html_entity_decode($author,ENT_QUOTES)); $Name = str_replace(["'s","'s"],"",$Name); $author = ""; + $Path = $Repository = $Plugin = $IconFA = $ModeratorComment = $RecommendedDate = $UpdateAvailable = $Blacklist = $Official = $Trusted = $Pinned = $actionsContext = $Deprecated = $Removable = $CAComment = $Installed = $Uninstalled = $Uninstall = $fav = $Beta = $Requires = $caTemplateExists = $actionCentre = $Overview = $imageNoClick = ""; } $bottomClass = "ca_bottomLineSpotLight"; @@ -1142,7 +1156,7 @@ function displayCard($template) {
".tr("Docker Hub")."
"; } else { - if ( $PluginURL ) { + if ( $PluginURL ?? false) { $dataPluginURL = "data-pluginurl='$PluginURL'"; } else { $dataPluginURL = ""; @@ -1176,8 +1190,8 @@ function displayCard($template) { $card .= ""; } else $card .= ""; - if ( ! $Pinned ) - $pinStyle = "display:none;"; + + $pinStyle = $Pinned ? "" : "display:none;"; $pindata = (strpos($Repository,"/") !== false) ? $Repository : "library/$Repository"; $card .= ""; @@ -1197,7 +1211,8 @@ function displayCard($template) { $type = 'plugin'; break; } - if ($Removable && !$DockerInfo && ! $Installed && ! $Blacklist) { + $checked = $checked ?? ""; + if ($Removable && !($DockerInfo ?? false) && ! $Installed && ! $Blacklist) { $card .= ""; } elseif ( $actionCentre && $UpdateAvailable ) { $card .= ""; @@ -1250,7 +1265,7 @@ function displayCard($template) {
"; - $Overview = $Overview ?: $Description; + $Overview = $Overview ?: ($Description ?? ""); if ( ! $Overview ) $Overview = tr("No description present"); @@ -1398,7 +1413,7 @@ function displayPopup($template) {
"; - if ( $Requires && ! is_file($RequiresFile) ) + if ( $Requires && ! is_file($RequiresFile ?? "") ) $card .= "
".tr("Additional Requirements")."
{$template['Requires']}
"; if ( $Deprecated )