applicationpage.php 13.2 KB
Newer Older
1 2 3 4 5
<?php
// error_reporting(E_ALL);
// ini_set('display_errors', 1);

include 'includes/class_appdata2.inc';
6

7
$url_split = explode('/', $_SERVER['REQUEST_URI']);
8
$url_dir = $url_split[1];
Jonathan Riddell's avatar
Jonathan Riddell committed
9

10 11 12 13
// khelpcenter has an appstream id of org.kde.Help so the forward from the old URLs does not work
// this json file has that mapping
$contents = file_get_contents('unusual-appstream-ids.json');
$contents = utf8_encode($contents);
14
$unusual_appstream_ids = json_decode($contents, true);
15

16 17
// forward for old kde.org/applications site URLs
if (strpos($_GET['application'], 'org.kde') === false) {
18
    $application_name = $_GET['application'];
19
    if (array_key_exists($application_name, $unusual_appstream_ids)) {
20 21 22
        $application_name = $unusual_appstream_ids[$application_name];
    }
    header("Location: /".  $url_dir . "/" . $_GET['category'] . '/' . 'org.kde.' . $application_name);
23 24 25 26
    exit();
}

// if it doesn't exist return 404
27
$app = new AppData2($_GET['application']);
Jonathan Riddell's avatar
Jonathan Riddell committed
28
if ($app->valid() === false) {
Jonathan Riddell's avatar
Jonathan Riddell committed
29 30
    http_response_code(404);
    print 'App not found';
Jonathan Riddell's avatar
Jonathan Riddell committed
31 32
    exit();
}
Jonathan Riddell's avatar
Jonathan Riddell committed
33

34 35 36
$category = $_GET['category'];
$development = isset($_GET['development']);

Jonathan Riddell's avatar
Jonathan Riddell committed
37 38 39 40 41 42 43 44 45
$index = json_decode(file_get_contents("index.json"), true);

$categories = array_keys($index);
foreach($categories as $cat) {
    if (strtolower($cat) == $_GET["category"]) {
        $category_string = $cat;
        break;
    }
}
Jonathan Riddell's avatar
Jonathan Riddell committed
46 47 48 49 50
if (!isset($category_string)) {
    http_response_code(404);
    print 'Category not found';
    exit();
}
Jonathan Riddell's avatar
Jonathan Riddell committed
51

52

53 54 55
// if app category is wrong forward to correct one
$correct_category = null;
foreach ($categories as $cat) {
56
    if (in_array($_GET['application'], $index[$cat])) {
57 58 59 60
        $correct_category = $cat;
    }
}
if (strtolower($correct_category) != $_GET['category']) {
Jonathan Riddell's avatar
Jonathan Riddell committed
61
    header("Location: /". $url_dir . '/' . strtolower($correct_category) . '/' . $_GET['application']);
62 63 64
    exit();
}

65 66 67 68 69 70 71 72
$page_title = $app->name();
if (!empty($app->genericName())) {
    $page_title = $page_title." - ".$app->genericName();
}

if ($development) {
    $page_title=$app->name()." - Development Information";
}
73
$page_title_extra_html = '<div class="app-icon"><img src="/' . $url_dir . '/icons/'.$app->icon().'" alt="'.$app->name().' Icon" /></div>';
74

