summaryrefslogtreecommitdiffstats
path: root/app/classes
diff options
context:
space:
mode:
authorRomain d'Alverny <rdalverny@gmail.com>2022-01-16 17:01:53 +0100
committerRomain d'Alverny <rdalverny@gmail.com>2022-01-16 17:01:53 +0100
commit58ce95a255c04e1b6ecac0d794bc4dbeb23871de (patch)
tree4205d2da15a4e92dfb8ad59a112ef3d2e1c2c143 /app/classes
parent9d3f003ba2ab29ef6a790535cc586ca20d555d15 (diff)
downloadplanet-58ce95a255c04e1b6ecac0d794bc4dbeb23871de.tar
planet-58ce95a255c04e1b6ecac0d794bc4dbeb23871de.tar.gz
planet-58ce95a255c04e1b6ecac0d794bc4dbeb23871de.tar.bz2
planet-58ce95a255c04e1b6ecac0d794bc4dbeb23871de.tar.xz
planet-58ce95a255c04e1b6ecac0d794bc4dbeb23871de.zip
Add test coverage, add tests, refactor OPML code
Diffstat (limited to 'app/classes')
-rw-r--r--app/classes/CSRF.php4
-rw-r--r--app/classes/Opml.php11
-rw-r--r--app/classes/OpmlManager.php65
3 files changed, 54 insertions, 26 deletions
diff --git a/app/classes/CSRF.php b/app/classes/CSRF.php
index 9a700cf..cf9fc1e 100644
--- a/app/classes/CSRF.php
+++ b/app/classes/CSRF.php
@@ -3,7 +3,7 @@
class CSRF
{
/** @var string */
- const HMAC_ALGORITHM = 'sha1';
+ const HMAC_ALGORITHM = 'sha256';
/** @var string */
const SESSION_KEY_NAME = '_csrf_key';
@@ -48,7 +48,7 @@ class CSRF
public static function getKey()
{
if (empty($_SESSION[self::SESSION_KEY_NAME])) {
- $_SESSION[self::SESSION_KEY_NAME] = random_bytes(16);
+ $_SESSION[self::SESSION_KEY_NAME] = bin2hex(random_bytes(16));
}
return $_SESSION[self::SESSION_KEY_NAME];
}
diff --git a/app/classes/Opml.php b/app/classes/Opml.php
index c5f185f..b91b43e 100644
--- a/app/classes/Opml.php
+++ b/app/classes/Opml.php
@@ -9,6 +9,9 @@ class Opml
public string $ownerEmail = '';
public string $ownerId = '';
+ public string $dateCreated = '';
+ public string $dateModified = '';
+
public string $title = '';
/** @var array<int, string> */
@@ -21,7 +24,7 @@ class Opml
'TITLE' => 'name',
'XMLURL' => 'feed',
'DESCRIPTION' => 'description',
- 'ISDOWN' => 'isDown'
+ 'ISDOWN' => 'isDown',
);
@@ -81,6 +84,12 @@ class Opml
case 'OWNERID':
$this->ownerId = $cdata;
break;
+ case 'DATECREATED':
+ $this->dateCreated = $cdata;
+ break;
+ case 'DATEMODIFIED':
+ $this->dateModified = $cdata;
+ break;
}
}
diff --git a/app/classes/OpmlManager.php b/app/classes/OpmlManager.php
index cd3d685..679d1c4 100644
--- a/app/classes/OpmlManager.php
+++ b/app/classes/OpmlManager.php
@@ -3,7 +3,7 @@
class OpmlManager
{
- public static function load($file)
+ public static function load(string $file) : Opml
{
if (!file_exists($file)) {
throw new Exception('OPML file not found!');
@@ -22,44 +22,63 @@ class OpmlManager
return $opml;
}
- /**
- * @param Opml $opml
- * @param string $file
- */
- public static function save($opml, $file)
+ public static function format(Opml $opml, $freezeDateModified = false) : string
{
- $out = '<?xml version="1.0"?>'."\n";
- $out.= '<opml version="2.0">'."\n";
- $out.= '<head>'."\n";
- $out.= '<title>'.htmlspecialchars($opml->getTitle()).'</title>'."\n";
- $out.= '<dateCreated>'.gmdate('c').'</dateCreated>'."\n";
- $out.= '<dateModified>'.gmdate('c').'</dateModified>'."\n";
+ $owner = '';
if ($opml->ownerName != '') {
- $out.= '<ownerName>'.htmlspecialchars($opml->ownerName).'</ownerName>'."\n";
+ $owner .= '<ownerName>'.htmlspecialchars($opml->ownerName).'</ownerName>'."\n";
}
if ($opml->ownerEmail != '') {
- $out.= '<ownerEmail>'.htmlspecialchars($opml->ownerEmail).'</ownerEmail>'."\n";
+ $owner .= '<ownerEmail>'.htmlspecialchars($opml->ownerEmail).'</ownerEmail>'."\n";
}
if ($opml->ownerId != '') {
- $out.= '<ownerId>'.htmlspecialchars($opml->ownerId).'</ownerId>'."\n";
+ $owner .= '<ownerId>'.htmlspecialchars($opml->ownerId).'</ownerId>'."\n";
}
- $out.= '<docs>http://opml.org/spec2.opml</docs>'."\n";
- $out.= '</head>'."\n";
- $out.= '<body>'."\n";
+ $entries = '';
foreach ($opml->entries as $person) {
- $out .= sprintf(
- '<outline text="%s" htmlUrl="%s" xmlUrl="%s" isDown="%s" />',
+ $entries .= sprintf(
+ "\t" . '<outline text="%s" htmlUrl="%s" xmlUrl="%s" isDown="%s" />',
htmlspecialchars($person['name'], ENT_QUOTES),
htmlspecialchars($person['website'], ENT_QUOTES),
htmlspecialchars($person['feed'], ENT_QUOTES),
htmlspecialchars($person['isDown'] ?? '', ENT_QUOTES)
) . "\n";
}
- $out.= '</body>'."\n";
- $out.= '</opml>';
- file_put_contents($file, $out);
+ $template = <<<XML
+<?xml version="1.0"?>
+<opml version="2.0">
+<head>
+ <title>%s</title>
+ <dateCreated>%s</dateCreated>
+ <dateModified>%s</dateModified>
+ %s
+ <docs>http://opml.org/spec2.opml</docs>
+</head>
+<body>
+%s
+</body>
+</opml>
+XML;
+
+ return sprintf(
+ $template,
+ htmlspecialchars($opml->getTitle()),
+ $opml->dateCreated,
+ $freezeDateModified ? $opml->dateModified : date_format(date_create('now', new DateTimeZone('UTC')), DateTimeInterface::ATOM),
+ $owner,
+ $entries
+ );
+ }
+
+ /**
+ * @param Opml $opml
+ * @param string $file
+ */
+ public static function save(Opml $opml, string $file) : int|bool
+ {
+ return file_put_contents($file, self::format($opml));
}
public static function backup($file)