Skip to content

Commit

Permalink
Add migration to convert article and article category to many to many
Browse files Browse the repository at this point in the history
  • Loading branch information
thecodeholic committed Jan 26, 2017
1 parent feb0487 commit 902ffdb
Show file tree
Hide file tree
Showing 10 changed files with 369 additions and 97 deletions.
2 changes: 2 additions & 0 deletions controllers/ArticleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use centigen\i18ncontent\models\ArticleCategory;
use centigen\i18ncontent\web\Controller;
use Yii;
use yii\helpers\ArrayHelper;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;

Expand Down Expand Up @@ -99,6 +100,7 @@ public function actionCreate()
public function actionUpdate($id)
{
$model = $this->findModel($id);
$model->category_ids = ArrayHelper::getColumn($model->articleCategoryArticles, 'category_id');

$articleCategories = ArticleCategory::getCategories();
$locales = BaseHelper::getAvailableLocales();
Expand Down
55 changes: 55 additions & 0 deletions migrations/m170126_070327_article_category_article_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

use yii\db\Migration;
use yii\db\Schema;

class m170126_070327_article_category_article_table extends Migration
{
public function up()
{
$this->createTable(\centigen\i18ncontent\models\ArticleCategoryArticle::tableName(), [
'id' => Schema::TYPE_PK,
'article_id' => Schema::TYPE_INTEGER . '(11) NOT NULL',
'category_id' => Schema::TYPE_INTEGER . '(11) NOT NULL',
'created_at' => Schema::TYPE_INTEGER,
'updated_at' => Schema::TYPE_INTEGER,
]);

// $articles = \centigen\i18ncontent\models\Article::find()->all();
// $trans = Yii::$app->db->beginTransaction();
// foreach ($articles as $article) {
// $articleArticleCategory =
// }

$this->createIndex('idx_article_category_article_article_id', \centigen\i18ncontent\models\ArticleCategoryArticle::tableName(), 'article_id');
$this->addForeignKey('fk_article_category_article_article', \centigen\i18ncontent\models\ArticleCategoryArticle::tableName(), 'article_id',
\centigen\i18ncontent\models\Article::tableName(), 'id', 'cascade', 'cascade');
$this->createIndex('idx_article_category_article_article_category_id', \centigen\i18ncontent\models\ArticleCategoryArticle::tableName(), 'article_category_id');
$this->addForeignKey('fk_article_category_article_article_category', \centigen\i18ncontent\models\ArticleCategoryArticle::tableName(), 'article_category_id',
\centigen\i18ncontent\models\ArticleCategory::tableName(), 'id', 'cascade', 'cascade');


}

public function down()
{
$this->dropForeignKey('fk_article_category_article_article', \centigen\i18ncontent\models\ArticleCategoryArticle::tableName());
$this->dropIndex('idx_article_category_article_article_id', \centigen\i18ncontent\models\ArticleCategoryArticle::tableName());

$this->dropForeignKey('fk_article_category_article_article_category', \centigen\i18ncontent\models\ArticleCategoryArticle::tableName());
$this->dropIndex('idx_article_category_article_category_id', \centigen\i18ncontent\models\ArticleCategoryArticle::tableName());

$this->dropTable(\centigen\i18ncontent\models\ArticleCategoryArticle::tableName());
}

/*
// Use safeUp/safeDown to run migration code within a transaction
public function safeUp()
{
}
public function safeDown()
{
}
*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

use yii\db\Migration;

class m170126_072252_migrate_to_article_category_article_table extends Migration
{
public function safeUp()
{
$articles = \centigen\i18ncontent\models\Article::find()->all();

$trans = Yii::$app->db->beginTransaction();
foreach ($articles as $article){
$articleCategoryArticle = new \centigen\i18ncontent\models\ArticleCategoryArticle();
$articleCategoryArticle->article_category_id = $article->category_id;
$articleCategoryArticle->article_id = $article->id;
if (!$articleCategoryArticle->save()){
$trans->rollBack();
return false;
}
}

$trans->commit();

$this->dropForeignKey('fk_article_category', \centigen\i18ncontent\models\Article::tableName());
$this->dropIndex('idx_category_id', \centigen\i18ncontent\models\Article::tableName());
$this->dropColumn(\centigen\i18ncontent\models\Article::tableName(), 'category_id');

return null;
}

public function down()
{
echo "m170126_072252_migrate_to_article_category_article_table cannot be reverted.\n";

return false;
}

/*
// Use safeUp/safeDown to run migration code within a transaction
public function safeUp()
{
}
public function safeDown()
{
}
*/
}
100 changes: 72 additions & 28 deletions models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

namespace centigen\i18ncontent\models;

use centigen\base\helpers\UtilHelper;
use centigen\i18ncontent\models\query\ArticleQuery;
use trntv\filekit\behaviors\UploadBehavior;
use Yii;
use yii\behaviors\BlameableBehavior;
use yii\behaviors\SluggableBehavior;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveQuery;
use yii\helpers\ArrayHelper;

/**
* This is the model class for table "article".
Expand All @@ -22,7 +24,6 @@
* @property array $attachments
* @property integer $author_id
* @property integer $updater_id
* @property integer $category_id
* @property integer $status
* @property integer $published_at
* @property integer $position
Expand All @@ -31,7 +32,7 @@
*
* @property string $title
* @property string $body
* @property ArticleCategory $category
* @property ArticleCategoryArticle[] $articleCategoryArticles
* @property ArticleAttachment[] $articleAttachments
* @property ArticleTranslation[] $translations
* @property ArticleTranslation $activeTranslation
Expand All @@ -56,6 +57,8 @@ class Article extends TranslatableModel

public $articleCount = null;

public $category_ids = [];

/**
* @author Zura Sekhniashvili <[email protected]>
* @var ArticleTranslation[]
Expand Down Expand Up @@ -126,17 +129,16 @@ public function behaviors()
public function rules()
{
return [
[['category_id'], 'required'],
[['slug'], 'unique'],
[['published_at'], 'default', 'value' => time()],
[['published_at'], 'filter', 'filter' => 'strtotime', 'when' => function($model) {
[['published_at'], 'filter', 'filter' => 'strtotime', 'when' => function ($model) {
return is_string($model->published_at);
}],
[['category_id'], 'exist', 'targetClass' => ArticleCategory::className(), 'targetAttribute' => 'id'],
[['author_id', 'updater_id', 'position', 'status'], 'integer'],
[['slug', 'thumbnail_base_url', 'thumbnail_path', 'url'], 'string', 'max' => 2024],
[['view'], 'string', 'max' => 255],
[['attachments', 'thumbnail', 'published_at'], 'safe']
[['attachments', 'thumbnail', 'published_at'], 'safe'],
['category_ids', 'each', 'rule' => ['integer']],
];
}

Expand All @@ -149,12 +151,12 @@ public function attributeLabels()
'id' => Yii::t('i18ncontent', 'ID'),
'slug' => Yii::t('i18ncontent', 'Slug'),
'view' => Yii::t('i18ncontent', 'Article View'),
'category_ids' => Yii::t('i18ncontent', 'Article Categories'),
'thumbnail' => Yii::t('i18ncontent', 'Thumbnail'),
'position' => Yii::t('i18ncontent', 'Position'),
'url' => Yii::t('i18ncontent', 'Url'),
'author_id' => Yii::t('i18ncontent', 'Author'),
'updater_id' => Yii::t('i18ncontent', 'Updater'),
'category_id' => Yii::t('i18ncontent', 'Category'),
'status' => Yii::t('i18ncontent', 'Published'),
'published_at' => Yii::t('i18ncontent', 'Published At'),
'created_at' => Yii::t('i18ncontent', 'Created At'),
Expand All @@ -181,9 +183,9 @@ public function getUpdater()
/**
* @return \yii\db\ActiveQuery
*/
public function getCategory()
public function getArticleCategoryArticles()
{
return $this->hasOne(ArticleCategory::className(), ['id' => 'category_id']);
return $this->hasMany(ArticleCategoryArticle::className(), ['article_id' => 'id']);
}

/**
Expand All @@ -194,6 +196,55 @@ public function getArticleAttachments()
return $this->hasMany(ArticleAttachment::className(), ['article_id' => 'id']);
}

public function save($runValidation = true, $attributeNames = null)
{
$transaction = Yii::$app->db->beginTransaction();
if (parent::save()){

$existingCategoryIds = ArrayHelper::getColumn($this->articleCategoryArticles, 'category_id');
$toDeleteCategoryIds = array_diff($existingCategoryIds, $this->category_ids);
$toAddCategoryIds = array_diff($this->category_ids, $existingCategoryIds);
// \centigen\base\helpers\UtilHelper::vardump($toDeleteCategoryIds, $toAddCategoryIds);
// exit;
if ($this->removeCategories($toDeleteCategoryIds) && $this->addCategories($toAddCategoryIds)){
$transaction->commit();
return true;
}
}
$transaction->rollBack();
return false;
}

protected function removeCategories($categoryIds)
{
if (empty($categoryIds)){
return true;
}
ArticleCategoryArticle::deleteAll(['category_id' => $categoryIds]);
return true;
}

protected function addCategories($categoryIds)
{
if (empty($categoryIds)){
return true;
}
$data = [];
foreach ($categoryIds as $category_id){
$data[] = [
'article_id' => $this->id,
'category_id' => $category_id,
'updated_at' => time(),
'created_at' => time()
];
}

Yii::$app->db->createCommand()->batchInsert(ArticleCategoryArticle::tableName(),
['article_id', 'category_id', 'updated_at', 'created_at'], $data)->execute();

return true;
}

/**
* Find Article-s by category. Return array of Article or ActiveQuery
*
Expand All @@ -206,10 +257,8 @@ public static function getArticlesByCategory(ArticleCategory $cat, $getQuery = t
{
$query = Article::find()
->with('activeTranslation')
->where([
'category_id' => $cat->id,
'status' => self::STATUS_PUBLISHED
]);
->byCategoryId($cat->id)
->published();
return $getQuery ? $query : $query->all();
}

Expand All @@ -222,15 +271,11 @@ public static function getArticlesByCategory(ArticleCategory $cat, $getQuery = t
*/
public static function getByCategorySlug($slug)
{
return Article::find()
->from(self::tableName().' a')
->innerJoin('{{%article_category}} ac', 'ac.id = a.category_id')
return Article::find()->byCategorySlug($slug)
->categoryActive()
->published()
->with('activeTranslation')
->where([
'ac.slug' => $slug,
'a.status' => self::STATUS_PUBLISHED,
'ac.status' => self::STATUS_PUBLISHED
])->all();
->all();
}

/**
Expand All @@ -244,10 +289,9 @@ public static function getBySlug($slug)
{
return Article::find()
->with('activeTranslation')
->where([
'slug' => $slug,
'status' => self::STATUS_PUBLISHED
])->one();
->bySlug($slug)
->published()
->one();
}

/**
Expand All @@ -274,10 +318,10 @@ public function getShortDescription()
return $this->activeTranslation ? $this->activeTranslation->getShortDescription() : '';
}

public function getThumbnailUrl()
public function getThumbnailUrl()
{
if ($this->thumbnail_path){
return Yii::getAlias('@storageUrl') . '/source/'.ltrim($this->thumbnail_path, '/');
if ($this->thumbnail_path) {
return Yii::getAlias('@storageUrl') . '/source/' . ltrim($this->thumbnail_path, '/');
}
return null;
}
Expand Down
Loading

0 comments on commit 902ffdb

Please sign in to comment.