75
function printSidebar($app, $category, $development)
76 77
{
    $content = '';
78 79
    $url_split = explode('/', $_SERVER['REQUEST_URI']);
    $url_dir = $url_split[1];
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

    if ($app->hasHomepage() || $app->hasKDEApps()) {
        $content .= '<div class="infobox"><strong>More about '.$app->name().'</strong>';
        if ($app->hasHomepage()) {
            $content .= '<br /><a href="'.$app->homepage().'">'.$app->name().' Homepage</a>';
        }
        if ($app->hasKDEApps()) {
            $url = htmlspecialchars("http://kde-apps.org/content/show.php?content=".$app->KDEAppsId());
            $content .= '<br /><a href="'.$url.'">'.$app->name().' on KDE-Apps.org</a>';
        }
        $content .= '</div>';
    }

    $content .= '<div class="infobox"><strong>Get help</strong>';
    if ($app->hasUserbase()) {
        $content .= '<br /><a href="'.$app->userbase().'">'.$app->name().' on UserBase</a>';
    }
    $content .= '<br /><a href="'.$app->forumUrl().'">KDE Community Forums</a>';
    if ($app->hasHandbook()) {
        $content .= '<br /><a href="'.$app->handbook().'">'.$app->name().' Handbook</a>';
    }
    $content .= '</div>';

    $content .= '<div class="infobox"><strong>Contact the authors</strong>';

    //Bug tracker links
    if ($app->hasBugTracker()) {
        if ($app->isBugTrackerExternal()) {
            $content .= '<br /><a href="'.htmlentities($app->bugzillaProduct()).'">Report a bug</a>';
        } else { //KDE Bugzilla
            $componentstring = "";
            if ($app->bugzillaComponent()) {
                $componentstring = '&amp;component='.$app->bugzillaComponent();
            }
            $content .= '<br /><a href="https://bugs.kde.org/enter_bug.cgi?format=guided&amp;product='.$app->bugzillaProduct().$componentstring.'">Report a bug</a>';
        }
    } else { //Empty bugtracker, use default link
        $content .= '<br /><a href="https://bugs.kde.org/wizard.cgi">Report a bug</a>';
    }
    foreach ($app->ircChannels() as $channel) {
        $content .= '<br />IRC: <a href="irc://irc.freenode.org/'.$channel.'">'.$channel.' on Freenode</a>';
    }
    foreach ($app->mailingLists() as $ml) {
        //KDE mailing lists
        if (substr($ml, -8, 8) == "@kde.org") {
            $base = substr($ml, 0, -8);
            $content .= '<br />Mailing List: <a href="mailto:'.htmlspecialchars($ml).'">' .htmlspecialchars($base).'</a>';
            $content .= '<br />(<a href="https://mail.kde.org/mailman/listinfo/'.$base.'">subscribe</a>, <a href="https://mail.kde.org/mailman/listinfo/'.$base.'/">list information</a>)';
        } else if (substr($ml, -22, 22) == "@lists.sourceforge.net") { //Sourceforge.net
            $base = substr($ml, 0, -22);
            $content .= '<br />Mailing List: <a href="mailto:'.htmlspecialchars($ml).'">'.htmlspecialchars($base).'</a>';
            $content .= '<br />(<a href="https://lists.sourceforge.net/lists/listinfo/'.$base.'">subscribe</a>, <a href="http://sourceforge.net/mailarchive/forum.php?forum_name='.$base.'">archive</a>)';
        } else if (substr($ml, 0, 31) == "http://groups.google.com/group/") { //Google Groups (web)
            $base = substr($ml, 31, strlen($ml)-31);
            $content .= '<br />Mailing List: <a href="mailto:'.htmlspecialchars($base).'@googlegroups.com">'.htmlspecialchars($base).'</a>';
            $content .= '<br />(<a href="http://groups.google.com/group/'.$base.'/subscribe?note=1">subscribe</a>, <a href="http://groups.google.com/group/'.$base.'/topics">archive</a>)';
        } else if (substr($ml, -17, 17) == "@googlegroups.com") { //Google Groups (mail)
            $base = substr($ml, 0, -17);
            $content .= '<br />Mailing List: <a href="mailto:'.htmlspecialchars($ml).'">'.htmlspecialchars($base).'</a>';
            $content .= '<br />(<a href="http://groups.google.com/group/'.$base.'/subscribe?note=1">subscribe</a>, <a href="http://groups.google.com/group/'.$base.'/topics">archive</a>)';
        } else { //Default mail
            $content .= '<br />Mailing List: <a href="mailto:'.htmlspecialchars($ml).'">'.$app->name().'</a>';
        }
    }
    $content .= '</div>';

146 147 148
    if (!$development) {
        $content .= '<div class="infobox"><strong><a href="'.$_SERVER['REQUEST_URI'].'/development">Development Information</a></strong></div>';
    }
149

Jonathan Riddell's avatar
Jonathan Riddell committed
150 151
    if ($category != 'unmaintained') {
        $content .= <<<EOT
152
            <link href="/{$url_dir}/fonts/css/fontawesome-all.css" rel="stylesheet">
153
            <link rel="stylesheet" href="/{$url_dir}/download.css">
Jonathan Riddell's avatar
Jonathan Riddell committed
154 155 156 157 158 159 160 161

            <div class="infobox"><strong>Get {$app->name()}</strong>
                <div class="downloadButton">
                    <a href="appstream://{$app->AppStreamId()}">
                        <span class="fa fa-download"></span>
                        Install
                    </a>
                </div>
162 163
            </div>
EOT;
Jonathan Riddell's avatar
Jonathan Riddell committed
164
    }
165 166 167 168

    return $content;
}

Jonathan Riddell's avatar
Jonathan Riddell committed
169
function printPage($app, $category)
170 171
{
    //Print screenshot or dummy "no screenshot available" image
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
    $screenshots = $app->getScreenshots();
    if (sizeof($screenshots) === 0) {
        // no screenshot, display dummy "no screenshot available" image
?>
        <div class="d-flex justify-content-center mb-2">
            <img class="img-fluid" src="/images/screenshots/no_screenshot_available.png" alt="No screenshot available" />
        </div>
<?php
    } else if (sizeof($screenshots) === 1) {
        $screenshot = $screenshots[0];
?>
        <div class="d-flex justify-content-center mb-2">
            <a href="<?php echo($screenshot['source-image']); ?>" data-toggle="lightbox">
                <img class="img-fluid" src="<?php echo($screenshot['thumbnails']); ?>" alt="Screenshot <?php echo($app->name()); ?>" />
            </a>
        </div>
<?php
189
    } else {
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
?>
    <div id="carouselAppControls" class="carousel slide" data-ride="carousel">
        <div class="carousel-inner">
<?php
        foreach ($screenshots as $index => $screenshot) { ?>
            <div class='carousel-item <?php echo($index === 0 ? 'active' : ''); ?>'>
                 <a href="<?php echo($screenshot['source-image']); ?>" data-toggle="lightbox">
                    <img src='<?php echo $screenshot['source-image'] ?>' class='w-100 d-block' alt='<?php (isset($screenshot['caption']) ? $screenshot['caption'] : ($app->name() . ' screenshot')); ?>'>
                </a>
            </div>
        <?php
        }
?>
        </div>
        <a class="carousel-control-prev" href="#carouselAppControls" role="button" data-slide="prev" onclick="return false;">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#carouselAppControls" role="button" data-slide="next" onclick="return false;">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
        </a>
    </div>
<?php
214 215
    }

Jonathan Riddell's avatar
Jonathan Riddell committed
216 217 218 219
    if ($category == 'unmaintained') {
        print "<p><b>This app is unmaintained and no longer released by the KDE community.</b></p>";
    }

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    print $app->descriptionHtml();
    if ($app->hasVersions() || $app->hasAuthors() || $app->hasLicense()) {
        if ($app->hasAuthors()) {
            print '<h2>Developed By</h2>';
            print $app->authorHtml();
        }
        if ($app->hasVersions()) {
            ///TODO: Versions not yet implemented
        }
        if ($app->hasLicense()) {
            print '<h2>License</h2>';
            print $app->licenseHtml();
        }
    }

    print '<div style="clear:left;"></div>';
}

