Refactor API notification usage

- Remove "mapFields()" from BaseModel
- Add new Notification API entity (including collection)
- Add new NotificationFactory method "getApiList()"
This commit is contained in:
nupplaPhil 2020-01-28 21:28:57 +01:00
parent 4a3544582c
commit 582f6bd4a3
No known key found for this signature in database
GPG key ID: D8365C3D36B77D90
9 changed files with 164 additions and 109 deletions

View file

@ -5892,10 +5892,11 @@ api_register_func('api/friendica/activity/unattendmaybe', 'api_friendica_activit
* Returns notifications * Returns notifications
* *
* @param string $type Known types are 'atom', 'rss', 'xml' and 'json' * @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
*
* @return string|array * @return string|array
* @throws BadRequestException
* @throws ForbiddenException * @throws ForbiddenException
* @throws InternalServerErrorException * @throws BadRequestException
* @throws Exception
*/ */
function api_friendica_notification($type) function api_friendica_notification($type)
{ {
@ -5908,7 +5909,7 @@ function api_friendica_notification($type)
throw new BadRequestException("Invalid argument count"); throw new BadRequestException("Invalid argument count");
} }
$notifications = DI::notify()->select(['uid' => api_user()], ['order' => ['seen' => 'ASC', 'date' => 'DESC'], 'limit' => 50]); $notifications = DI::notification()->getApiList(local_user());
if ($type == "xml") { if ($type == "xml") {
$xmlnotes = false; $xmlnotes = false;

View file

@ -17,14 +17,14 @@ abstract class BaseCollection extends \ArrayIterator
protected $totalCount = 0; protected $totalCount = 0;
/** /**
* @param BaseModel[] $models * @param BaseEntity[] $entities
* @param int|null $totalCount * @param int|null $totalCount
*/ */
public function __construct(array $models = [], int $totalCount = null) public function __construct(array $entities = [], int $totalCount = null)
{ {
parent::__construct($models); parent::__construct($entities);
$this->totalCount = $totalCount ?? count($models); $this->totalCount = $totalCount ?? count($entities);
} }
/** /**

View file

@ -11,7 +11,22 @@ namespace Friendica;
*/ */
abstract class BaseEntity implements \JsonSerializable abstract class BaseEntity implements \JsonSerializable
{ {
/**
* Returns the current entity as an json array
*
* @return array
*/
public function jsonSerialize() public function jsonSerialize()
{
return $this->toArray();
}
/**
* Returns the current entity as an array
*
* @return array
*/
public function toArray()
{ {
return get_object_vars($this); return get_object_vars($this);
} }

View file

@ -12,7 +12,7 @@ use Psr\Log\LoggerInterface;
* *
* @property int id * @property int id
*/ */
abstract class BaseModel abstract class BaseModel extends BaseEntity
{ {
/** @var Database */ /** @var Database */
protected $dba; protected $dba;
@ -48,23 +48,9 @@ abstract class BaseModel
$this->originalData = $data; $this->originalData = $data;
} }
/**
* Maps a data array (original/current) to a known field list of the chosen model
*
* This is useful to filter out additional attributes, which aren't part of the db-table (like readonly cached fields)
*
* @param array $data The data array to map to db-fields
*
* @return array the mapped data array
*/
protected function mapFields(array $data)
{
return $data;
}
public function getOriginalData() public function getOriginalData()
{ {
return $this->mapFields($this->originalData); return $this->originalData;
} }
public function resetOriginalData() public function resetOriginalData()
@ -129,16 +115,9 @@ abstract class BaseModel
$this->data[$name] = $value; $this->data[$name] = $value;
} }
/** public function toArray()
* Returns the values of the current model as an array
*
* @param bool $dbOnly True, if just the db-relevant fields should be returned
*
* @return array The values of the current model
*/
public function toArray(bool $dbOnly = false)
{ {
return $dbOnly ? $this->mapFields($this->data) : $this->data; return $this->data;
} }
protected function checkValid() protected function checkValid()

View file

@ -0,0 +1,17 @@
<?php
namespace Friendica\Collection\Api;
use Friendica\BaseCollection;
use Friendica\Object\Api\Friendica\Notification;
class Notifications extends BaseCollection
{
/**
* @return Notification
*/
public function current()
{
return parent::current();
}
}

View file

@ -280,14 +280,6 @@ abstract class DI
return self::$dice->create(Model\User\Cookie::class); return self::$dice->create(Model\User\Cookie::class);
} }
/**
* @return Repository\Notify
*/
public static function notify()
{
return self::$dice->create(Repository\Notify::class);
}
/** /**
* @return Model\Storage\IStorage * @return Model\Storage\IStorage
*/ */
@ -324,6 +316,14 @@ abstract class DI
return self::$dice->create(Repository\ProfileField::class); return self::$dice->create(Repository\ProfileField::class);
} }
/**
* @return Repository\Notify
*/
public static function notify()
{
return self::$dice->create(Repository\Notify::class);
}
// //
// "Protocol" namespace instances // "Protocol" namespace instances
// //

View file

@ -6,6 +6,7 @@ use Exception;
use Friendica\App; use Friendica\App;
use Friendica\App\BaseURL; use Friendica\App\BaseURL;
use Friendica\BaseFactory; use Friendica\BaseFactory;
use Friendica\Collection\Api\Notifications as ApiNotifications;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\PConfig\IPConfig; use Friendica\Core\PConfig\IPConfig;
@ -15,6 +16,7 @@ use Friendica\Database\Database;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Module\BaseNotifications; use Friendica\Module\BaseNotifications;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Object\Api\Friendica\Notification as ApiNotification;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Repository; use Friendica\Repository;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
@ -352,4 +354,26 @@ class Notification extends BaseFactory
return $formattedNotifications; return $formattedNotifications;
} }
/**
* @param int $uid The user id of the API call
* @param array $params Additional parameters
*
* @return ApiNotifications
*
* @throws Exception
*/
public function getApiList(int $uid, array $params = ['order' => ['seen' => 'ASC', 'date' => 'DESC'], 'limit' => 50])
{
$notifies = $this->notification->select(['uid' => $uid], $params);
/** @var ApiNotification[] $notifications */
$notifications = [];
foreach ($notifies as $notify) {
$notifications[] = new ApiNotification($notify);
}
return new ApiNotifications($notifications);
}
} }

View file

