summaryrefslogtreecommitdiffstats
path: root/public/admin
diff options
context:
space:
mode:
Diffstat (limited to 'public/admin')
-rwxr-xr-xpublic/admin/administration.php59
-rw-r--r--public/admin/changepassword.php12
-rwxr-xr-xpublic/admin/default.css232
-rw-r--r--public/admin/img/button-add.pngbin0 -> 244 bytes
-rw-r--r--public/admin/img/button-delete.pngbin0 -> 201 bytes
-rw-r--r--public/admin/img/button-h.pngbin0 -> 212 bytes
-rw-r--r--public/admin/img/button.pngbin0 -> 212 bytes
-rw-r--r--public/admin/img/h3.pngbin0 -> 212 bytes
-rw-r--r--public/admin/img/moonmoon.pngbin0 -> 564 bytes
-rw-r--r--public/admin/img/nav-admin.pngbin0 -> 1519 bytes
-rw-r--r--public/admin/img/nav-feed.pngbin0 -> 1090 bytes
-rw-r--r--public/admin/inc/auth.inc.php9
-rwxr-xr-xpublic/admin/index.php149
-rwxr-xr-xpublic/admin/login.php51
-rw-r--r--public/admin/logout.php10
-rw-r--r--public/admin/purgecache.php24
-rwxr-xr-xpublic/admin/subscriptions.php84
-rwxr-xr-xpublic/admin/template.php54
18 files changed, 684 insertions, 0 deletions
diff --git a/public/admin/administration.php b/public/admin/administration.php
new file mode 100755
index 0000000..09b5f85
--- /dev/null
+++ b/public/admin/administration.php
@@ -0,0 +1,59 @@
+<?php
+
+require_once __DIR__ . '/../../app/app.php';
+require_once __DIR__ . '/inc/auth.inc.php';
+
+
+$opml = OpmlManager::load($PlanetConfig->getOpmlFile());
+$opml_people = $opml->getPeople();
+$page_id = 'admin-admin';
+$header_extra = <<<"HTML"
+ <script>
+ window.onload = function(){
+ var formManage = document.getElementById('frmPurge');
+ formManage.onsubmit = function(){
+ return confirm("{$l10n->getString('Are you sure you want to purge the cache?')}");
+ }
+ }
+ </script>
+
+HTML;
+
+$repo_url = 'https://github.com/moonmoon/moonmoon';
+$releases_url = "$repo_url/releases";
+$link_url = "<a href='$releases_url'>$releases_url</a>";
+$version_current = str_replace('%s', $moon_version, $l10n->getString('Your moonmoon instance version is %s.'));
+$version_action = str_replace('%s', $link_url, $l10n->getString('You can check for a more recent version on: %s.'));
+
+$page_content = <<<"FRAGMENT"
+
+ <div class="widget">
+ <h3>{$l10n->getString('Clear cache')}</h3>
+ <form action="purgecache.php" method="post" id="frmPurge">
+ <input type="hidden" value="{$csrf->generate('frmPurge')}" name="_csrf">
+ <p><label>{$l10n->getString('Clear cache:')}</label><input type="submit" class="submit delete" name="purge" id="purge" value="{$l10n->getString('Clear')}" /></p>
+ <p class="help">{$l10n->getString('Clearing the cache will make moonmoon reload all feeds.')}</p>
+ </form>
+ </div>
+
+ <div class="widget">
+ <h3>{$l10n->getString('Change administrator password')}</h3>
+ <form action="changepassword.php" method="post" id="frmPassword">
+ <input type="hidden" value="{$csrf->generate('frmPassword')}" name="_csrf">
+ <p><label for="password">{$l10n->getString('New password:')}</label> <input type="password" class="text" value="" name="password" id="password" size="20" /> <input type="submit" class="submit delete" name="changepwd" id="changepwd" value="{$l10n->getString('Change password')}" /></p>
+ </form>
+ </div>
+
+ <div class="widget">
+ <h3>{$l10n->getString('Upgrade moonmoon')}</h3>
+ <form>
+ <p>{$version_current}</p>
+ <p>{$version_action}</p>
+ </form>
+ </div>
+
+FRAGMENT;
+
+$footer_extra = '';
+$admin_access = 1;
+require_once __DIR__ . '/template.php';
diff --git a/public/admin/changepassword.php b/public/admin/changepassword.php
new file mode 100644
index 0000000..c1e61ff
--- /dev/null
+++ b/public/admin/changepassword.php
@@ -0,0 +1,12 @@
+<?php
+
+require_once __DIR__.'/../app/app.php';
+require_once __DIR__.'/inc/auth.inc.php';
+
+if ($csrf->verify($_POST['_csrf'], 'frmPassword') && isset($_POST['password']) && ('' != $_POST['password'])) {
+ $out = sprintf('<?php $login="admin"; $password="%s"; ?>', hash('sha256', $_POST['password']));
+ file_put_contents(__DIR__.'/inc/pwd.inc.php', $out);
+ die("Password changed. <a href='administration.php'>Login</a>");
+} else {
+ die('Can not change password');
+}
diff --git a/public/admin/default.css b/public/admin/default.css
new file mode 100755
index 0000000..fcba3f4
--- /dev/null
+++ b/public/admin/default.css
@@ -0,0 +1,232 @@
+html, body{
+ margin: 0;
+ padding: 0;
+}
+html{
+ font-size: 62.5%;
+}
+body{
+ background: #FFF;
+ color: #333;
+ font: 1.1em/1.6em "Lucida Grande", Tahoma, Arial, sans-serif;
+}
+
+
+fieldset{
+ border: 0;
+ padding: 0;
+ margin: 1em 0;
+}
+input.text{
+ border: 1px solid #BBB;
+ padding: 4px;
+}
+input.submit{
+ font-size: 1em;
+ padding: 4px;
+ background: #D1D1D1 url(img/button.png) repeat-x left center;
+ border: 1px solid #FFF;
+ border-bottom: 1px solid #CECECE;
+ border-right: 1px solid #CECECE;
+ cursor: pointer;
+}
+input.submit:hover{
+ background: #D1D1D1 url(img/button-h.png) repeat-x left center;
+ color: #000;
+ border: 1px solid #FFF;
+ border-bottom: 1px solid #C6C6C6;
+ border-right: 1px solid #C6C6C6;
+}
+input.delete{
+ margin-left: 1em;
+}
+input.delete:hover{
+ background: #ffabab url(img/button-delete.png) repeat-x left center;
+ color: #C00;
+ border: 1px solid #FCC;
+ border-bottom: 1px solid #F99;
+ border-right: 1px solid #F99;
+}
+input.add{
+ font-weight: bold;
+}
+input.add:hover{
+ background: #65a5e1 url(img/button-add.png) repeat-x left center;
+ color: #20466a;
+ border: 1px solid #a6c7e5;
+ border-bottom: 1px solid #4f90cd;
+ border-right: 1px solid #4f90cd;
+}
+p.help{
+ font-size: 0.8em;
+ color: #999;
+ margin: 0;
+}
+
+#page{
+}
+
+ header{
+ background: #E0E0E0 url(img/moonmoon.png) no-repeat right center;
+ border-top: 5px solid #D0D0D0;
+ margin: 0;
+ padding: 10px;
+ }
+ header h1{
+ display: none;
+ margin: 0 0 0 20px;
+ padding: 0;
+ height: 14px;
+ width: 95px;
+ background: transparent url(img/moonmoon.png) no-repeat left center;
+
+ overflow: hidden;
+ text-indent: -1000em;
+ }
+ header p{
+ margin: 0 0 0 20px;
+ padding: 0;
+ }
+ header p a{
+ color: #AAA;
+ }
+ header p a:hover{
+ color: #111;
+ }
+
+
+ nav ul{
+ margin: 20px 30px;
+ padding: 0;
+ list-style: none;
+ }
+ nav ul:after {content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+ nav ul {display: inline-table;}
+ /* Hides from IE-mac \*/
+ * html nav ul {height: 1%;}
+ nav ul {display: block;}
+ /* End hide from IE-mac */
+
+ nav ul li{
+ display: block;
+ float: left;
+ }
+ nav ul li a{
+ display: block;
+ border: 1px solid #DDD;
+ padding: 8px 8px 8px 36px;
+ margin-right: 8px;
+ text-decoration: none;
+ color: #666;
+ background-repeat: no-repeat;
+ background-position: 6px center;
+ }
+ nav ul li a:hover,
+ body#admin-feed #nav-feed a,
+ body#admin-admin #nav-admin a {
+ background-color: #f0f2f6;
+ border-color: #AAA;
+ color: #111;
+ }
+ #nav-feed a{
+ background-image: url(img/nav-feed.png);
+ }
+ #nav-admin a{
+ background-image: url(img/nav-admin.png);
+ }
+
+ #content{
+ margin: 20px 30px;
+ }
+
+ .widget{
+ margin: 20px 0;
+ }
+ .widget h3{
+ background: #3e4350 url(img/h3.png) repeat-x left center;
+ color: #FFF;
+ text-transform: uppercase;
+ margin: 0;
+ padding: 10px;
+ }
+ .widget form{
+ padding: 10px;
+ border: 1px solid #EEE;
+ border-top: 0;
+ }
+
+ #feedmanage p.select{
+ margin: 3px 0;
+ }
+ #feedmanage p.action span.count{
+ float: right;
+ padding-right: 10px;
+ font-size: 1.3em;
+ }
+ #feedmanage table{
+ width: 99%;
+ border-collapse: collapse;
+ border: 1px solid #f0f2f6;
+ }
+ #feedmanage thead th{
+ background: #f0f2f6;
+ text-align: left;
+ padding: 6px;
+ }
+ #feedmanage thead span{
+ display: none;
+ }
+ #feedmanage tr{
+ border-bottom: 1px solid #e8ebf1;
+ }
+ #feedmanage tr.even td{
+ background: #f0f2f6;
+ width: auto;
+ }
+ #feedmanage .text{
+ background: transparent;
+ border: 1px solid #FFF;
+ width: 90%;
+ }
+ #feedmanage tr.even td .text{
+ border: 1px solid #f0f2f6;
+ }
+ #feedmanage tr td input.text:focus{
+ background: #FFF;
+ border: 1px solid #4392b7;
+ }
+
+ #feedmanage tr.selected td{
+ background: #ffabab;
+ background: #4392b7;
+ color: #FFF;
+ }
+ #feedmanage tr.selected td .text{
+ color: #FFF;
+ border: 1px solid #4392b7;
+ }
+ #feedmanage tr td input.text:focus{
+ background: #FFF;
+ color: #000;
+ border: 1px solid #4392b7;
+ }
+
+/* Login form
+*******************************************************************************/
+form.login {
+ width: 400px;
+ margin: 0 auto;
+}
+form.login fieldset {
+ border: 1px solid #CCC;
+ text-align: center;
+}
+
+p.logout {
+ float: right;
+ margin: 20px 30px 0 0;
+}
+ p.logout a {
+ padding: 8px;
+ display: block;
+ }
diff --git a/public/admin/img/button-add.png b/public/admin/img/button-add.png
new file mode 100644
index 0000000..859364a
--- /dev/null
+++ b/public/admin/img/button-add.png
Binary files differ
diff --git a/public/admin/img/button-delete.png b/public/admin/img/button-delete.png
new file mode 100644
index 0000000..7bfebc2
--- /dev/null
+++ b/public/admin/img/button-delete.png
Binary files differ
diff --git a/public/admin/img/button-h.png b/public/admin/img/button-h.png
new file mode 100644
index 0000000..0a43a6a
--- /dev/null
+++ b/public/admin/img/button-h.png
Binary files differ
diff --git a/public/admin/img/button.png b/public/admin/img/button.png
new file mode 100644
index 0000000..fad6ccc
--- /dev/null
+++ b/public/admin/img/button.png
Binary files differ
diff --git a/public/admin/img/h3.png b/public/admin/img/h3.png
new file mode 100644
index 0000000..0c86748
--- /dev/null
+++ b/public/admin/img/h3.png
Binary files differ
diff --git a/public/admin/img/moonmoon.png b/public/admin/img/moonmoon.png
new file mode 100644
index 0000000..26cc8f4
--- /dev/null
+++ b/public/admin/img/moonmoon.png
Binary files differ
diff --git a/public/admin/img/nav-admin.png b/public/admin/img/nav-admin.png
new file mode 100644
index 0000000..3077a54
--- /dev/null
+++ b/public/admin/img/nav-admin.png
Binary files differ
diff --git a/public/admin/img/nav-feed.png b/public/admin/img/nav-feed.png
new file mode 100644
index 0000000..00c896b
--- /dev/null
+++ b/public/admin/img/nav-feed.png
Binary files differ
diff --git a/public/admin/inc/auth.inc.php b/public/admin/inc/auth.inc.php
new file mode 100644
index 0000000..32615e7
--- /dev/null
+++ b/public/admin/inc/auth.inc.php
@@ -0,0 +1,9 @@
+<?php
+
+include config_path('pwd.inc.php');
+
+if (!Planet::authenticateUser($_COOKIE['auth'] ?? '', $password)) {
+ setcookie('auth', '', time() - 3600);
+ header('Location: login.php');
+ die();
+}
diff --git a/public/admin/index.php b/public/admin/index.php
new file mode 100755
index 0000000..37939ea
--- /dev/null
+++ b/public/admin/index.php
@@ -0,0 +1,149 @@
+<?php
+
+require_once __DIR__ . '/../../app/app.php';
+require_once __DIR__ . '/inc/auth.inc.php';
+
+if (!$PlanetConfig::isInstalled()) {
+ die('<p>' . _g('You might want to <a href="../install.php">install moonmoon</a>.') . '</p>');
+}
+
+//Instantiate app
+$Planet = new Planet($PlanetConfig);
+
+//Load
+if (0 < $Planet->loadOpml($PlanetConfig->getOpmlFile())) {
+ $Planet->loadFeeds();
+ $items = $Planet->getItems();
+}
+
+$everyone = $Planet->getPeople();
+$count_feeds = count($everyone);
+$page_id = 'admin-feed';
+$footer_extra = <<<FRAGMENT
+ <script>
+ var allCheckboxes = function(status){
+ var form = document.getElementById('feedmanage');
+ var selectboxes = form.getElementsByTagName('input');
+ for (var i=0; i<selectboxes.length; i++){
+ if ('checkbox' == selectboxes[i].type){
+ selectboxes[i].checked = status;
+ }
+ }
+ }
+
+ window.onload = function(){
+ //Select/unselect rows
+ var form = document.getElementById('feedmanage');
+ var selectboxes = form.getElementsByTagName('input');
+ for (var i=0; i<selectboxes.length; i++){
+ if ('checkbox' == selectboxes[i].type) {
+ selectboxes[i].onchange = function() {
+ var tr = this.parentNode.parentNode;
+ if (this.checked) {
+ tr.className += ' selected';
+ } else {
+ tr.className = tr.className.replace('selected','');
+ }
+ }
+ }
+ }
+
+ var btSelectall = document.getElementById('selectall');
+ btSelectall.onclick = function(){
+ allCheckboxes('checked');
+ }
+
+ var btSelectnone = document.getElementById('selectnone');
+ btSelectnone.onclick = function(){
+ allCheckboxes('');
+ }
+ }
+ </script>
+FRAGMENT;
+
+ob_start();
+?>
+
+ <div class="widget">
+ <h3><?=_g('Add Feed')?></h3>
+ <form action="subscriptions.php" method="post" id="feedimport">
+ <fieldset>
+ <label for="url"><?=_g('Link:')?></label>
+ <input type="text" class="text" name="url" id="url" placeholder="http://" class="text" size="50" />
+ <input type="submit" class="submit add" name="add" value="<?=_g('Add Feed')?>" />
+ </fieldset>
+ <p class="help"><?=_g('Accepted formats are RSS and ATOM. If the link is not a feed, moonmoon will try to autodiscover the feed.')?></p>
+ <input type="hidden" value="<?php echo $csrf->generate('feedmanage'); ?>" name="_csrf">
+ </form>
+ </div>
+
+ <div class="widget">
+ <h3><?=_g('Manage existing feeds')?></h3>
+ <form action="subscriptions.php" method="post" id="feedmanage">
+ <p class="action">
+ <span class="count"><?php echo sprintf(_g('Number of feeds: %s'), $count_feeds)?></span>
+ <input type="hidden" value="<?php echo $csrf->generate('feedmanage'); ?>" name="_csrf">
+ <input type="submit" class="submit save" name="save" id="save" value="<?=_g('Save changes')?>" />
+ <input type="submit" class="submit delete" name="delete" id="delete" value="<?=_g('Delete selected Feeds')?>" />
+ </p>
+ <p class="select"><?=_g('Select :')?> <a href="javascript:void(0);" id="selectall"><?=_g('All')?></a>, <a href="javascript:void(0);" id="selectnone"><?=_g('None')?></a></p>
+ <table>
+ <thead>
+ <tr>
+ <th><span><?=_g('Selection')?></span></th>
+ <th><?=_g('Name')?></th>
+ <th><?=_g('Last entry')?></th>
+ <th><?=_g('Website link')?></th>
+ <th><?=_g('Feed link')?></th>
+ <th><?=_g('Unavailable')?></th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $i = 0;
+ foreach ($everyone as $opml_person) {
+ $i++;
+ ?>
+ <tr class="<?=($i%2)?'odd':'even'; ?>">
+ <td><input type="checkbox" class="checkbox" name="opml[<?=$i; ?>][delete]" /></td>
+ <td><input type="text" size="10" class="text" name="opml[<?=$i; ?>][name]" value="<?=$opml_person->getName(); ?>" /></td>
+ <td>
+ <?php
+ $items = $opml_person->get_items();
+ if (count($items) > 0) {
+ echo $items[0]->get_date();
+ } else {
+ echo _g('Not in cache');
+ }
+ $check_is_down = $opml_person->getIsDown() === '1' ? 'checked="checked"' : '';
+ ?>
+ </td>
+ <td><input type="text" size="30" class="text" name="opml[<?=$i; ?>][website]" value="<?=$opml_person->getWebsite(); ?>" /></td>
+ <td><input type="text" size="30" class="text" name="opml[<?=$i; ?>][feed]" value="<?=$opml_person->getFeed(); ?>" /></td>
+ <td><input type="checkbox" readonly="readonly" name="opml[<?=$i; ?>][isDown]" <?=$check_is_down?> value="1" /></td>
+ </tr>
+ <?php } ?>
+ </tbody>
+ </table>
+ </form>
+ </div>
+
+ <div class="widget">
+ <h3><?=_g('Upload OPML file')?></h3>
+ <form action="subscriptions.php" method="post" id="opmlimport" enctype="multipart/form-data">
+ <p>Beware! This will totally erase and replace the list of your feeds just above.</p>
+ <fieldset>
+ <label for="url"><?=_g('File:')?></label>
+ <input type="file" class="text" name="opml" id="opml" class="text" size="50" />
+ <input type="submit" class="submit add" name="upload" value="<?=_g('Upload OPML file and replace existing feeds')?>" />
+ </fieldset>
+ <input type="hidden" value="<?php echo $csrf->generate('feedmanage'); ?>" name="_csrf">
+ </form>
+ </div>
+
+<?php
+$page_content = ob_get_contents();
+ob_end_clean();
+
+$admin_access = 1;
+require_once __DIR__ . '/template.php';
diff --git a/public/admin/login.php b/public/admin/login.php
new file mode 100755
index 0000000..418bbe6
--- /dev/null
+++ b/public/admin/login.php
@@ -0,0 +1,51 @@
+<?php
+
+require_once __DIR__ . '/../../app/app.php';
+
+if (isset($_POST['password'])) {
+ session_regenerate_id();
+
+ $hash_pwd = hash('sha256', $_POST['password']);
+
+ // check if old moonmoon was installed and convert stored password
+ // from md5 to current hash function
+ $md5_pwd = md5($_POST['password']);
+ $passfile = config_path('pwd.inc.php');
+ include($passfile);
+
+ if ($md5_pwd == $password) {
+ error_log("Migrating password from md5 to sha256");
+ file_put_contents($passfile, sprintf('<?php $login="admin"; $password="%s"; ?>', $hash_pwd));
+ }
+
+ setcookie('auth', $hash_pwd);
+ header('Location: index.php');
+}
+
+$page_content = <<<FRAGMENT
+ <form action="" method="post" class="login">
+ <fieldset>
+ <p class="field">
+ <label for="password">{$l10n->getString('Password:')}</label>
+ <input type="password" name="password" id="password"/>
+ <input type="submit" class="submit" value="{$l10n->getString('OK')}"/>
+ </p>
+ </fieldset>
+ </form>
+FRAGMENT;
+
+$footer_extra = <<<FRAGMENT
+ <script type="text/javascript">
+ <!--
+ window.onload = function() {
+ document.getElementById('password').focus();
+ }
+ -->
+ </script>
+
+FRAGMENT;
+
+$page_id = 'admin-login';
+$admin_access = 0;
+
+require_once __DIR__ . '/template.php';
diff --git a/public/admin/logout.php b/public/admin/logout.php
new file mode 100644
index 0000000..25a3e4c
--- /dev/null
+++ b/public/admin/logout.php
@@ -0,0 +1,10 @@
+<?php
+
+require_once __DIR__ . '/../../app/app.php';
+
+setcookie('auth', '', time() - 3600);
+session_destroy();
+session_regenerate_id();
+
+header('Location: login.php');
+die();
diff --git a/public/admin/purgecache.php b/public/admin/purgecache.php
new file mode 100644
index 0000000..d47f9a7
--- /dev/null
+++ b/public/admin/purgecache.php
@@ -0,0 +1,24 @@
+<?php
+
+require_once __DIR__.'/../../app/app.php';
+require_once __DIR__.'/inc/auth.inc.php';
+
+if (isset($_POST['purge'])) {
+ $dir = __DIR__.'/../../cache/';
+
+ $dh = opendir($dir);
+
+ while ($filename = readdir($dh)) {
+ if ($filename == '.' or $filename == '..') {
+ continue;
+ }
+
+ $file = $dir . DIRECTORY_SEPARATOR . $filename;
+ if (is_file($file) && filemtime($file) < time()) {
+ unlink($file);
+ }
+ }
+}
+
+header('Location: administration.php');
+die();
diff --git a/public/admin/subscriptions.php b/public/admin/subscriptions.php
new file mode 100755
index 0000000..418e354
--- /dev/null
+++ b/public/admin/subscriptions.php
@@ -0,0 +1,84 @@
+<?php
+
+require_once __DIR__ . '/../../app/app.php';
+require_once __DIR__ . '/inc/auth.inc.php';
+
+function removeSlashes(&$item, $key)
+{
+ $item = stripslashes($item);
+}
+
+if (!$csrf->verify($_POST['_csrf'], 'feedmanage')) {
+ die('Invalid CSRF token!');
+}
+
+$opmlFile = $PlanetConfig->getOpmlFile();
+
+if (isset($_POST['upload']) &&
+ isset($_FILES['opml']) &&
+ is_uploaded_file($_FILES['opml']['tmp_name']) &&
+ $_FILES['opml']['size'] > 0) {
+ OpmlManager::backup($opmlFile);
+ $newOpml = new Opml();
+ $newOpml->parse(file_get_contents($_FILES['opml']['tmp_name']));
+ OpmlManager::save($newOpml, $opmlFile);
+} elseif (isset($_POST['opml']) || isset($_POST['add'])) {
+ // Load old OPML
+ $oldOpml = OpmlManager::load($opmlFile);
+ if ($PlanetConfig->getName() === '') {
+ $PlanetConfig->setName($oldOpml->getTitle());
+ }
+ $newOpml = new Opml();
+ $newOpml->title = $PlanetConfig->getName();
+
+ // Remove slashes if needed
+ if (isset($_POST['opml'])) {
+ array_walk_recursive($_POST['opml'], 'removeSlashes');
+ }
+ // Delete/Save feeds
+ if (isset($_POST['delete']) || isset($_POST['save'])) {
+ foreach ($_POST['opml'] as $person) {
+ if (isset($_POST['delete'])) {
+ //delete mode, check if to be deleted
+ if (!isset($person['delete'])) {
+ $newOpml->entries[] = $person;
+ }
+ } else {
+ $newOpml->entries[] = $person;
+ }
+ }
+ }
+
+ // Add feed
+ if (isset($_POST['add'])) {
+ if ('http://' != $_POST['url']) {
+ //autodiscover feed
+ $feed = new SimplePie();
+ $feed->enable_cache(false);
+ $feed->set_feed_url($_POST['url']);
+ if (!$PlanetConfig->checkCertificates()) {
+ $feed->set_curl_options([
+ CURLOPT_SSL_VERIFYHOST => false,
+ CURLOPT_SSL_VERIFYPEER => false
+ ]);
+ }
+ $feed->init();
+ $feed->handle_content_type();
+ $person['name'] = html_entity_decode($feed->get_title());
+ $person['website'] = $feed->get_permalink();
+ $person['feed'] = $feed->feed_url;
+ $person['isDown'] = '0';
+
+ $oldOpml->entries[] = $person;
+ }
+ $newOpml->entries = $oldOpml->entries;
+ }
+
+ // Backup old OPML
+ OpmlManager::backup($opmlFile);
+
+ // Save new OPML
+ OpmlManager::save($newOpml, $opmlFile);
+}
+header("Location: index.php");
+die();
diff --git a/public/admin/template.php b/public/admin/template.php
new file mode 100755
index 0000000..964c639
--- /dev/null
+++ b/public/admin/template.php
@@ -0,0 +1,54 @@
+<?php if (!isset($admin_access)) {
+ return;
+} ?>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>
+
+<?php
+ echo _g('Administration') . ' — ';
+ printf(_g('moonmoon %s', '%s is the version number for moonmoon, this string appears as the tab title in the admin panel'), $moon_version);
+?>
+ </title>
+ <link rel="stylesheet" media="screen" type="text/css" href="default.css">
+<!--[if lte IE 9]>
+<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+<![endif]-->
+
+ <?=@$header_extra ?: ''; ?>
+
+</head>
+
+<body id="<?=@$page_id ?: ''; ?>">
+ <div id="page">
+ <header>
+ <h1>moonmoon</h1>
+ <p><a href="../"><?=_g('Back to main page')?></a></p>
+ </header>
+
+ <?php if ($admin_access == 1) : ?>
+ <p class="logout"><a href="logout.php"><?=_g('Logout')?></a></p>
+ <nav>
+ <ul>
+ <li id="nav-feed"><a href="index.php"><?=_g('Feeds')?></a></li>
+ <li id="nav-admin"><a href="administration.php"><?=_g('Administration')?></a></li>
+ </ul>
+ </nav>
+
+ <?php endif; ?>
+
+
+
+ <div id="content">
+
+ <?=@$page_content ?: ''; ?>
+
+ </div>
+ </div>
+
+<?=@$footer_extra ?: ''; ?>
+
+</body>
+</html>