238
function printDevelopmentPage($app, $category)
239
{
Jonathan Riddell's avatar
Jonathan Riddell committed
240
    print '<h2>Source Code Repository</h2>';
241

242 243 244 245 246
    if ($category == 'unmaintained') {
        print "<p><b>This app is unmaintained and no longer released by the KDE community.</b></p>";
        return;
    }

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
    print $app->browseSourcesHtml();

    print $app->checkoutSourcesHtml();

    //Show bugzilla related links only for applications hosted at bugs.kde.org
    if ($app->hasBugTracker() && !$app->isBugTrackerExternal()) {
        print '<h2>Search for open bugs</h2>';

        $product = $app->bugzillaProduct();

        $componentstring = "";
        if ($app->bugzillaComponent()) {
            $componentstring = '&component='.$app->bugzillaComponent();
        }

        $majorBugs  = 'https://bugs.kde.org/buglist.cgi?short_desc_type=allwordssubstr&product='.$product.$componentstring.'&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=critical&bug_severity=grave&bug_severity=major&bug_severity=crash';
        $minorBugs  = 'https://bugs.kde.org/buglist.cgi?short_desc_type=allwordssubstr&product='.$product.$componentstring.'&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=normal&bug_severity=minor';
        $wishes     = 'https://bugs.kde.org/buglist.cgi?short_desc_type=allwordssubstr&product='.$product.$componentstring.'&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=wishlist';
        $juniorJobs = 'https://bugs.kde.org/buglist.cgi?keywords=junior-jobs&product='.$product.$componentstring.'&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&cmdtype=doit';

        print '<ul>';
        print '<li><a href="'.htmlspecialchars($majorBugs).'">Major Bug reports</a></li>';
        print '<li><a href="'.htmlspecialchars($minorBugs).'">Minor Bug reports</a></li>';
        print '<li><a href="'.htmlspecialchars($wishes).'">Wish reports</a></li>';
        print '<li><a href="'.htmlspecialchars($juniorJobs).'">Junior Jobs</a></li>';
        print '</ul>';
    }

    if ($app->hasEbn()) {
        print '<h2>Code checking</h2>';
        print '<p>Show results of automated code checking on the English Breakfast Network (EBN).</p>';
        print '<ul>';
        print '<li><a href="'.htmlspecialchars($app->ebnCodeCheckingUrl()).'">Code Checking</a></li>';
        print '<li><a href="'.htmlspecialchars($app->ebnDocCheckingUrl()).'">Documentation Sanitation</a></li>';
        print '</ul>';
    }

}

Jonathan Riddell's avatar
Jonathan Riddell committed
286 287
require('config.php');
require(KDE_ORG . '/aether/config.php');
288

Jonathan Riddell's avatar
Jonathan Riddell committed
289 290 291 292
$pageConfig = array_merge($pageConfig, [
    'title' => $page_title,
    'cssFile' => '/css/applications.css'
]);
293

Jonathan Riddell's avatar
Jonathan Riddell committed
294 295
require(KDE_ORG . '/aether/header.php');
$site_root = "../";
296

Jonathan Riddell's avatar
Jonathan Riddell committed
297
echo '<script src="/js/use-ekko-lightbox.js" defer="true"></script>';
298 299
echo '<main class="container">';

300
echo '<h1><a href="/'.$url_dir.'/">KDE\'s Applications</a> <a href="/'.$url_dir.'/'.$category.'/">'.$category_string.'</a> ';
301 302 303 304 305 306
if ($development) {
    echo '<a href="..">'.$app->name().'</a> Development Information';
} else {
    echo $app->name();
}
echo '</h1>';
Carl Schwan's avatar
Carl Schwan committed
307 308
echo '<div class="row">';
echo '<div class="col-12 col-md-3 order-first order-md-last mb-4">';
Jonathan Riddell's avatar
Jonathan Riddell committed
309
echo '<div id="sidebar">';
310
echo printSidebar($app, $category, $development);
Jonathan Riddell's avatar
Jonathan Riddell committed
311
echo '</div>';
Carl Schwan's avatar
Carl Schwan committed
312 313
echo '</div>';

Jonathan Riddell's avatar
Jonathan Riddell committed
314

Carl Schwan's avatar
Carl Schwan committed
315
echo '<div class="col-12 col-md-9 order-last order-md-first">';
316
if (!$development) {
Jonathan Riddell's avatar
Jonathan Riddell committed
317
    printPage($app, $category);
318
} else {
319
    printDevelopmentPage($app, $category);
320
}
Jonathan Riddell's avatar
Jonathan Riddell committed
321
echo '<br clear="all"/>';
322 323

echo '</main>';
Jonathan Riddell's avatar
Jonathan Riddell committed
324
require(KDE_ORG . '/aether/footer.php');