Skip to content

Commit

Permalink
Port News model to new QueryBuilder
Browse files Browse the repository at this point in the history
- Update News model to use new `is_deleted` and `is_draft` columns with
  the respective database migration
- Update News controller to use new query builder
- Change News editor to only allow drafts for items that have not been
  published yet
  • Loading branch information
allejo committed Feb 5, 2018
1 parent 2427620 commit d05df7c
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 90 deletions.
45 changes: 30 additions & 15 deletions controllers/NewsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,44 @@

class NewsController extends CRUDController
{
public function showAction(News $article)
public function showAction(Player $me, News $article)
{
return array("article" => $article, "categories" => $this->getCategories());
if ($article->isDraft() && (!$me->isValid() || !$me->hasPermission(News::EDIT_PERMISSION))) {
throw new ForbiddenException('You do not have permission to view draft posts.');
}

return [
'article' => $article,
'categories' => $this->getCategories(),
];
}

public function listAction(Request $request, NewsCategory $category = null)
public function listAction(Request $request, Player $me, NewsCategory $category = null)
{
$currentPage = $this->getCurrentPage();
$qb = $this->getQueryBuilder();

$currentPage = $this->getCurrentPage();
$news = $qb
->orderBy('created', 'DESC')
->limit(5)
->fromPage($currentPage)
;

$news = $qb->sortBy('created')->reverse()
->where('category')->is($category)
->limit(5)->fromPage($currentPage)
->getModels();
if ($category !== null) {
$news->where('category', '=', $category->getId());
}

if (!$me->isValid() || !$me->hasPermission(News::CREATE_PERMISSION)) {
$news->whereNot('is_draft', '=', true);
}

return array(
"news" => $news,
"categories" => $this->getCategories(),
"category" => $category,
"currentPage" => $currentPage,
"totalPages" => $qb->countPages()
);
return [
'news' => $news->getModels(true),
'categories' => $this->getCategories(),
'category' => $category,
'currentPage' => $currentPage,
'totalPages' => $qb->countPages(),
];
}

public function createAction(Player $me)
Expand Down
67 changes: 67 additions & 0 deletions migrations/20180202213952_news_status_column_conversion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php


use Phinx\Migration\AbstractMigration;

class NewsStatusColumnConversion extends AbstractMigration
{
public function up()
{
$newsTable = $this->table('news');
$newsTable
->addColumn('is_draft', 'boolean', [
'after' => 'editor',
'null' => false,
'default' => false,
'comment' => 'Whether or not the news article is a draft',
])
->addColumn('is_deleted', 'boolean', [
'after' => 'is_draft',
'null' => false,
'default' => false,
'comment' => 'Whether or not the news article has been soft deleted',
])
->update()
;

$this->query("UPDATE news SET is_draft = 1 WHERE status = 'revision' OR status ='draft';");
$this->query("UPDATE news SET is_deleted = 1 WHERE status = 'deleted' OR status = 'disabled';");

$newsTable
->removeColumn('parent_id')
->removeColumn('status')
->update()
;
}

public function down()
{
$newsTable = $this->table('news');
$newsTable
->addColumn('parent_id', 'integer', [
'after' => 'id',
'null' => true,
'default' => null,
'length' => 11,
'comment' => 'The ID of the original news post. If this column is set, then it is a revision',
])
->addColumn('status', 'set', [
'values' => ['published', 'revision', 'draft', 'disabled', 'deleted'],
'after' => 'editor',
'null' => false,
'default' => 'published',
'comment' => 'The status of the news element',
])
->update()
;

$this->query("UPDATE news SET status = 'draft' WHERE is_draft = 1;");
$this->query("UPDATE news SET status = 'deleted' WHERE is_deleted = 1;");

$newsTable
->removeColumn('is_draft')
->removeColumn('is_deleted')
->update()
;
}
}
91 changes: 53 additions & 38 deletions models/News.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,10 @@ class News extends UrlModel implements NamedModel
*/
protected $editor;

const DEFAULT_STATUS = 'published';
/** @var bool Whether or not the News item is a draft */
protected $is_draft;

/**
* The name of the database table used for queries
*/
const DELETED_COLUMN = 'is_deleted';
const TABLE = "news";

const CREATE_PERMISSION = Permission::CREATE_NEWS;
Expand All @@ -78,7 +77,8 @@ protected function assignResult($news)
$this->updated = TimeDate::fromMysql($news['updated']);
$this->author = $news['author'];
$this->editor = $news['editor'];
$this->status = $news['status'];
$this->is_draft = $news['is_draft'];
$this->is_deleted = $news['is_deleted'];
}

