Category.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. /**
  3. * Author: lf
  4. * Blog: https://blog.feehi.com
  5. * Email: job@feehi.com
  6. * Created at: 2017-03-15 21:16
  7. */
  8. namespace common\models;
  9. use Yii;
  10. use common\libs\FamilyTree;
  11. use yii\behaviors\TimestampBehavior;
  12. use yii\helpers\ArrayHelper;
  13. use yii\helpers\FileHelper;
  14. /**
  15. * This is the model class for table "{{%category}}".
  16. *
  17. * @property integer $id
  18. * @property integer $parent_id
  19. * @property string $name
  20. * @property string $alias
  21. * @property integer $sort
  22. * @property string $template
  23. * @property string $article_template
  24. * @property string $remark
  25. * @property string $created_at
  26. * @property string $updated_at
  27. */
  28. class Category extends \yii\db\ActiveRecord
  29. {
  30. use FamilyTree;
  31. public $level;
  32. public $prefix_level_name;
  33. /**
  34. * @inheritdoc
  35. */
  36. public static function tableName()
  37. {
  38. return '{{%category}}';
  39. }
  40. public function behaviors()
  41. {
  42. return [
  43. TimestampBehavior::className(),
  44. ];
  45. }
  46. /**
  47. * @inheritdoc
  48. */
  49. public function rules()
  50. {
  51. return [
  52. [['sort', 'parent_id', 'created_at', 'updated_at'], 'integer'],
  53. [['sort'], 'compare', 'compareValue' => 0, 'operator' => '>='],
  54. [['parent_id'], 'default', 'value' => 0],
  55. [['name', 'alias', 'remark', 'template', 'article_template'], 'string', 'max' => 255],
  56. [['alias'], 'match', 'pattern' => '/^[a-zA-Z0-9_]+$/', 'message' => Yii::t('app', 'Must begin with alphabet and can only includes alphabet,_,and number')],
  57. [['name', 'alias'], 'required'],
  58. [['sort'], 'default', 'value' => 0]
  59. ];
  60. }
  61. /**
  62. * @inheritdoc
  63. */
  64. public function attributeLabels()
  65. {
  66. return [
  67. 'id' => Yii::t('app', 'ID'),
  68. 'parent_id' => Yii::t('app', 'Parent Category Id'),
  69. 'name' => Yii::t('app', 'Name'),
  70. 'alias' => Yii::t('app', 'Alias'),
  71. 'sort' => Yii::t('app', 'Sort'),
  72. 'template' => Yii::t('app', 'Category Template'),
  73. 'article_template' => Yii::t('app', 'Article Template'),
  74. 'remark' => Yii::t('app', 'Remark'),
  75. 'created_at' => Yii::t('app', 'Created At'),
  76. 'updated_at' => Yii::t('app', 'Updated At'),
  77. ];
  78. }
  79. public function getItems()
  80. {
  81. return self::_getCategories();
  82. }
  83. /**
  84. * @return array|\yii\db\ActiveRecord[]
  85. */
  86. protected static function _getCategories()
  87. {
  88. return self::find()->orderBy(['sort'=>SORT_ASC, "parent_id"=>SORT_ASC])->all();
  89. }
  90. /**
  91. * @inheritdoc
  92. */
  93. public function beforeDelete()
  94. {
  95. $subs = $this->getDescendants($this->id);
  96. if (! empty($subs)) {
  97. $this->addError('id', Yii::t('app', 'Allowed not to be deleted, sub level existed.'));
  98. return false;
  99. }
  100. if (Article::findOne(['cid' => $this->id]) != null) {
  101. $this->addError('id', Yii::t('app', 'Allowed not to be deleted, some article belongs to this category.'));
  102. return false;
  103. }
  104. return parent::beforeDelete();
  105. }
  106. /**
  107. * @inheritdoc
  108. */
  109. public function afterValidate()
  110. {
  111. if (! $this->getIsNewRecord() ) {
  112. if( $this->id == $this->parent_id ) {
  113. $this->addError('parent_id', Yii::t('app', 'Cannot be themselves sub'));
  114. return false;
  115. }
  116. $descendants = $this->getDescendants($this->id);
  117. $descendants = ArrayHelper::getColumn($descendants, 'id');
  118. if( in_array($this->parent_id, $descendants) ){
  119. $this->addError('parent_id', Yii::t('app', 'Cannot be themselves descendants sub'));
  120. return false;
  121. }
  122. }
  123. parent::afterValidate();
  124. }
  125. public function afterSave($insert, $changedAttributes)
  126. {
  127. self::_generateUrlRules();
  128. parent::afterSave($insert, $changedAttributes);
  129. }
  130. private function _generateUrlRules()
  131. {
  132. $categories = self::_getCategories();
  133. $data = [];
  134. foreach ($categories as $v){
  135. $parents = $this->getAncestors($v['id']);
  136. $url = '';
  137. if(!empty($parents)){
  138. $parents = array_reverse($parents);
  139. foreach ($parents as $parent) {
  140. $url .= '/' . $parent['alias'];
  141. }
  142. }
  143. $url .= '/<cat:' . $v['alias'] . '>';
  144. $data[$url] = 'article/index';
  145. }
  146. $json = json_encode($data);
  147. $path = Yii::getAlias('@frontend/runtime/cache/');
  148. if( !file_exists($path) ) FileHelper::createDirectory($path);
  149. file_put_contents($path . 'category.txt', $json);
  150. }
  151. public function getUrlRules()
  152. {
  153. $file = Yii::getAlias('@frontend/runtime/cache/category.txt');
  154. if( !file_exists($file) ){
  155. $this->_generateUrlRules();
  156. }
  157. return json_decode(file_get_contents($file), true);
  158. }
  159. public function getParent()
  160. {
  161. return $this->hasOne(self::className(), ['id' => 'parent_id']);
  162. }
  163. }