@ -5,19 +5,12 @@ namespace Friendica\Model;
use Exception; use Exception;
use Friendica\BaseModel; use Friendica\BaseModel;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
/** /**
* Model for an entry in the notify table * Model for an entry in the notify table
* - Including additional, calculated properties
*
* Is used either for frontend interactions or for API-based interaction
* @see https://github.com/friendica/friendica/blob/develop/doc/API-Entities.md#notification
* *
* @property string hash * @property string hash
* @property integer type * @property integer type
@ -36,11 +29,6 @@ use Psr\Log\LoggerInterface;
* *
* @property-read string name_cache Full name of the contact subject * @property-read string name_cache Full name of the contact subject
* @property-read string msg_cache Plaintext version of the notification text with a placeholder (`{0}`) for the subject contact's name. * @property-read string msg_cache Plaintext version of the notification text with a placeholder (`{0}`) for the subject contact's name.
*
* @property-read integer timestamp Unix timestamp
* @property-read string dateRel Time since the note was posted, eg "1 hour ago"
* @property-read string $msg_html
* @property-read string $msg_plain
*/ */
class Notify extends BaseModel class Notify extends BaseModel
{ {
@ -59,8 +47,7 @@ class Notify extends BaseModel
$this->repo = $repo; $this->repo = $repo;
$this->setNameCache(); $this->setNameCache();
$this->setTimestamp(); $this->setMsgCache();
$this->setMsg();
} }
/** /**
@ -81,41 +68,23 @@ class Notify extends BaseModel
} }
} }
/**
* Set some extra properties to the notification from db:
* - timestamp as int in default TZ
* - date_rel : relative date string
*/
private function setTimestamp()
{
try {
$this->timestamp = strtotime(DateTimeFormat::local($this->date));
} catch (Exception $e) {
}
$this->dateRel = Temporal::getRelativeDate($this->date);
}
/** /**
* Sets the pre-formatted name (caching) * Sets the pre-formatted name (caching)
*
* @throws InternalServerErrorException
*/ */
private function setNameCache() private function setNameCache()
{ {
$this->name_cache = strip_tags(BBCode::convert($this->source_name ?? '')); try {
$this->name_cache = strip_tags(BBCode::convert($this->source_name ?? ''));
} catch (InternalServerErrorException $e) {
}
} }
/** /**
* Set some extra properties to the notification from db: * Sets the pre-formatted msg (caching)
* - msg_html: message as html string
* - msg_plain: message as plain text string
* - msg_cache: The pre-formatted message (caching)
*/ */
private function setMsg() private function setMsgCache()
{ {
try { try {
$this->msg_html = BBCode::convert($this->msg, false);
$this->msg_plain = explode("\n", trim(HTML::toPlaintext($this->msg_html, 0)))[0];
$this->msg_cache = self::formatMessage($this->name_cache, strip_tags(BBCode::convert($this->msg))); $this->msg_cache = self::formatMessage($this->name_cache, strip_tags(BBCode::convert($this->msg)));
} catch (InternalServerErrorException $e) { } catch (InternalServerErrorException $e) {
} }
@ -125,12 +94,8 @@ class Notify extends BaseModel
{ {
parent::__set($name, $value); parent::__set($name, $value);
if ($name == 'date') {
$this->setTimestamp();
}
if ($name == 'msg') { if ($name == 'msg') {
$this->setMsg(); $this->setMsgCache();
} }
if ($name == 'source_name') { if ($name == 'source_name') {
@ -163,29 +128,4 @@ class Notify extends BaseModel
return $message; return $message;
} }
/**
* {@inheritDoc}
*/
protected function mapFields(array $data)
{
return [
'hash' => $data['hash'] ?? '',
'type' => $data['type'] ?? 0,
'name' => $data['name'] ?? '',
'url' => $data['url'] ?? '',
'photo' => $data['photo'] ?? '',
'date' => $data['date'] ?? DateTimeFormat::utcNow(),
'msg' => $data['msg'] ?? '',
'uid' => $data['uid'] ?? 0,
'link' => $data['link'] ?? '',
'iid' => $data['iid'] ?? 0,
'parent' => $data['parent'] ?? 0,
'seen' => $data['seen'] ?? false,
'verb' => $data['verb'] ?? '',
'otype' => $data['otype'] ?? '',
'name_cache' => $data['name_cache'] ?? null,
'msg_cache' => $data['msg_cache'] ?? null,
];
}
} }

View file

@ -0,0 +1,79 @@
<?php
namespace Friendica\Object\Api\Friendica;
use Friendica\BaseEntity;
use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Model\Notify;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal;
/**
* Friendica Notification
*
* @see https://github.com/friendica/friendica/blob/develop/doc/API-Entities.md#notification
*/
class Notification extends BaseEntity
{
/** @var integer */
protected $id;
/** @var string */
protected $hash;
/** @var integer */
protected $type;
/** @var string Full name of the contact subject */
protected $name;
/** @var string Profile page URL of the contact subject */
protected $url;
/** @var string Profile photo URL of the contact subject */
protected $photo;
/** @var string YYYY-MM-DD hh:mm:ss local server time */
protected $date;
/** @var string The message (BBCode) */
protected $msg;
/** @var integer Owner User Id */
protected $uid;
/** @var string Notification URL */
protected $link;
/** @var integer Item Id */
protected $iid;
/** @var integer Parent Item Id */
protected $parent;
/** @var boolean Whether the notification was read or not. */
protected $seen;
/** @var string Verb URL @see http://activitystrea.ms */
protected $verb;
/** @var string Subject type (`item`, `intro` or `mail`) */
protected $otype;
/** @var string Full name of the contact subject (HTML) */
protected $name_cache;
/** @var string Plaintext version of the notification text with a placeholder (`{0}`) for the subject contact's name. (Plaintext) */
protected $msg_cache;
/** @var integer Unix timestamp */
protected $timestamp;
/** @var string Time since the note was posted, eg "1 hour ago" */
protected $date_rel;
/** @var string Message (HTML) */
protected $msg_html;
/** @var string Message (Plaintext) */
protected $msg_plain;
public function __construct(Notify $notify)
{
// map each notify attribute to the entity
foreach ($notify->toArray() as $key => $value) {
$this->{$key} = $value;
}
// add additional attributes for the API
try {
$this->timestamp = strtotime(DateTimeFormat::local($this->date));
$this->msg_html = BBCode::convert($this->msg, false);
$this->msg_plain = explode("\n", trim(HTML::toPlaintext($this->msg_html, 0)))[0];
} catch (\Exception $e) {
}
$this->date_rel = Temporal::getRelativeDate($this->date);
}
}