27 changed files with 617 additions and 238 deletions
@ -1,29 +0,0 @@
|
||||
<?php |
||||
/** |
||||
* @copyright Copyright (C) 2010-2021, the Friendica project |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace Friendica\Collection; |
||||
|
||||
use Friendica\BaseCollection; |
||||
|
||||
class Introductions extends BaseCollection |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,9 @@
|
||||
<?php |
||||
|
||||
namespace Friendica\Contact\Introduction\Collection; |
||||
|
||||
use Friendica\BaseCollection; |
||||
|
||||
class Introductions extends BaseCollection |
||||
{ |
||||
} |
@ -0,0 +1,209 @@
|
||||
<?php |
||||
/** |
||||
* @copyright Copyright (C) 2010-2021, the Friendica project |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace Friendica\Contact\Introduction\Depository; |
||||
|
||||
use Friendica\BaseDepository; |
||||
use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException; |
||||
use Friendica\Contact\Introduction\Exception\IntroductionPersistenceException; |
||||
use Friendica\Contact\Introduction\Collection; |
||||
use Friendica\Contact\Introduction\Entity; |
||||
use Friendica\Contact\Introduction\Factory; |
||||
use Friendica\Database\Database; |
||||
use Friendica\Network\HTTPException\NotFoundException; |
||||
use Friendica\Util\DateTimeFormat; |
||||
use Psr\Log\LoggerInterface; |
||||
|
||||
class Introduction extends BaseDepository |
||||
{ |
||||
/** @var Factory\Introduction */ |
||||
protected $factory; |
||||
|
||||
protected static $table_name = 'intro'; |
||||
|
||||
public function __construct(Database $database, LoggerInterface $logger, Factory\Introduction $factory) |
||||
{ |
||||
parent::__construct($database, $logger, $factory); |
||||
} |
||||
|
||||
/** |
||||
* @param array $condition |
||||
* @param array $params |
||||
* |
||||
* @return Entity\Introduction |
||||
* |
||||
* @throws NotFoundException the underlying exception if there's no Introduction with the given conditions |
||||
*/ |
||||
private function selectOne(array $condition, array $params = []): Entity\Introduction |
||||
{ |
||||
return parent::_selectOne($condition, $params); |
||||
} |
||||
|
||||
/** |
||||
* Converts a given Introduction into a DB compatible row array |
||||
* |
||||
* @param Entity\Introduction $introduction |
||||
* |
||||
* @return array |
||||
*/ |
||||
protected function convertToTableRow(Entity\Introduction $introduction): array |
||||
{ |
||||
return [ |
||||
'uid' => $introduction->uid, |
||||
'contact-id' => $introduction->cid, |
||||
'suggest-cid' => $introduction->sid, |
||||
'knowyou' => $introduction->knowyou ? 1 : 0, |
||||
'note' => $introduction->note, |
||||
'hash' => $introduction->hash, |
||||
'ignore' => $introduction->ignore ? 1 : 0, |
||||
'datetime' => $introduction->datetime->format(DateTimeFormat::MYSQL), |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @param int $id |
||||
* @param int $uid |
||||
* |
||||
* @return Entity\Introduction |
||||
* |
||||
* @throws IntroductionNotFoundException in case there is no Introduction with this id |
||||
*/ |
||||
public function selectOneById(int $id, int $uid): Entity\Introduction |
||||
{ |
||||
try { |
||||
return $this->selectOne(['id' => $id, 'uid' => $uid]); |
||||
} catch (NotFoundException $exception) { |
||||
throw new IntroductionNotFoundException(sprintf('There is no Introduction with the ID %d for the user %d', $id, $uid), $exception); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Selects introductions for a given user |
||||
* |
||||
* @param int $uid |
||||
* @param int|null $min_id |
||||
* @param int|null $max_id |
||||
* @param int $limit |
||||
* |
||||
* @return Collection\Introductions |
||||
*/ |
||||
public function selectForUser(int $uid, int $min_id = null, int $max_id = null, int $limit = self::LIMIT): Collection\Introductions |
||||
{ |
||||
try { |
||||
$BaseCollection = parent::_selectByBoundaries( |
||||
['`uid = ?` AND NOT `ignore`',$uid], |
||||
['order' => ['id' => 'DESC']], |
||||
$min_id, $max_id, $limit); |
||||
} catch (\Exception $e) { |
||||
throw new IntroductionPersistenceException(sprintf('Cannot select Introductions for used %d', $uid), $e); |
||||
} |
||||
|
||||
return new Collection\Introductions($BaseCollection->getArrayCopy(), $BaseCollection->getTotalCount()); |
||||
} |
||||
|
||||
/** |
||||
* Selects the introduction for a given contact |
||||
* |
||||
* @param int $cid |
||||
* |
||||
* @return Entity\Introduction |
||||
* |
||||
* @throws IntroductionNotFoundException in case there is not Introduction for this contact |
||||
*/ |
||||
public function selectForContact(int $cid): Entity\Introduction |
||||
{ |
||||
try { |
||||
return $this->selectOne(['contact-id' => $cid]); |
||||
} catch (NotFoundException $exception) { |
||||
throw new IntroductionNotFoundException(sprintf('There is no Introduction for the contact %d', $cid), $exception); |
||||
} |
||||
} |
||||
|
||||
public function countActiveForUser($uid, array $params = []): int |
||||
{ |
||||
try { |
||||
return $this->count(['ignore' => false, 'uid' => $uid], $params); |
||||
} catch (\Exception $e) { |
||||
throw new IntroductionPersistenceException(sprintf('Cannot count Introductions for used %d', $uid), $e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Checks, if the suggested contact already exists for the user |
||||
* |
||||
* @param int $sid |
||||
* @param int $uid |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public function suggestionExistsForUser(int $sid, int $uid): bool |
||||
{ |
||||
try { |
||||
return $this->exists(['uid' => $uid, 'suggest-cid' => $sid]); |
||||
} catch (\Exception $e) { |
||||
throw new IntroductionPersistenceException(sprintf('Cannot check suggested Introduction for contact %d and user %d', $sid, $uid), $e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param Entity\Introduction $introduction |
||||
* |
||||
* @return bool |
||||
* |
||||
* @throws IntroductionPersistenceException in case the underlying storage cannot delete the Introduction |
||||
*/ |
||||
public function delete(Entity\Introduction $introduction): bool |
||||
{ |
||||
if (!$introduction->id) { |
||||
return false; |
||||
} |
||||
|
||||
try { |
||||
return $this->db->delete(self::$table_name, ['id' => $introduction->id]); |
||||
} catch (\Exception $e) { |
||||
throw new IntroductionPersistenceException(sprintf('Cannot delete Introduction with id %d', $introduction->id), $e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param Entity\Introduction $introduction |
||||
* |
||||
* @return Entity\Introduction |
||||
* |
||||
* @throws IntroductionPersistenceException In case the underlying storage cannot save the Introduction |
||||
*/ |
||||
public function save(Entity\Introduction $introduction): Entity\Introduction |
||||
{ |
||||
try { |
||||
$fields = $this->convertToTableRow($introduction); |
||||
|
||||
if ($introduction->id) { |
||||
$this->db->update(self::$table_name, $fields, ['id' => $introduction->id]); |
||||
return $this->factory->createFromTableRow($fields); |
||||
} else { |
||||
$this->db->insert(self::$table_name, $fields); |
||||
return $this->selectOneById($this->db->lastInsertId(), $introduction->uid); |
||||
} |
||||
} catch (\Exception $exception) { |
||||
throw new IntroductionPersistenceException(sprintf('Cannot insert/update the Introduction %d for user %d', $introduction->id, $introduction->uid), $exception); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,89 @@
|
||||
<?php |
||||
/** |
||||
* @copyright Copyright (C) 2010-2021, the Friendica project |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace Friendica\Contact\Introduction\Entity; |
||||
|
||||
use Friendica\BaseEntity; |
||||
|
||||
/** |
||||
* @property-read int $uid |
||||
* @property-read int $cid |
||||
* @property-read int|null $sid |
||||
* @property-read bool $knowyou |
||||
* @property-read string $note |
||||
* @property-read string $hash |
||||
* @property-read \DateTime $datetime |
||||
* @property-read bool $ignore |
||||
* @property-read int|null $id |
||||
*/ |
||||
class Introduction extends BaseEntity |
||||
{ |
||||
/** @var int */ |
||||
protected $uid; |
||||
/** @var int */ |
||||
protected $cid; |
||||
/** @var int|null */ |
||||
protected $sid; |
||||
/** @var bool */ |
||||
protected $knowyou; |
||||
/** @var string */ |
||||
protected $note; |
||||
/** @var string */ |
||||
protected $hash; |
||||
/** @var \DateTime */ |
||||
protected $datetime; |
||||
/** @var bool */ |
||||
protected $ignore; |
||||
/** @var int|null */ |
||||
protected $id; |
||||
|
||||
/** |
||||
* @param int $uid |
||||
* @param int $cid |
||||
* @param int|null $sid |
||||
* @param bool $knowyou |
||||
* @param string $note |
||||
* @param string $hash |
||||
* @param \DateTime $datetime |
||||
* @param bool $ignore |
||||
* @param int|null $id |
||||
*/ |
||||
public function __construct(int $uid, int $cid, ?int $sid, bool $knowyou, string $note, string $hash, \DateTime $datetime, bool $ignore, ?int $id) |
||||
{ |
||||
$this->uid = $uid; |
||||
$this->cid = $cid; |
||||
$this->sid = $sid; |
||||
$this->knowyou = $knowyou; |
||||
$this->note = $note; |
||||
$this->hash = $hash; |
||||
$this->datetime = $datetime; |
||||
$this->ignore = $ignore; |
||||
$this->id = $id; |
||||
} |
||||
|
||||
/** |
||||
* Ignore the current Introduction |
||||
*/ |
||||
public function ignore() |
||||
{ |
||||
$this->ignore = true; |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
<?php |
||||
|
||||
namespace Friendica\Contact\Introduction\Exception; |
||||
|
||||
class IntroductionNotFoundException extends \OutOfBoundsException |
||||
{ |
||||
public function __construct($message = "", \Throwable $previous = null) |
||||
{ |
||||
parent::__construct($message, 404, $previous); |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
<?php |
||||
|
||||
namespace Friendica\Contact\Introduction\Exception; |
||||
|
||||
class IntroductionPersistenceException extends \RuntimeException |
||||
{ |
||||
public function __construct($message = "", \Throwable $previous = null) |
||||
{ |
||||
parent::__construct($message, 500, $previous); |
||||
} |
||||
} |
@ -0,0 +1,73 @@
|
||||
<?php |
||||
/** |
||||
* @copyright Copyright (C) 2010-2021, the Friendica project |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace Friendica\Contact\Introduction\Factory; |
||||
|
||||
use Friendica\BaseFactory; |
||||
use Friendica\Contact\Introduction\Entity; |
||||
use Friendica\Capabilities\ICanCreateFromTableRow; |
||||
use Friendica\Util\DateTimeFormat; |
||||
use Friendica\Util\Strings; |
||||
|
||||
class Introduction extends BaseFactory implements ICanCreateFromTableRow |
||||
{ |
||||
/** |
||||
* @inheritDoc |
||||
*/ |
||||
public function createFromTableRow(array $row): Entity\Introduction |
||||
{ |
||||
return new Entity\Introduction( |
||||
$row['uid'] ?? 0, |
||||
$row['contact-id'] ?? 0, |
||||
$row['suggest-cid'] ?? null, |
||||
!empty($row['knowyou']), |
||||
$row['note'] ?? '', |
||||
$row['hash'] ?? '', |
||||
new \DateTime($row['datetime'] ?? 'now', new \DateTimeZone('UTC')), |
||||
!empty($row['ignore']), |
||||
$row['id'] ?? null |
||||
); |
||||
} |
||||
|
||||
public function createNew( |
||||
int $uid, |
||||
int $cid, |
||||
string $note, |
||||
int $sid = null, |
||||
bool $knowyou = false |
||||
): Entity\Introduction { |
||||
return $this->createFromTableRow([ |
||||
'uid' => $uid, |
||||
'suggest-cid' => $sid, |
||||
'contact-id' => $cid, |
||||
'knowyou' => $knowyou, |
||||
'note' => $note, |
||||
'hash' => Strings::getRandomHex(), |
||||
'datetime' => DateTimeFormat::utcNow(), |
||||
'ignore' => false, |
||||
]); |
||||
} |
||||
|
||||
public function createDummy(?int $id): Entity\Introduction |
||||
{ |
||||
return $this->createFromTableRow(['id' => $id]); |
||||
} |
||||
} |
@ -1,79 +0,0 @@
|
||||
<?php |
||||
/** |
||||
* @copyright Copyright (C) 2010-2021, the Friendica project |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace Friendica\Repository; |
||||
|
||||
use Friendica\BaseRepository; |
||||
use Friendica\Collection; |
||||
use Friendica\Model; |
||||
|
||||
class Introduction extends BaseRepository |
||||
{ |
||||
protected static $table_name = 'intro'; |
||||
|
||||
protected static $model_class = Model\Introduction::class; |
||||
|
||||
protected static $collection_class = Collection\Introductions::class; |
||||
|
||||
/** |
||||
* @param array $data |
||||
* @return Model\Introduction |
||||
*/ |
||||
protected function create(array $data) |
||||
{ |
||||
return new Model\Introduction($this->dba, $this->logger, $this, $data); |
||||
} |
||||
|
||||
/** |
||||
* @param array $condition |
||||
* @return Model\Introduction |
||||
* @throws \Friendica\Network\HTTPException\NotFoundException |
||||
*/ |
||||
public function selectFirst(array $condition) |
||||
{ |
||||
return parent::selectFirst($condition); |
||||
} |
||||
|
||||
/** |
||||
* @param array $condition |
||||
* @param array $params |
||||
* @return Collection\Introductions |
||||
* @throws \Exception |
||||
*/ |
||||
public function select(array $condition = [], array $params = []) |
||||
{ |
||||
return parent::select($condition, $params); |
||||
} |
||||
|
||||
/** |
||||
* @param array $condition |
||||
* @param array $params |
||||
* @param int|null $min_id |
||||
* @param int|null $max_id |
||||
* @param int $limit |
||||
* @return Collection\Introductions |
||||
* @throws \Exception |
||||
*/ |
||||
public function selectByBoundaries(array $condition = [], array $params = [], int $min_id = null, int $max_id = null, int $limit = self::LIMIT) |
||||
{ |
||||
return parent::selectByBoundaries($condition, $params, $min_id, $max_id, $limit); |
||||
} |
||||
} |
@ -0,0 +1,113 @@
|
||||
<?php |
||||
|
||||
namespace Friendica\Test\src\Contact\Introduction\Factory; |
||||
|
||||
use Friendica\Contact\Introduction\Factory\Introduction; |
||||
use PHPUnit\Framework\TestCase; |
||||
use Psr\Log\NullLogger; |
||||
|
||||
class IntroductionTest extends TestCase |
||||
{ |
||||
public function dataRow() |
||||
{ |
||||
return [ |
||||
'default' => [ |
||||
'input' => [ |
||||
'uid' => 42, |
||||
'suggest-cid' => 13, |
||||
'contact-id' => 24, |
||||
'knowyou' => 1, |
||||
'note' => 'a note', |
||||
'hash' => '12345', |
||||
'datetime' => '1970-01-01 00:00:00', |
||||
'ignore' => 0, |
||||
'id' => 56, |
||||
], |
||||
'assertion' => [ |
||||
'uid' => 42, |
||||
'suggest-cid' => 13, |
||||
'contact-id' => 24, |
||||
'knowyou' => true, |
||||
'note' => 'a note', |
||||
'hash' => '12345', |
||||
'datetime' => new \DateTime('1970-01-01 00:00:00', new \DateTimeZone('UTC')), |
||||
'ignore' => false, |
||||
'id' => 56, |
||||
] |
||||
], |
||||
'empty' => [ |
||||
'input' => [ |
||||
], |
||||
'assertion' => [ |
||||
'uid' => 0, |
||||
'contact-id' => 0, |
||||
'suggest-cid' => null, |
||||
'knowyou' => false, |
||||
'note' => '', |
||||
'ignore' => false, |
||||
'id' => null, |
||||
] |
||||
], |
||||
]; |
||||
} |
||||
|
||||
public function assertIntro(\Friendica\Contact\Introduction\Entity\Introduction $intro, array $assertion) |
||||
{ |
||||
self::assertEquals($intro->id, $assertion['id'] ?? null); |
||||
self::assertEquals($intro->uid, $assertion['uid'] ?? 0); |
||||
self::assertEquals($intro->cid, $assertion['contact-id'] ?? 0); |
||||
self::assertEquals($intro->sid, $assertion['suggest-cid'] ?? null); |
||||
self::assertEquals($intro->knowyou, $assertion['knowyou'] ?? false); |
||||
self::assertEquals($intro->note, $assertion['note'] ?? ''); |
||||
if (isset($assertion['hash'])) { |
||||
self::assertEquals($intro->hash, $assertion['hash']); |
||||
} else { |
||||
self::assertIsString($intro->hash); |
||||
} |
||||
if (isset($assertion['datetime'])) { |
||||
self::assertEquals($intro->datetime, $assertion['datetime']); |
||||
} else { |
||||
self::assertInstanceOf(\DateTime::class, $intro->datetime); |
||||
} |
||||
self::assertEquals($intro->ignore, $assertion['ignore'] ?? false); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider dataRow |
||||
*/ |
||||
public function testCreateFromTableRow(array $input, array $assertion) |
||||
{ |
||||
$factory = new Introduction(new NullLogger()); |
||||
|
||||
$intro = $factory->createFromTableRow($input); |
||||
$this->assertIntro($intro, $assertion); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider dataRow |
||||
*/ |
||||
public function testCreateNew(array $input, array $assertion) |
||||
{ |
||||
$factory = new Introduction(new NullLogger()); |
||||
|
||||
$intro = $factory->createNew($input['uid'] ?? 0, $input['cid'] ?? 0, $input['note'] ?? ''); |
||||
|
||||
$this->assertIntro($intro, [ |
||||
'uid' => $input['uid'] ?? 0, |
||||
'contact-id' => $input['cid'] ?? 0, |
||||
'note' => $input['note'] ?? '', |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider dataRow |
||||
*/ |
||||
public function testCreateDummy(array $input, array $assertion) |
||||
{ |
||||
$factory = new Introduction(new NullLogger()); |
||||
|
||||
$intro = $factory->createDummy($input['id'] ?? null); |
||||
|
||||
$this->assertIntro($intro, ['id' => $input['id'] ?? null]); |
||||
} |
||||
} |
Loading…
Reference in new issue