/**
Expand Down Expand Up @@ -181,6 +181,16 @@ public function getName()
return $this->getSubject();
}

/**
* Get whether or not this news article is
*
* @return bool
*/
public function isDraft()
{
return $this->is_draft;
}

/**
* {@inheritdoc}
*/
Expand All @@ -197,6 +207,18 @@ public static function getRouteName($action = 'show')
return "news_$action";
}

/**
* Update the "draft" status of a post
*
* @param bool $draft
*
* @return static
*/
public function setDraft($draft)
{
return $this->updateProperty($this->is_draft, 'is_draft', $draft);
}

/**
* Update the content of a post
*
Expand Down Expand Up @@ -248,6 +270,8 @@ public function updateCategory($categoryID)
*/
public function updateStatus($status = 'published')
{
@trigger_error('The `status` column of the News article has been deprecated. Use `is_draft` or `is_deleted`', E_USER_DEPRECATED);

return $this->updateProperty($this->status, 'status', $status);
}

Expand All @@ -262,35 +286,27 @@ public function updateSubject($subject)
return $this->updateProperty($this->subject, 'subject', $subject);
}

/**
* {@inheritdoc}
*/
public static function getActiveStatuses()
{
return array('published', 'revision');
}

/**
* Add a new news article
*
* @param string $subject The subject of the article
* @param string $content The content of the article
* @param int $authorID The ID of the author
* @param int $categoryId The ID of the category this article will be published under
* @param string $status The status of the article: 'published', 'disabled', or 'deleted'
* @param bool $is_draft Whether or not the added news item should be stored as a draft
*
* @return News An object representing the article that was just created or false if the article was not created
*/
public static function addNews($subject, $content, $authorID, $categoryId = 1, $status = 'published')
public static function addNews($subject, $content, $authorID, $categoryId = 1, $is_draft = false)
{
return self::create(array(
return self::create([
'category' => $categoryId,
'subject' => $subject,
'content' => $content,
'author' => $authorID,
'editor' => $authorID,
'status' => $status,
), array('created', 'updated'));
'is_draft' => $is_draft,
], ['created', 'updated']);
}

/**
Expand All @@ -300,38 +316,37 @@ public static function addNews($subject, $content, $authorID, $categoryId = 1, $
* @param int $limit The amount of matches to be retrieved
* @param bool $getDrafts Whether or not to fetch drafts
*
* @throws Exception When a database is not configured in BZiON
*
* @return News[] An array of news objects
*/
public static function getNews($start = 0, $limit = 5, $getDrafts = false)
{
$ignoredStatuses[] = "deleted";

if (!$getDrafts) {
$ignoredStatuses[] = "draft";
$qb = self::getQueryBuilder()
->limit($limit)
->offset($start)
->orderBy('created', 'DESC')
->active()
;

if ($getDrafts) {
$qb->orWhere('is_draft', '=', true);
}

return self::arrayIdToModel(
self::fetchIdsFrom(
"status", $ignoredStatuses, true,
"ORDER BY created DESC LIMIT $limit OFFSET $start"
)
);
return $qb->getModels(true);
}

/**
* Get a query builder for news
* @return QueryBuilder
*
* @throws Exception
*
* @return QueryBuilderFlex
*/
public static function getQueryBuilder()
{
return new QueryBuilder('News', array(
'columns' => array(
'subject' => 'subject',
'category' => 'category',
'created' => 'created',
'status' => 'status'
),
'name' => 'subject'
));
return QueryBuilderFlex::createForModel(News::class)
->setNameColumn('subject')
;
}
}
23 changes: 13 additions & 10 deletions models/NewsCategory.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,25 @@ public function getStatus()
* @param int $limit The amount of matches to be retrieved
* @param bool $getDrafts Whether or not to fetch drafts
*
* @throws \Pixie\Exception
* @throws Exception
*
* @return News[] An array of news objects
*/
public function getNews($start = 0, $limit = 5, $getDrafts = false)
{
$ignoredStatuses = "";

if (!$getDrafts) {
$ignoredStatuses = "'draft', ";
$qb = News::getQueryBuilder()
->limit($limit)
->offset($start)
->active()
->where('category', '=', $this->getId())
;

if ($getDrafts) {
$qb->whereNot('is_draft', '=', true);
}

$ignoredStatuses .= "'deleted'";

$query = "WHERE status NOT IN ($ignoredStatuses) AND category = ? ";
$query .= "ORDER BY created DESC LIMIT $limit OFFSET $start";

return News::arrayIdToModel(News::fetchIds($query, array($this->getId())));
return $qb->getModels(true);
}

/**
Expand Down
Loading

0 comments on commit d05df7c

Please sign in to comment.