Added sorting by tag usage dates to tag list
This commit is contained in:
parent
c1f8a5e632
commit
9e29441c68
7 changed files with 124 additions and 36 deletions
|
@ -4,6 +4,8 @@ use \Chibi\Sql as Sql;
|
|||
final class TagEntity extends AbstractEntity implements IValidatable, ISerializable
|
||||
{
|
||||
private $name;
|
||||
private $creationDate;
|
||||
private $updateDate;
|
||||
|
||||
public function fillNew()
|
||||
{
|
||||
|
@ -13,6 +15,8 @@ final class TagEntity extends AbstractEntity implements IValidatable, ISerializa
|
|||
{
|
||||
$this->id = (int) $row['id'];
|
||||
$this->name = $row['name'];
|
||||
$this->creationDate = TextHelper::toIntegerOrNull($row['creation_date']);
|
||||
$this->updateDate = TextHelper::toIntegerOrNull($row['update_date']);
|
||||
|
||||
if (isset($row['post_count']))
|
||||
$this->setCache('post_count', (int) $row['post_count']);
|
||||
|
@ -57,6 +61,16 @@ final class TagEntity extends AbstractEntity implements IValidatable, ISerializa
|
|||
return $this->name;
|
||||
}
|
||||
|
||||
public function getCreationDate()
|
||||
{
|
||||
return $this->creationDate;
|
||||
}
|
||||
|
||||
public function getUpdateDate()
|
||||
{
|
||||
return $this->updateDate;
|
||||
}
|
||||
|
||||
public function getPostCount()
|
||||
{
|
||||
if ($this->hasCache('post_count'))
|
||||
|
|
|
@ -43,47 +43,69 @@ final class PostModel extends AbstractCrudModel
|
|||
$stmt->setCriterion(Sql\Functors::equals('id', new Sql\Binding($post->getId())));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
|
||||
//tags
|
||||
$tags = $post->getTags();
|
||||
|
||||
$stmt = Sql\Statements::delete();
|
||||
$stmt->setTable('post_tag');
|
||||
$stmt->setCriterion(Sql\Functors::equals('post_id', new Sql\Binding($post->getId())));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
|
||||
foreach ($tags as $postTag)
|
||||
{
|
||||
$stmt = Sql\Statements::insert();
|
||||
$stmt->setTable('post_tag');
|
||||
$stmt->setColumn('post_id', new Sql\Binding($post->getId()));
|
||||
$stmt->setColumn('tag_id', new Sql\Binding($postTag->getId()));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
}
|
||||
|
||||
//relations
|
||||
$relations = $post->getRelations();
|
||||
|
||||
$stmt = Sql\Statements::delete();
|
||||
$stmt->setTable('crossref');
|
||||
$binding = new Sql\Binding($post->getId());
|
||||
$stmt->setCriterion(Sql\Functors::disjunction()
|
||||
->add(Sql\Functors::equals('post_id', $binding))
|
||||
->add(Sql\Functors::equals('post2_id', $binding)));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
|
||||
foreach ($relations as $relatedPost)
|
||||
{
|
||||
$stmt = Sql\Statements::insert();
|
||||
$stmt->setTable('crossref');
|
||||
$stmt->setColumn('post_id', new Sql\Binding($post->getId()));
|
||||
$stmt->setColumn('post2_id', new Sql\Binding($relatedPost->getId()));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
}
|
||||
self::saveTags($post);
|
||||
self::saveRelations($post);
|
||||
});
|
||||
|
||||
return $post;
|
||||
}
|
||||
|
||||
private static function saveTags($post)
|
||||
{
|
||||
$newTagIds = array_map(function($tag) { return $tag->getId(); }, $post->getTags());
|
||||
|
||||
$stmt = Sql\Statements::select();
|
||||
$stmt->setTable('post_tag');
|
||||
$stmt->setColumn('tag_id');
|
||||
$stmt->setCriterion(Sql\Functors::equals('post_id', new Sql\Binding($post->getId())));
|
||||
$rows = Core::getDatabase()->fetchAll($stmt);
|
||||
$oldTagIds = array_map(function($row) { return $row['tag_id']; }, $rows);
|
||||
|
||||
$tagIdsToInsert = array_diff($newTagIds, $oldTagIds);
|
||||
$tagIdsToDelete = array_diff($oldTagIds, $newTagIds);
|
||||
|
||||
if (count($tagIdsToDelete))
|
||||
{
|
||||
$stmt = Sql\Statements::delete();
|
||||
$stmt->setTable('post_tag');
|
||||
$stmt->setCriterion(Sql\Functors::conjunction()
|
||||
->add(Sql\Functors::in('tag_id', Sql\Binding::fromArray($tagIdsToDelete)))
|
||||
->add(Sql\Functors::equals('post_id', new Sql\Binding($post->getId()))));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
}
|
||||
|
||||
foreach ($tagIdsToInsert as $tagIdToInsert)
|
||||
{
|
||||
$stmt = Sql\Statements::insert();
|
||||
$stmt->setTable('post_tag');
|
||||
$stmt->setColumn('post_id', new Sql\Binding($post->getId()));
|
||||
$stmt->setColumn('tag_id', new Sql\Binding($tagIdToInsert));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
}
|
||||
}
|
||||
|
||||
private static function saveRelations($post)
|
||||
{
|
||||
$relations = $post->getRelations();
|
||||
|
||||
$stmt = Sql\Statements::delete();
|
||||
$stmt->setTable('crossref');
|
||||
$binding = new Sql\Binding($post->getId());
|
||||
$stmt->setCriterion(Sql\Functors::disjunction()
|
||||
->add(Sql\Functors::equals('post_id', $binding))
|
||||
->add(Sql\Functors::equals('post2_id', $binding)));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
|
||||
foreach ($relations as $relatedPost)
|
||||
{
|
||||
$stmt = Sql\Statements::insert();
|
||||
$stmt->setTable('crossref');
|
||||
$stmt->setColumn('post_id', new Sql\Binding($post->getId()));
|
||||
$stmt->setColumn('post2_id', new Sql\Binding($relatedPost->getId()));
|
||||
Core::getDatabase()->execute($stmt);
|
||||
}
|
||||
}
|
||||
|
||||
protected static function removeSingle($post)
|
||||
{
|
||||
Core::getDatabase()->transaction(function() use ($post)
|
||||
|
|
|
@ -38,6 +38,10 @@ class TagSearchParser extends AbstractSearchParser
|
|||
{
|
||||
if ($orderByString == 'popularity')
|
||||
$this->statement->setOrderBy('post_count', $orderDir);
|
||||
elseif ($orderByString == 'creation_date')
|
||||
$this->statement->setOrderBy('tag.creation_date', $orderDir);
|
||||
elseif ($orderByString == 'update_date')
|
||||
$this->statement->setOrderBy('tag.update_date', $orderDir);
|
||||
elseif ($orderByString == 'alpha')
|
||||
$this->statement->setOrderBy(Sql\Functors::{'case'}('tag.name'), $orderDir);
|
||||
else
|
||||
|
|
15
src/Upgrades/mysql/Upgrade17.sql
Normal file
15
src/Upgrades/mysql/Upgrade17.sql
Normal file
|
@ -0,0 +1,15 @@
|
|||
ALTER TABLE tag ADD COLUMN creation_date INTEGER DEFAULT NULL;
|
||||
ALTER TABLE tag ADD COLUMN update_date INTEGER DEFAULT NULL;
|
||||
|
||||
DROP TRIGGER post_tag_insert;
|
||||
CREATE TRIGGER post_tag_insert AFTER INSERT ON post_tag FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE post SET tag_count = tag_count + 1 WHERE post.id = NEW.post_id;
|
||||
UPDATE tag SET update_date = UNIX_TIMESTAMP() WHERE tag.id = NEW.tag_id;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER tag_insert BEFORE INSERT ON tag FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.creation_date = UNIX_TIMESTAMP();
|
||||
SET NEW.update_date = UNIX_TIMESTAMP();
|
||||
END;
|
15
src/Upgrades/sqlite/Upgrade17.sql
Normal file
15
src/Upgrades/sqlite/Upgrade17.sql
Normal file
|
@ -0,0 +1,15 @@
|
|||
ALTER TABLE tag ADD COLUMN creation_date INTEGER DEFAULT NULL;
|
||||
ALTER TABLE tag ADD COLUMN update_date INTEGER DEFAULT NULL;
|
||||
|
||||
DROP TRIGGER post_tag_insert;
|
||||
CREATE TRIGGER post_tag_insert AFTER INSERT ON post_tag FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE post SET tag_count = tag_count + 1 WHERE post.id = NEW.post_id;
|
||||
UPDATE tag SET update_date = STRFTIME('%s', 'NOW') WHERE tag.id = NEW.tag_id;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER tag_insert AFTER INSERT ON tag FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE tag SET creation_date = STRFTIME('%s', 'NOW') WHERE tag.id = NEW.id;
|
||||
UPDATE tag SET update_date = STRFTIME('%s', 'NOW') WHERE tag.id = NEW.id;
|
||||
END;
|
|
@ -7,6 +7,8 @@
|
|||
'order:alpha,desc' => 'Sort Z→A',
|
||||
'order:popularity,desc' => 'Often used first',
|
||||
'order:popularity,asc' => 'Rarely used first',
|
||||
'order:update_date,desc' => 'Recently used',
|
||||
'order:creation_date,desc' => 'Recently created',
|
||||
];
|
||||
?>
|
||||
|
||||
|
|
16
tests/Tests/ModelTests/TagModelTest.php
Normal file
16
tests/Tests/ModelTests/TagModelTest.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
class TagModelTest extends AbstractTest
|
||||
{
|
||||
public function testSavingAndRetrieving()
|
||||
{
|
||||
$tag = TagModel::spawn();
|
||||
$tag->setName('test');
|
||||
|
||||
TagModel::save($tag);
|
||||
$otherTag = TagModel::getById($tag->getId());
|
||||
|
||||
$this->assert->areEqual($tag->getName(), $otherTag->getName());
|
||||
$this->assert->areEqual(time(), $otherTag->getCreationDate());
|
||||
$this->assert->areEqual(time(), $otherTag->getUpdateDate());
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue