Egorka
7 years ago
3216 changed files with 48060 additions and 3130 deletions
@ -0,0 +1,113 @@
|
||||
<?php |
||||
/** |
||||
* Created by Error202 |
||||
* Date: 04.06.2018 |
||||
*/ |
||||
|
||||
namespace backend\components; |
||||
|
||||
use yii\base\Action; |
||||
use yii\db\Expression; |
||||
use yii\base\InvalidConfigException; |
||||
use yii\web\MethodNotAllowedHttpException; |
||||
use Yii; |
||||
|
||||
class ToggleAction extends Action |
||||
{ |
||||
/** |
||||
* @var string name of the model |
||||
*/ |
||||
public $modelClass; |
||||
/** |
||||
* @var string model attribute |
||||
*/ |
||||
public $attribute = 'active'; |
||||
/** |
||||
* @var string scenario model |
||||
*/ |
||||
public $scenario = null; |
||||
/** |
||||
* @var string|array additional condition for loading the model |
||||
*/ |
||||
public $andWhere; |
||||
/** |
||||
* @var string|int|boolean|Expression what to set active models to |
||||
*/ |
||||
public $onValue = 1; |
||||
/** |
||||
* @var string|int|boolean what to set inactive models to |
||||
*/ |
||||
public $offValue = 0; |
||||
/** |
||||
* @var bool whether to set flash messages or not |
||||
*/ |
||||
public $setFlash = false; |
||||
/** |
||||
* @var string flash message on success |
||||
*/ |
||||
public $flashSuccess = "Model saved"; |
||||
/** |
||||
* @var string flash message on error |
||||
*/ |
||||
public $flashError = "Error saving Model"; |
||||
/** |
||||
* @var string|array URL to redirect to |
||||
*/ |
||||
public $redirect; |
||||
/** |
||||
* @var string pk field name |
||||
*/ |
||||
public $primaryKey = 'id'; |
||||
|
||||
|
||||
public function run($id) |
||||
{ |
||||
if (!Yii::$app->request->getIsPost()) { |
||||
throw new MethodNotAllowedHttpException(); |
||||
} |
||||
$id = (int)$id; |
||||
$result = null; |
||||
if (empty($this->modelClass) || !class_exists($this->modelClass)) { |
||||
throw new InvalidConfigException("Model class doesn't exist"); |
||||
} |
||||
/* @var $modelClass \yii\db\ActiveRecord */ |
||||
$modelClass = $this->modelClass; |
||||
$attribute = $this->attribute; |
||||
$model = $modelClass::find()->where([$this->primaryKey => $id]); |
||||
if (!empty($this->andWhere)) { |
||||
$model->andWhere($this->andWhere); |
||||
} |
||||
$model = $model->one(); |
||||
if (!is_null($this->scenario)) { |
||||
$model->scenario = $this->scenario; |
||||
} |
||||
if (!$model->hasAttribute($this->attribute)) { |
||||
throw new InvalidConfigException("Attribute doesn't exist"); |
||||
} |
||||
if ($model->$attribute == $this->onValue) { |
||||
$model->$attribute = $this->offValue; |
||||
} elseif ($this->onValue instanceof Expression && $model->$attribute != $this->offValue) { |
||||
$model->$attribute = $this->offValue; |
||||
} else { |
||||
$model->$attribute = $this->onValue; |
||||
} |
||||
if ($model->save()) { |
||||
if ($this->setFlash) { |
||||
Yii::$app->session->setFlash('success', $this->flashSuccess); |
||||
} |
||||
} else { |
||||
if ($this->setFlash) { |
||||
Yii::$app->session->setFlash('error', $this->flashError); |
||||
} |
||||
} |
||||
if (Yii::$app->request->getIsAjax()) { |
||||
Yii::$app->end(); |
||||
} |
||||
/* @var $controller \yii\web\Controller */ |
||||
$controller = $this->controller; |
||||
if (!empty($this->redirect)) { |
||||
return $controller->redirect($this->redirect); |
||||
} |
||||
return $controller->redirect(Yii::$app->request->getReferrer()); |
||||
} |
||||
} |
@ -0,0 +1,143 @@
|
||||
<?php |
||||
/** |
||||
* Created by Error202 |
||||
* Date: 04.06.2018 |
||||
*/ |
||||
|
||||
namespace backend\components; |
||||
|
||||
use yii\grid\DataColumn; |
||||
use yii\helpers\Html; |
||||
use yii\web\View; |
||||
use Yii; |
||||
|
||||
class ToggleColumn extends DataColumn |
||||
{ |
||||
/** |
||||
* Toggle action that will be used as the toggle action in your controller |
||||
* @var string |
||||
*/ |
||||
public $action = 'toggle'; |
||||
|
||||
|
||||
/** |
||||
* @var string pk field name |
||||
*/ |
||||
public $primaryKey = 'primaryKey'; |
||||
|
||||
/** |
||||
* Whether to use ajax or not |
||||
* @var bool |
||||
*/ |
||||
public $enableAjax = true; |
||||
|
||||
/** |
||||
* @var string glyphicon for 'on' value |
||||
*/ |
||||
public $iconOn = 'ok'; |
||||
|
||||
/** |
||||
* @var string glyphicon for 'off' value |
||||
*/ |
||||
public $iconOff = 'remove'; |
||||
|
||||
/** |
||||
* @var string text to display on the 'on' link |
||||
*/ |
||||
public $onText; |
||||
|
||||
/** |
||||
* @var string text to display on the 'off' link |
||||
*/ |
||||
public $offText; |
||||
|
||||
/** |
||||
* @var string text to display next to the 'on' link |
||||
*/ |
||||
public $displayValueText = false; |
||||
|
||||
/** |
||||
* @var string text to display next to the 'on' link |
||||
*/ |
||||
public $onValueText; |
||||
|
||||
/** |
||||
* @var string text to display next to the 'off' link |
||||
*/ |
||||
public $offValueText; |
||||
|
||||
|
||||
public function init() |
||||
{ |
||||
if ($this->onText === null) { |
||||
$this->onText = Yii::t('main', 'On'); |
||||
} |
||||
if ($this->offText === null) { |
||||
$this->offText = Yii::t('main', 'Off'); |
||||
} |
||||
if ($this->onValueText === null) { |
||||
$this->onValueText = Yii::t('main', 'Active'); |
||||
} |
||||
if ($this->offValueText === null) { |
||||
$this->offValueText = Yii::t('main', 'Inactive'); |
||||
} |
||||
if ($this->enableAjax) { |
||||
$this->registerJs(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
protected function renderDataCellContent($model, $key, $index) |
||||
{ |
||||
$url = [$this->action, 'id' => $model->{$this->primaryKey}]; |
||||
|
||||
$attribute = $this->attribute; |
||||
$value = $model->$attribute; |
||||
|
||||
if ($value === null || $value == true) { |
||||
$icon = $this->iconOn; |
||||
$title = $this->offText; |
||||
$valueText = $this->onValueText; |
||||
$color = 'green'; |
||||
} else { |
||||
$icon = $this->iconOff; |
||||
$title = $this->onText; |
||||
$valueText = $this->offValueText; |
||||
$color = 'red'; |
||||
} |
||||
return Html::a( |
||||
'<span class="glyphicon glyphicon-' . $icon . '"></span>', |
||||
$url, |
||||
[ |
||||
'title' => $title, |
||||
'class' => 'toggle-column', |
||||
'style' => 'color:' . $color, |
||||
'data-method' => 'post', |
||||
'data-pjax' => '0', |
||||
] |
||||
) . ( $this->displayValueText ? " {$valueText}" : "" ); |
||||
} |
||||
|
||||
/** |
||||
* Registers the ajax JS |
||||
*/ |
||||
public function registerJs() |
||||
{ |
||||
if(Yii::$app->request->isAjax) { |
||||
return; |
||||
} |
||||
$js = <<<'JS' |
||||
$(document.body).on("click", "a.toggle-column", function(e) { |
||||
e.preventDefault(); |
||||
$.post($(this).attr("href"), function(data) { |
||||
var pjaxId = $(e.target).closest("[data-pjax-container]").attr("id"); |
||||
$.pjax.reload({container:"#" + pjaxId}); |
||||
}); |
||||
return false; |
||||
}); |
||||
JS; |
||||
$this->grid->view->registerJs($js, View::POS_READY, 'zx-toggle-column'); |
||||
} |
||||
} |
@ -0,0 +1,150 @@
|
||||
<?php |
||||
/** |
||||
* Created by Error202 |
||||
* Date: 04.06.2018 |
||||
*/ |
||||
|
||||
namespace backend\controllers; |
||||
|
||||
|
||||
use backend\forms\SettingsSearch; |
||||
use core\entities\Settings; |
||||
use core\forms\SettingsForm; |
||||
use core\services\SettingsService; |
||||
use yii\filters\AccessControl; |
||||
use yii\filters\VerbFilter; |
||||
use yii\web\Controller; |
||||
use backend\components\ToggleAction; |
||||
use Yii; |
||||
use yii\web\NotFoundHttpException; |
||||
|
||||
class SettingsController extends Controller |
||||
{ |
||||
private $service; |
||||
|
||||
public function __construct( string $id, $module, SettingsService $service, array $config = [] ) { |
||||
parent::__construct( $id, $module, $config ); |
||||
$this->service = $service; |
||||
} |
||||
|
||||
public function behaviors() |
||||
{ |
||||
return [ |
||||
'verbs' => [ |
||||
'class' => VerbFilter::className(), |
||||
'actions' => [ |
||||
'delete' => ['POST'], |
||||
], |
||||
], |
||||
'access' => [ |
||||
'class' => AccessControl::className(), |
||||
'rules' => [ |
||||
[ |
||||
'actions' => ['create','view','index', 'update', 'delete', 'toggle'], |
||||
'allow' => true, |
||||
'roles' => ['SettingsManagement'], |
||||
], |
||||
[ // all the action are accessible to admin |
||||
'allow' => true, |
||||
'roles' => ['admin'], |
||||
], |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
|
||||
public function actions() |
||||
{ |
||||
return [ |
||||
'toggle' => [ |
||||
'class' => ToggleAction::className(), |
||||
'modelClass' => Settings::class, |
||||
//'setFlash' => true, |
||||
] |
||||
]; |
||||
} |
||||
|
||||
public function actionIndex() |
||||
{ |
||||
$searchModel = new SettingsSearch(); |
||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); |
||||
return $this->render( |
||||
'index', |
||||
[ |
||||
'searchModel' => $searchModel, |
||||
'dataProvider' => $dataProvider, |
||||
] |
||||
); |
||||
} |
||||
|
||||
public function actionView($id) |
||||
{ |
||||
return $this->render( |
||||
'view', |
||||
[ |
||||
'model' => $this->findModel($id), |
||||
] |
||||
); |
||||
} |
||||
|
||||
public function actionCreate() |
||||
{ |
||||
$form = new SettingsForm(); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$settings = $this->service->create($form); |
||||
return $this->redirect(['view', 'id' => $settings->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
else { |
||||
$form->active = 1; |
||||
} |
||||
return $this->render( |
||||
'create', |
||||
[ |
||||
'model' => $form, |
||||
] |
||||
); |
||||
} |
||||
|
||||
public function actionUpdate($id) |
||||
{ |
||||
$settings = $this->findModel($id); |
||||
|
||||
$form = new SettingsForm($settings); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$this->service->edit($settings->id, $form); |
||||
return $this->redirect(['view', 'id' => $settings->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
return $this->render( |
||||
'update', |
||||
[ |
||||
'model' => $form, |
||||
'settings' => $settings, |
||||
] |
||||
); |
||||
} |
||||
|
||||
public function actionDelete($id) |
||||
{ |
||||
$this->service->remove($id); |
||||
return $this->redirect(['index']); |
||||
} |
||||
|
||||
protected function findModel($id) |
||||
{ |
||||
if (($model = Settings::findOne($id)) !== null) { |
||||
return $model; |
||||
} else { |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,66 @@
|
||||
<?php |
||||
/** |
||||
* Created by Error202 |
||||
* Date: 04.06.2018 |
||||
*/ |
||||
|
||||
namespace backend\forms; |
||||
|
||||
|
||||
use core\entities\Settings; |
||||
use yii\base\Model; |
||||
use yii\data\ActiveDataProvider; |
||||
|
||||
class SettingsSearch extends Settings |
||||
{ |
||||
public $id; |
||||
public $type; |
||||
public $section; |
||||
public $key; |
||||
public $value; |
||||
public $active; |
||||
|
||||
public function rules() |
||||
{ |
||||
return [ |
||||
[['id'], 'integer'], |
||||
[['active'], 'boolean'], |
||||
[['type', 'section', 'key', 'value'], 'safe'], |
||||
]; |
||||
} |
||||
/** |
||||
* @return array |
||||
*/ |
||||
public function scenarios() |
||||
{ |
||||
// bypass scenarios() implementation in the parent class |
||||
return Model::scenarios(); |
||||
} |
||||
/** |
||||
* @param $params |
||||
* @return ActiveDataProvider |
||||
*/ |
||||
public function search($params) |
||||
{ |
||||
$query = Settings::find(); |
||||
$dataProvider = new ActiveDataProvider( |
||||
[ |
||||
'query' => $query, |
||||
] |
||||
); |
||||
if (!($this->load($params) && $this->validate())) { |
||||
return $dataProvider; |
||||
} |
||||
$query->andFilterWhere( |
||||
[ |
||||
'id' => $this->id, |
||||
'active' => $this->active, |
||||
'section' => $this->section, |
||||
] |
||||
); |
||||
$query->andFilterWhere(['like', 'key', $this->key]) |
||||
->andFilterWhere(['like', 'value', $this->value]); |
||||
return $dataProvider; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,43 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\widgets\ActiveForm; |
||||
use core\forms\SettingsForm; |
||||
|
||||
/** |
||||
* @var yii\web\View $this |
||||
* @var SettingsForm $model |
||||
* @var yii\widgets\ActiveForm $form |
||||
*/ |
||||
?> |
||||
|
||||
<div class="setting-form"> |
||||
|
||||
<div class="box box-default"> |
||||
<div class="box-body"> |
||||
|
||||
<?php $form = ActiveForm::begin(); ?> |
||||
|
||||
<?= $form->field($model, 'section')->textInput(['maxlength' => 255]) ?> |
||||
|
||||
<?= $form->field($model, 'key')->textInput(['maxlength' => 255]) ?> |
||||
|
||||
<?= $form->field($model, 'value')->textarea(['rows' => 6]) ?> |
||||
|
||||
<?= $form->field($model, 'active')->checkbox(['value' => 1]) ?> |
||||
|
||||
<?= |
||||
$form->field($model, 'type')->dropDownList( |
||||
$model->getTypes() |
||||
)->hint(Yii::t('main', 'Change at your own risk')) ?> |
||||
|
||||
<div class="form-group"> |
||||
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?> |
||||
</div> |
||||
|
||||
<?php ActiveForm::end(); ?> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
@ -0,0 +1,24 @@
|
||||
<?php |
||||
|
||||
use core\forms\SettingsForm; |
||||
|
||||
/** |
||||
* @var yii\web\View $this |
||||
* @var SettingsForm $model |
||||
*/ |
||||
|
||||
$this->title = Yii::t('main','Create Setting'); |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('main', 'Settings'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="setting-create"> |
||||
|
||||
<?= |
||||
$this->render( |
||||
'_form', |
||||
[ |
||||
'model' => $model, |
||||
] |
||||
) ?> |
||||
|
||||
</div> |
@ -0,0 +1,70 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\grid\GridView; |
||||
use yii\helpers\ArrayHelper; |
||||
use yii\widgets\Pjax; |
||||
use core\entities\Settings; |
||||
use backend\components\ToggleColumn; |
||||
|
||||
/** |
||||
* @var yii\web\View $this |
||||
* @var \backend\forms\SettingsSearch $searchModel |
||||
* @var yii\data\ActiveDataProvider $dataProvider |
||||
*/ |
||||
|
||||
$this->title = Yii::t('main', 'Settings'); |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="setting-index"> |
||||
|
||||
<p> |
||||
<?= |
||||
Html::a( |
||||
Yii::t('buttons','Create Setting'), |
||||
['create'], |
||||
['class' => 'btn btn-success'] |
||||
) ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
|
||||
<?php Pjax::begin(); ?> |
||||
<?= |
||||
GridView::widget( |
||||
[ |
||||
'dataProvider' => $dataProvider, |
||||
'filterModel' => $searchModel, |
||||
'columns' => [ |
||||
//'id', |
||||
//'type', |
||||
[ |
||||
'attribute' => 'section', |
||||
'filter' => ArrayHelper::map( |
||||
Settings::find()->select('section')->distinct()->where(['<>', 'section', ''])->all(), |
||||
'section', |
||||
'section' |
||||
), |
||||
], |
||||
'key', |
||||
'value:ntext', |
||||
[ |
||||
'class' => ToggleColumn::class, |
||||
'attribute' => 'active', |
||||
'filter' => [1 => Yii::t('yii', 'Yes'), 0 => Yii::t('yii', 'No')], |
||||
'options' => ['style' => 'width: 100px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
[ |
||||
'class' => 'yii\grid\ActionColumn', |
||||
'options' => ['style' => 'width: 100px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
], |
||||
] |
||||
); ?> |
||||
<?php Pjax::end(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,29 @@
|
||||
<?php |
||||
|
||||
use core\forms\SettingsForm; |
||||
use core\entities\Settings; |
||||
|
||||
/** |
||||
* @var yii\web\View $this |
||||
* @var SettingsForm $model |
||||
* @var Settings $settings |
||||
*/ |
||||
|
||||
$this->title = Yii::t( |
||||
'main', |
||||
'Updating Setting') . ' ' . $model->section. '.' . $model->key; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('main', 'Settings'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = ['label' => $model->section. '.' . $model->key, 'url' => ['view', 'id' => $settings->id]]; |
||||
$this->params['breadcrumbs'][] = Yii::t('main', 'Editing'); |
||||
?> |
||||
<div class="setting-update"> |
||||
|
||||
<?= |
||||
$this->render( |
||||
'_form', |
||||
[ |
||||
'model' => $model, |
||||
] |
||||
) ?> |
||||
|
||||
</div> |
@ -0,0 +1,60 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\widgets\DetailView; |
||||
|
||||
/** |
||||
* @var yii\web\View $this |
||||
* @var \core\entities\Settings $model |
||||
*/ |
||||
|
||||
$this->title = $model->section. '.' . $model->key; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('main', 'Settings'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="setting-view"> |
||||
|
||||
<p> |
||||
<?= Html::a(Yii::t('buttons','All Settings'), ['index'], ['class' => 'btn btn-default']) ?> |
||||
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?> |
||||
<?= |
||||
Html::a( |
||||
Yii::t('buttons', 'Delete'), |
||||
['delete', 'id' => $model->id], |
||||
[ |
||||
'class' => 'btn btn-danger', |
||||
'data' => [ |
||||
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'), |
||||
'method' => 'post', |
||||
], |
||||
] |
||||
) ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
<?= |
||||
DetailView::widget( |
||||
[ |
||||
'model' => $model, |
||||
'attributes' => [ |
||||
'id', |
||||
'type', |
||||
'section', |
||||
'active:boolean', |
||||
'key', |
||||
'value:ntext', |
||||
[ |
||||
'attribute' => 'created_at', |
||||
'format' => ['datetime', 'php:d.m.Y H:i'], |
||||
], |
||||
[ |
||||
'attribute' => 'updated_at', |
||||
'format' => ['datetime', 'php:d.m.Y H:i'], |
||||
], |
||||
], |
||||
] |
||||
) ?> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -1,12 +1,5 @@
|
||||
<?php |
||||
return [ |
||||
'supportEmail' => 'info@zertex.ru', |
||||
'adminEmail' => 'info@zertex.ru', |
||||
'user.passwordResetTokenExpire' => 3600, |
||||
'user.rememberMeDuration' => 3600 * 24 * 30, |
||||
//'cookieDomain' => '.example.com', |
||||
//'frontendHostInfo' => 'http://example.com', |
||||
//'backendHostInfo' => 'http://backend.example.com', |
||||
//'staticHostInfo' => 'http://static.example.com', |
||||
'staticPath' => dirname(__DIR__, 2) . '/static', |
||||
]; |
||||
|
@ -0,0 +1,93 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog; |
||||
use core\components\modules\ModuleInterface; |
||||
use yii\helpers\ArrayHelper; |
||||
|
||||
|
||||
/** |
||||
* blog module definition class |
||||
*/ |
||||
class BlogModule extends \yii\base\Module implements ModuleInterface |
||||
{ |
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public $controllerNamespace = 'common\modules\blog\controllers'; |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function init() |
||||
{ |
||||
parent::init(); |
||||
|
||||
// custom initialization code goes here |
||||
} |
||||
|
||||
public function bootstrap($app) |
||||
{ |
||||
// add rules |
||||
$app->getUrlManager()->addRules([ |
||||
'blog' => 'blog/post/index', |
||||
]); |
||||
|
||||
$app->getUrlManager()->addRules([ |
||||
['class' => 'common\modules\blog\urls\BlogMainUrlRule'], |
||||
['class' => 'common\modules\blog\urls\BlogCategoryUrlRule'], |
||||
['class' => 'common\modules\blog\urls\BlogTagUrlRule'], |
||||
]); |
||||
|
||||
// add languages |
||||
$app->getI18n()->translations = ArrayHelper::merge($app->getI18n()->translations, [ |
||||
'blog' => [ |
||||
'class' => 'yii\i18n\PhpMessageSource', |
||||
'basePath' => '@common/modules/blog/messages', |
||||
], |
||||
'blog_public' => [ |
||||
'class' => 'yii\i18n\PhpMessageSource', |
||||
'basePath' => '@common/modules/blog/messages', |
||||
], |
||||
]); |
||||
|
||||
// add menu items |
||||
/*$app->params['adminMenu'][] = [ |
||||
'label' => \Yii::t('blog', 'Blog'), 'icon' => 'book', 'items' => [ |
||||
['label' => \Yii::t('blog', 'Categories'), 'icon' => 'caret-right', 'url' => ['/blog/manage/category/index'], 'active' => \Yii::$app->controller->getUniqueId() == 'blog/manage/category'], |
||||
['label' => \Yii::t('blog', 'Posts'), 'icon' => 'caret-right', 'url' => ['/blog/manage/post/index'], 'active' => \Yii::$app->controller->getUniqueId() == 'blog/manage/post'], |
||||
], 'visible' => \Yii::$app->user->can('admin') || \Yii::$app->user->can('BlogManagement') |
||||
];*/ |
||||
//print_r(basename($app->getBasePath())); die; |
||||
//print_r($app->basePath); die; |
||||
|
||||
if (basename($app->getBasePath()) === 'backend') { |
||||
$app->params['adminMenu'][] = [ |
||||
'label' => \Yii::t( 'blog', 'Blog' ), |
||||
'icon' => 'book', |
||||
'items' => [ |
||||
[ |
||||
'label' => \Yii::t( 'blog', 'Categories' ), |
||||
'icon' => 'caret-right', |
||||
'url' => [ '/blog/manage/category/index' ] |
||||
], |
||||
[ |
||||
'label' => \Yii::t( 'blog', 'Posts' ), |
||||
'icon' => 'caret-right', |
||||
'url' => [ '/blog/manage/post/index' ] |
||||
], |
||||
[ |
||||
'label' => \Yii::t( 'blog', 'Comments' ), |
||||
'icon' => 'caret-right', |
||||
'url' => [ '/blog/manage/comment/index' ] |
||||
], |
||||
[ |
||||
'label' => \Yii::t( 'blog', 'Tags' ), |
||||
'icon' => 'caret-right', |
||||
'url' => [ '/blog/manage/tag/index' ] |
||||
], |
||||
], |
||||
'visible' => \Yii::$app->user->can( 'admin' ) || \Yii::$app->user->can( 'BlogManagement' ) |
||||
]; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,162 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\controllers; |
||||
|
||||
use common\modules\blog\forms\BlogCommentForm; |
||||
use common\modules\blog\repositories\read\BlogCategoryReadRepository; |
||||
use common\modules\blog\repositories\read\BlogPostReadRepository; |
||||
use common\modules\blog\repositories\read\BlogTagReadRepository; |
||||
use common\modules\blog\services\BlogCommentService; |
||||
use frontend\components\FrontendController; |
||||
use Yii; |
||||
use yii\data\ActiveDataProvider; |
||||
use yii\web\NotFoundHttpException; |
||||
use yii\filters\AccessControl; |
||||
|
||||
class PostController extends FrontendController |
||||
{ |
||||
public $layout = 'blog'; |
||||
|
||||
private $service; |
||||
private $posts; |
||||
private $categories; |
||||
private $tags; |
||||
|
||||
public function __construct( |
||||
$id, |
||||
$module, |
||||
BlogCommentService $service, |
||||
BlogPostReadRepository $posts, |
||||
BlogCategoryReadRepository $categories, |
||||
BlogTagReadRepository $tags, |
||||
$config = [] |
||||
) |
||||
{ |
||||
parent::__construct($id, $module, $config); |
||||
$this->service = $service; |
||||
$this->posts = $posts; |
||||
$this->categories = $categories; |
||||
$this->tags = $tags; |
||||
} |
||||
|
||||
public function behaviors(): array |
||||
{ |
||||
return [ |
||||
'access' => [ |
||||
'class' => AccessControl::className(), |
||||
'rules' => [ |
||||
[ |
||||
'actions' => ['index', 'category', 'tag', 'post'], |
||||
'allow' => true, |
||||
//'roles' => ['Blog'], |
||||
], |
||||
[ |
||||
'actions' => ['comment'], |
||||
'allow' => true, |
||||
'roles' => ['Comments'], |
||||
], |
||||
[ // all the action are accessible to admin |
||||
'allow' => true, |
||||
'roles' => ['admin'], |
||||
], |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
public function actionIndex() |
||||
{ |
||||
/* @var $dataProvider ActiveDataProvider */ |
||||
$dataProvider = $this->posts->getAll(); |
||||
$dataProvider->pagination->pageSize = 10; |
||||
|
||||
return $this->render('index', [ |
||||
'dataProvider' => $dataProvider, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return string |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionCategory($id) |
||||
{ |
||||
if (!$category = $this->categories->find($id)) { |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
$dataProvider = $this->posts->getAllByCategory($category); |
||||
|
||||
return $this->render('category', [ |
||||
'category' => $category, |
||||
'dataProvider' => $dataProvider, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* @return mixed |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionTag($id) |
||||
{ |
||||
if (!$tag = $this->tags->find($id)) { |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
$dataProvider = $this->posts->getAllByTag($tag); |
||||
|
||||
return $this->render('tag', [ |
||||
'tag' => $tag, |
||||
'dataProvider' => $dataProvider, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* @return mixed |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionPost($id) |
||||
{ |
||||
if (!$post = $this->posts->find($id)) { |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
|
||||
return $this->render('post', [ |
||||
'post' => $post, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* @return mixed |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionComment($id) |
||||
{ |
||||
if (!$post = $this->posts->find($id)) { |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
|
||||
$form = new BlogCommentForm(); |
||||
|
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$comment = $this->service->create($post->id, Yii::$app->user->id, $form); |
||||
return $this->redirect(['post', 'id' => $post->id, '#' => 'comment_' . $comment->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
|
||||
return $this->render('comment', [ |
||||
'post' => $post, |
||||
'model' => $form, |
||||
]); |
||||
} |
||||
} |
@ -0,0 +1,155 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\controllers\manage; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use common\modules\blog\forms\BlogCategoryForm; |
||||
use common\modules\blog\forms\search\BlogCategorySearch; |
||||
use common\modules\blog\services\BlogCategoryManageService; |
||||
use Yii; |
||||
use yii\web\Controller; |
||||
use yii\web\NotFoundHttpException; |
||||
use yii\filters\VerbFilter; |
||||
use yii\filters\AccessControl; |
||||
|
||||
class CategoryController extends Controller |
||||
{ |
||||
private $service; |
||||
|
||||
public function __construct($id, $module, BlogCategoryManageService $service, $config = []) |
||||
{ |
||||
parent::__construct($id, $module, $config); |
||||
$this->service = $service; |
||||
} |
||||
|
||||
public function behaviors(): array |
||||
{ |
||||
return [ |
||||
'access' => [ |
||||
'class' => AccessControl::className(), |
||||
'rules' => [ |
||||
[ |
||||
'allow' => true, |
||||
'roles' => ['BlogManagement'], |
||||
], |
||||
[ // all the action are accessible to admin |
||||
'allow' => true, |
||||
'roles' => ['admin'], |
||||
], |
||||
], |
||||
], |
||||
'verbs' => [ |
||||
'class' => VerbFilter::className(), |
||||
'actions' => [ |
||||
'delete' => ['POST'], |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
public function actionIndex() |
||||
{ |
||||
$searchModel = new BlogCategorySearch(); |
||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); |
||||
|
||||
return $this->render('index', [ |
||||
'searchModel' => $searchModel, |
||||
'dataProvider' => $dataProvider, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return string |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionView($id) |
||||
{ |
||||
$category = $this->findModel($id); |
||||
return $this->render('view', [ |
||||
'category' => $category, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @return string|\yii\web\Response |
||||
*/ |
||||
public function actionCreate() |
||||
{ |
||||
$form = new BlogCategoryForm(); |
||||
$form->updateSort(); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$category = $this->service->create($form); |
||||
return $this->redirect(['view', 'id' => $category->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
return $this->render('create', [ |
||||
'model' => $form, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return string|\yii\web\Response |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionUpdate($id) |
||||
{ |
||||
$category = $this->findModel($id); |
||||
$form = new BlogCategoryForm($category); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$this->service->edit($category->id, $form); |
||||
return $this->redirect(['view', 'id' => $category->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
return $this->render('update', [ |
||||
'model' => $form, |
||||
'category' => $category, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return \yii\web\Response |
||||
*/ |
||||
public function actionDelete($id) |
||||
{ |
||||
//$category = $this->findModel($id); |
||||
try { |
||||
$this->service->remove($id); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
return $this->redirect(['index']); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return BlogCategory |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
protected function findModel($id): BlogCategory |
||||
{ |
||||
if (($model = BlogCategory::findOne($id)) !== null) { |
||||
return $model; |
||||
} |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
} |
@ -0,0 +1,159 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\controllers\manage; |
||||
|
||||
use common\modules\blog\entities\BlogPost; |
||||
use common\modules\blog\forms\BlogCommentEditForm; |
||||
use common\modules\blog\forms\search\BlogCommentSearch; |
||||
use common\modules\blog\services\BlogCommentManageService; |
||||
use Yii; |
||||
use yii\web\Controller; |
||||
use yii\web\NotFoundHttpException; |
||||
use yii\filters\VerbFilter; |
||||
use yii\filters\AccessControl; |
||||
|
||||
class CommentController extends Controller |
||||
{ |
||||
private $service; |
||||
|
||||
public function __construct($id, $module, BlogCommentManageService $service, $config = []) |
||||
{ |
||||
parent::__construct($id, $module, $config); |
||||
$this->service = $service; |
||||
} |
||||
|
||||
public function behaviors(): array |
||||
{ |
||||
return [ |
||||
'access' => [ |
||||
'class' => AccessControl::className(), |
||||
'rules' => [ |
||||
[ |
||||
'allow' => true, |
||||
'roles' => ['BlogManagement'], |
||||
], |
||||
[ // all the action are accessible to admin |
||||
'allow' => true, |
||||
'roles' => ['admin'], |
||||
], |
||||
], |
||||
], |
||||
'verbs' => [ |
||||
'class' => VerbFilter::className(), |
||||
'actions' => [ |
||||
'delete' => ['POST'], |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @return mixed |
||||
*/ |
||||
public function actionIndex() |
||||
{ |
||||
$searchModel = new BlogCommentSearch(); |
||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); |
||||
|
||||
return $this->render('index', [ |
||||
'searchModel' => $searchModel, |
||||
'dataProvider' => $dataProvider, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $post_id |
||||
* @param $id |
||||
* |
||||
* @return string|\yii\web\Response |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionUpdate($post_id, $id) |
||||
{ |
||||
$post = $this->findModel($post_id); |
||||
$comment = $post->getComment($id); |
||||
|
||||
$form = new BlogCommentEditForm($comment); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$this->service->edit($post->id, $comment->id, $form); |
||||
return $this->redirect(['view', 'post_id' => $post->id, 'id' => $comment->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
return $this->render('update', [ |
||||
'post' => $post, |
||||
'model' => $form, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $post_id |
||||
* @param $id |
||||
* |
||||
* @return string |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionView($post_id, $id) |
||||
{ |
||||
$post = $this->findModel($post_id); |
||||
$comment = $post->getComment($id); |
||||
|
||||
return $this->render('view', [ |
||||
'post' => $post, |
||||
'comment' => $comment, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $post_id |
||||
* @param $id |
||||
* |
||||
* @return \yii\web\Response |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionActivate($post_id, $id) |
||||
{ |
||||
$post = $this->findModel($post_id); |
||||
try { |
||||
$this->service->activate($post->id, $id); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
return $this->redirect(['view', 'post_id' => $post_id, 'id' => $id]); |
||||
} |
||||
|
||||
/** |
||||
* @param $post_id |
||||
* @param $id |
||||
* |
||||
* @return \yii\web\Response |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionDelete($post_id, $id) |
||||
{ |
||||
$post = $this->findModel($post_id); |
||||
try { |
||||
$this->service->remove($post->id, $id); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
return $this->redirect(['index']); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return BlogPost |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
protected function findModel($id): BlogPost |
||||
{ |
||||
if (($model = BlogPost::findOne($id)) !== null) { |
||||
return $model; |
||||
} |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
} |
@ -0,0 +1,202 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\controllers\manage; |
||||
|
||||
use common\modules\blog\entities\BlogPost; |
||||
use common\modules\blog\entities\BlogTag; |
||||
use common\modules\blog\forms\BlogPostForm; |
||||
use common\modules\blog\forms\search\BlogPostSearch; |
||||
use common\modules\blog\services\BlogPostManageService; |
||||
use Yii; |
||||
use yii\web\Controller; |
||||
use yii\web\NotFoundHttpException; |
||||
use yii\filters\VerbFilter; |
||||
use yii\filters\AccessControl; |
||||
use yii\web\Response; |
||||
|
||||
class PostController extends Controller |
||||
{ |
||||
private $service; |
||||
|
||||
public function __construct($id, $module, BlogPostManageService $service, $config = []) |
||||
{ |
||||
parent::__construct($id, $module, $config); |
||||
$this->service = $service; |
||||
} |
||||
|
||||
public function behaviors(): array |
||||
{ |
||||
return [ |
||||
'access' => [ |
||||
'class' => AccessControl::className(), |
||||
'rules' => [ |
||||
[ |
||||
'allow' => true, |
||||
'roles' => ['BlogManagement'], |
||||
], |
||||
[ // all the action are accessible to admin |
||||
'allow' => true, |
||||
'roles' => ['admin'], |
||||
], |
||||
], |
||||
], |
||||
'verbs' => [ |
||||
'class' => VerbFilter::className(), |
||||
'actions' => [ |
||||
'delete' => ['POST'], |
||||
'activate' => ['POST'], |
||||
'draft' => ['POST'], |
||||
'delete-photo' => ['POST'], |
||||
'move-photo-up' => ['POST'], |
||||
'move-photo-down' => ['POST'], |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
public function actionIndex() |
||||
{ |
||||
$searchModel = new BlogPostSearch(); |
||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); |
||||
return $this->render( 'index', [ |
||||
'searchModel' => $searchModel, |
||||
'dataProvider' => $dataProvider, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return string |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionView($id) |
||||
{ |
||||
$post = $this->findModel($id); |
||||
return $this->render('view', [ |
||||
'post' => $post, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @return string|Response |
||||
*/ |
||||
public function actionCreate() |
||||
{ |
||||
$form = new BlogPostForm(); |
||||
$form->published_at = date('d.m.Y H:i:s'); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$post = $this->service->create($form); |
||||
return $this->redirect(['view', 'id' => $post->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
return $this->render('create', [ |
||||
'model' => $form, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return string|\yii\web\Response |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionUpdate($id) |
||||
{ |
||||
$post = $this->findModel($id); |
||||
$form = new BlogPostForm($post); |
||||
$form->published_at = date('d.m.Y H:i:s', $form->published_at); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$this->service->edit($post->id, $form); |
||||
return $this->redirect(['view', 'id' => $post->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
return $this->render('update', [ |
||||
'model' => $form, |
||||
'post' => $post, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return Response |
||||
*/ |
||||
public function actionDelete($id) |
||||
{ |
||||
try { |
||||
$this->service->remove($id); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
return $this->redirect(['index']); |
||||
} |
||||
|
||||
/** |
||||
* @param integer $id |
||||
* @return mixed |
||||
*/ |
||||
public function actionActivate($id) |
||||
{ |
||||
try { |
||||
$this->service->activate($id); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
return $this->redirect(['view', 'id' => $id]); |
||||
} |
||||
|
||||
/** |
||||
* @param integer $id |
||||
* @return mixed |
||||
*/ |
||||
public function actionDraft($id) |
||||
{ |
||||
try { |
||||
$this->service->draft($id); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
return $this->redirect(['view', 'id' => $id]); |
||||
} |
||||
|
||||
public function actionTagSearch($q = null, $id = null) |
||||
{ |
||||
\Yii::$app->response->format = Response::FORMAT_JSON; |
||||
$out = ['results' => ['id' => '', 'text' => '']]; |
||||
if (!is_null($q)) { |
||||
$data = BlogTag::find()->select('name as id, name as text')->andWhere(['like', 'name', $q])->orderBy('name')->limit(20)->asArray()->all(); |
||||
$out['results'] = array_values($data); |
||||
} |
||||
elseif ($id > 0) { |
||||
$tag_name = BlogTag::findOne($id)->name; |
||||
$out['results'] = ['id' => $tag_name, 'text' => $tag_name]; |
||||
} |
||||
return $out; |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return BlogPost |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
protected function findModel($id): BlogPost |
||||
{ |
||||
if (($model = BlogPost::findOne($id)) !== null) { |
||||
return $model; |
||||
} |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
} |
@ -0,0 +1,151 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\controllers\manage; |
||||
|
||||
use common\modules\blog\entities\BlogTag; |
||||
use common\modules\blog\forms\BlogTagSingleForm; |
||||
use common\modules\blog\forms\search\BlogTagSearch; |
||||
use common\modules\blog\services\BlogTagManageService; |
||||
use Yii; |
||||
use yii\web\Controller; |
||||
use yii\web\NotFoundHttpException; |
||||
use yii\filters\VerbFilter; |
||||
use yii\filters\AccessControl; |
||||
|
||||
class TagController extends Controller |
||||
{ |
||||
private $service; |
||||
|
||||
public function __construct($id, $module, BlogTagManageService $service, $config = []) |
||||
{ |
||||
parent::__construct($id, $module, $config); |
||||
$this->service = $service; |
||||
} |
||||
|
||||
public function behaviors(): array |
||||
{ |
||||
return [ |
||||
'access' => [ |
||||
'class' => AccessControl::className(), |
||||
'rules' => [ |
||||
[ |
||||
'allow' => true, |
||||
'roles' => ['BlogManagement'], |
||||
], |
||||
[ // all the action are accessible to admin |
||||
'allow' => true, |
||||
'roles' => ['admin'], |
||||
], |
||||
], |
||||
], |
||||
'verbs' => [ |
||||
'class' => VerbFilter::className(), |
||||
'actions' => [ |
||||
'delete' => ['POST'], |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
public function actionIndex() |
||||
{ |
||||
$searchModel = new BlogTagSearch(); |
||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); |
||||
return $this->render('index', [ |
||||
'searchModel' => $searchModel, |
||||
'dataProvider' => $dataProvider, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return string |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionView($id) |
||||
{ |
||||
$tag = $this->findModel($id); |
||||
return $this->render('view', [ |
||||
'tag' => $tag, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @return string|\yii\web\Response |
||||
*/ |
||||
public function actionCreate() |
||||
{ |
||||
$form = new BlogTagSingleForm(); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$tag = $this->service->create($form); |
||||
return $this->redirect(['view', 'id' => $tag->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
return $this->render('create', [ |
||||
'model' => $form, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return string|\yii\web\Response |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
public function actionUpdate($id) |
||||
{ |
||||
$tag = $this->findModel($id); |
||||
$form = new BlogTagSingleForm($tag); |
||||
if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
||||
try { |
||||
$this->service->edit($tag->id, $form); |
||||
return $this->redirect(['view', 'id' => $tag->id]); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
} |
||||
return $this->render('update', [ |
||||
'model' => $form, |
||||
'tag' => $tag, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return \yii\web\Response |
||||
*/ |
||||
public function actionDelete($id) |
||||
{ |
||||
try { |
||||
$this->service->remove($id); |
||||
} catch (\DomainException $e) { |
||||
Yii::$app->errorHandler->logException($e); |
||||
Yii::$app->session->setFlash('error', $e->getMessage()); |
||||
} |
||||
return $this->redirect(['index']); |
||||
} |
||||
|
||||
/** |
||||
* @param $id |
||||
* |
||||
* @return BlogTag |
||||
* @throws NotFoundHttpException |
||||
*/ |
||||
protected function findModel($id): BlogTag |
||||
{ |
||||
if (($model = BlogTag::findOne($id)) !== null) { |
||||
return $model; |
||||
} |
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
||||
} |
||||
} |
@ -0,0 +1,88 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\entities; |
||||
|
||||
use core\behaviors\MetaBehavior; |
||||
use core\entities\Meta; |
||||
use yii\db\ActiveRecord; |
||||
use Yii; |
||||
|
||||
|
||||
/** |
||||
* @property integer $id |
||||
* @property string $name |
||||
* @property string $slug |
||||
* @property string $title |
||||
* @property string $description |
||||
* @property integer $sort |
||||
* @property string $meta_json |
||||
* @property Meta $meta |
||||
*/ |
||||
class BlogCategory extends ActiveRecord |
||||
{ |
||||
public $meta; |
||||
|
||||
public static function create($name, $slug, $title, $description, $sort, Meta $meta): self |
||||
{ |
||||
$category = new static(); |
||||
$category->name = $name; |
||||
$category->slug = $slug; |
||||
$category->title = $title; |
||||
$category->description = $description; |
||||
$category->sort = $sort; |
||||
$category->meta = $meta; |
||||
return $category; |
||||
} |
||||
|
||||
public function edit($name, $slug, $title, $description, $sort, Meta $meta): void |
||||
{ |
||||
$this->name = $name; |
||||
$this->slug = $slug; |
||||
$this->title = $title; |
||||
$this->description = $description; |
||||
$this->sort = $sort; |
||||
$this->meta = $meta; |
||||
} |
||||
|
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'id' => Yii::t('blog', 'ID'), |
||||
'name' => Yii::t('blog', 'Name'), |
||||
'slug' => Yii::t('blog', 'SEO link'), |
||||
'sort' => Yii::t('blog', 'Sort'), |
||||
'title' => Yii::t('blog', 'Title'), |
||||
'description' => Yii::t('blog', 'Description'), |
||||
'meta.title' => Yii::t('blog', 'Meta Title'), |
||||
'meta.description' => Yii::t('blog', 'Meta Description'), |
||||
'meta.keywords' => Yii::t('blog', 'Meta Keywords'), |
||||
]; |
||||
} |
||||
|
||||
public function getSeoTitle(): string |
||||
{ |
||||
return $this->meta->title ?: $this->getHeadingTile(); |
||||
} |
||||
|
||||
public function getHeadingTile(): string |
||||
{ |
||||
return $this->title ?: $this->name; |
||||
} |
||||
|
||||
public function getPostsCount(): int |
||||
{ |
||||
return BlogPost::find()->where(['category_id' => $this->id])->count('*'); |
||||
} |
||||
|
||||
public static function tableName(): string |
||||
{ |
||||
return '{{%blog_categories}}'; |
||||
} |
||||
|
||||
public function behaviors(): array |
||||
{ |
||||
return [ |
||||
MetaBehavior::className(), |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,93 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\entities; |
||||
|
||||
use core\entities\user\User; |
||||
use yii\db\ActiveQuery; |
||||
use yii\db\ActiveRecord; |
||||
use Yii; |
||||
|
||||
|
||||
/** |
||||
* @property int $id |
||||
* @property int $created_at |
||||
* @property int $post_id |
||||
* @property int $user_id |
||||
* @property int $parent_id |
||||
* @property string $text |
||||
* @property bool $active |
||||
* |
||||
* @property BlogPost $post |
||||
*/ |
||||
class BlogComment extends ActiveRecord |
||||
{ |
||||
public static function create($userId, $parentId, $text): self |
||||
{ |
||||
$review = new static(); |
||||
$review->user_id = $userId; |
||||
$review->parent_id = $parentId; |
||||
$review->text = $text; |
||||
$review->created_at = time(); |
||||
$review->active = true; |
||||
return $review; |
||||
} |
||||
|
||||
public function edit($parentId, $text): void |
||||
{ |
||||
$this->parent_id = $parentId; |
||||
$this->text = $text; |
||||
} |
||||
|
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'id' => Yii::t('blog', 'ID'), |
||||
'user_id' => Yii::t('blog', 'User'), |
||||
'parent_id' => Yii::t('blog', 'Parent Comment ID'), |
||||
'created_at' => Yii::t('blog', 'Created At'), |
||||
'active' => Yii::t('blog', 'Published'), |
||||
'post_id' => Yii::t('blog', 'Post'), |
||||
'text' => Yii::t('blog', 'Comment'), |
||||
]; |
||||
} |
||||
|
||||
public function activate(): void |
||||
{ |
||||
$this->active = true; |
||||
} |
||||
|
||||
public function draft(): void |
||||
{ |
||||
$this->active = false; |
||||
} |
||||
|
||||
public function isActive(): bool |
||||
{ |
||||
return $this->active == true; |
||||
} |
||||
|
||||
public function isIdEqualTo($id): bool |
||||
{ |
||||
return $this->id == $id; |
||||
} |
||||
|
||||
public function isChildOf($id): bool |
||||
{ |
||||
return $this->parent_id == $id; |
||||
} |
||||
|
||||
public function getPost(): ActiveQuery |
||||
{ |
||||
return $this->hasOne(BlogPost::class, ['id' => 'post_id']); |
||||
} |
||||
|
||||
public function getUser(): ActiveQuery |
||||
{ |
||||
return $this->hasOne(User::class, ['id' => 'user_id']); |
||||
} |
||||
|
||||
public static function tableName(): string |
||||
{ |
||||
return '{{%blog_comments}}'; |
||||
} |
||||
} |
@ -0,0 +1,347 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\entities; |
||||
|
||||
use common\modules\blog\entities\queries\BlogPostQuery; |
||||
use core\behaviors\MetaBehavior; |
||||
use core\entities\Meta; |
||||
use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior; |
||||
use yii\behaviors\TimestampBehavior; |
||||
use yii\db\ActiveQuery; |
||||
use yii\db\ActiveRecord; |
||||
use yii\web\UploadedFile; |
||||
use yiidreamteam\upload\ImageUploadBehavior; |
||||
use Yii; |
||||
|
||||
|
||||
/** |
||||
* This is the model class for table "posts". |
||||
* |
||||
* @property int $id |
||||
* @property int $category_id |
||||
* @property int $published_at |
||||
* @property int $created_at |
||||
* @property int $updated_at |
||||
* @property string $title |
||||
* @property string $description |
||||
* @property string $content |
||||
* @property string $image |
||||
* @property string $video |
||||
* @property int $status |
||||
* @property string $meta_json |
||||
* @property int $comments_count |
||||
* @property int $views |
||||
* @property string $slug |
||||
* |
||||
* @property BlogComment[] $blogComments |
||||
* @property BlogTagAssignment[] $blogTagAssignments |
||||
* @property BlogTag[] $tags |
||||
* @property BlogCategory $category |
||||
* |
||||
* @mixin ImageUploadBehavior |
||||
*/ |
||||
class BlogPost extends ActiveRecord |
||||
{ |
||||
const STATUS_DRAFT = 0; |
||||
const STATUS_ACTIVE = 1; |
||||
|
||||
const FILE_ORIGINAL_PATH = '@staticRoot/origin/posts'; |
||||
|
||||
public $meta; |
||||
|
||||
public static function create($categoryId, $title, $slug, $description, $content, $published_at, $video, Meta $meta): self |
||||
{ |
||||
$post = new static(); |
||||
$post->category_id = $categoryId; |
||||
$post->title = $title; |
||||
$post->slug = $slug; |
||||
$post->description = $description; |
||||
$post->content = $content; |
||||
$post->meta = $meta; |
||||
$post->status = self::STATUS_DRAFT; |
||||
$post->created_at = time(); |
||||
$post->comments_count = 0; |
||||
$post->published_at = $published_at; |
||||
$post->video = $video; |
||||
return $post; |
||||
} |
||||
|
||||
public function setImage(UploadedFile $image): void |
||||
{ |
||||
$this->image = $image; |
||||
} |
||||
|
||||
|
||||
public function edit($categoryId, $title, $slug, $description, $content, $published_at, $video, Meta $meta): void |
||||
{ |
||||
$this->category_id = $categoryId; |
||||
$this->title = $title; |
||||
$this->slug = $slug; |
||||
$this->description = $description; |
||||
$this->content = $content; |
||||
$this->meta = $meta; |
||||
$this->published_at = $published_at; |
||||
$this->video = $video; |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public static function tableName() |
||||
{ |
||||
return 'blog_posts'; |
||||
} |
||||
|
||||
/** |
||||
* @inheritdoc |
||||
*/ |
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'id' => Yii::t('blog', 'ID'), |
||||
'category_id' => Yii::t('blog', 'Category'), |
||||
'published_at' => Yii::t('blog', 'Published At'), |
||||
'created_at' => Yii::t('blog', 'Created At'), |
||||
'updated_at' => Yii::t('blog', 'Updated At'), |
||||
'title' => Yii::t('blog', 'Title'), |
||||
'description' => Yii::t('blog', 'Description'), |
||||
'content' => Yii::t('blog', 'Content'), |
||||
'image' => Yii::t('blog', 'Image'), |
||||
'video' => Yii::t('blog', 'Video'), |
||||
'status' => Yii::t('blog', 'Status'), |
||||
'meta_json' => Yii::t('blog', 'Meta Json'), |
||||
'comments_count' => Yii::t('blog', 'Comments Count'), |
||||
'views' => Yii::t('blog', 'Views'), |
||||
'slug' => Yii::t('blog', 'Slug'), |
||||
'meta.title' => Yii::t('blog', 'Meta Title'), |
||||
'meta.description' => Yii::t('blog', 'Meta Description'), |
||||
'meta.keywords' => Yii::t('blog', 'Meta Keywords'), |
||||
]; |
||||
} |
||||
|
||||
public function activate(): void |
||||
{ |
||||
if ($this->isActive()) { |
||||
throw new \DomainException('Post is already active.'); |
||||
} |
||||
$this->status = self::STATUS_ACTIVE; |
||||
} |
||||
|
||||
public function draft(): void |
||||
{ |
||||
if ($this->isDraft()) { |
||||
throw new \DomainException('Post is already draft.'); |
||||
} |
||||
$this->status = self::STATUS_DRAFT; |
||||
} |
||||
|
||||
public function isActive(): bool |
||||
{ |
||||
return $this->status == self::STATUS_ACTIVE; |
||||
} |
||||
|
||||
|
||||
public function isDraft(): bool |
||||
{ |
||||
return $this->status == self::STATUS_DRAFT; |
||||
} |
||||
|
||||
public function getSeoTitle(): string |
||||
{ |
||||
return $this->meta->title ?: $this->title; |
||||
} |
||||
|
||||
// Tags |
||||
|
||||
public function assignTag($id): void |
||||
{ |
||||
$assignments = $this->blogTagAssignments; |
||||
foreach ($assignments as $assignment) { |
||||
if ($assignment->isForTag($id)) { |
||||
return; |
||||
} |
||||
} |
||||
$assignments[] = BlogTagAssignment::create($id); |
||||
$this->blogTagAssignments = $assignments; |
||||
} |
||||
|
||||
public function revokeTag($id): void |
||||
{ |
||||
$assignments = $this->blogTagAssignments; |
||||
foreach ($assignments as $i => $assignment) { |
||||
if ($assignment->isForTag($id)) { |
||||
unset($assignments[$i]); |
||||
$this->blogTagAssignments = $assignments; |
||||
return; |
||||
} |
||||
} |
||||
throw new \DomainException('Assignment is not found.'); |
||||
} |
||||
|
||||
public function revokeTags(): void |
||||
{ |
||||
$this->blogTagAssignments = []; |
||||
} |
||||
|
||||
// Comments |
||||
|
||||
public function addComment($userId, $parentId, $text): BlogComment |
||||
{ |
||||
$parent = $parentId ? $this->getComment($parentId) : null; |
||||
if ($parent && !$parent->isActive()) { |
||||
throw new \DomainException('Cannot add comment to inactive parent.'); |
||||
} |
||||
$comments = $this->blogComments; |
||||
$comments[] = $comment = BlogComment::create($userId, $parent ? $parent->id : null, $text); |
||||
$this->updateComments($comments); |
||||
return $comment; |
||||
} |
||||
|
||||
public function editComment($id, $parentId, $text): void |
||||
{ |
||||
$parent = $parentId ? $this->getComment($parentId) : null; |
||||
$comments = $this->blogComments; |
||||
foreach ($comments as $comment) { |
||||
if ($comment->isIdEqualTo($id)) { |
||||
$comment->edit($parent ? $parent->id : null, $text); |
||||
$this->updateComments($comments); |
||||
return; |
||||
} |
||||
} |
||||
throw new \DomainException('Comment is not found.'); |
||||
} |
||||
|
||||
public function activateComment($id): void |
||||
{ |
||||
$comments = $this->blogComments; |
||||
foreach ($comments as $comment) { |
||||
if ($comment->isIdEqualTo($id)) { |
||||
$comment->activate(); |
||||
$this->updateComments($comments); |
||||
return; |
||||
} |
||||
} |
||||
throw new \DomainException('Comment is not found.'); |
||||
} |
||||
|
||||
public function removeComment($id): void |
||||
{ |
||||
$comments = $this->blogComments; |
||||
foreach ($comments as $i => $comment) { |
||||
if ($comment->isIdEqualTo($id)) { |
||||
if ($this->hasChildren($comment->id)) { |
||||
$comment->draft(); |
||||
} else { |
||||
unset($comments[$i]); |
||||
} |
||||
$this->updateComments($comments); |
||||
return; |
||||
} |
||||
} |
||||
throw new \DomainException('Comment is not found.'); |
||||
} |
||||
|
||||
public function getComment($id): BlogComment |
||||
{ |
||||
foreach ($this->blogComments as $comment) { |
||||
if ($comment->isIdEqualTo($id)) { |
||||
return $comment; |
||||
} |
||||
} |
||||
throw new \DomainException('Comment is not found.'); |
||||
} |
||||
|
||||
private function hasChildren($id): bool |
||||
{ |
||||
foreach ($this->blogComments as $comment) { |
||||
if ($comment->isChildOf($id)) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private function updateComments(array $comments): void |
||||
{ |
||||
$this->blogComments = $comments; |
||||
$this->comments_count = count(array_filter($comments, function (BlogComment $comment) { |
||||
return $comment->isActive(); |
||||
})); |
||||
} |
||||
|
||||
###################################### |
||||
|
||||
public function getBlogComments(): ActiveQuery |
||||
{ |
||||
return $this->hasMany(BlogComment::className(), ['post_id' => 'id']); |
||||
} |
||||
|
||||
public function getBlogTagAssignments(): ActiveQuery |
||||
{ |
||||
return $this->hasMany(BlogTagAssignment::className(), ['post_id' => 'id']); |
||||
} |
||||
|
||||
public function getTags(): ActiveQuery |
||||
{ |
||||
return $this->hasMany(BlogTag::className(), ['id' => 'tag_id'])->viaTable('post_tag_assignments', ['post_id' => 'id']); |
||||
} |
||||
|
||||
public function getCategory(): ActiveQuery |
||||
{ |
||||
return $this->hasOne(BlogCategory::className(), ['id' => 'category_id']); |
||||
} |
||||
|
||||
###################################### |
||||
|
||||
public function behaviors(): array |
||||
{ |
||||
return [ |
||||
TimestampBehavior::className(), |
||||
MetaBehavior::className(), |
||||
[ |
||||
'class' => SaveRelationsBehavior::className(), |
||||
'relations' => ['blogTagAssignments', 'blogComments'], |
||||
], |
||||
[ |
||||
// todo Image Sizes to settings or theme settings |
||||
'class' => ImageUploadBehavior::className(), |
||||
'attribute' => 'image', |
||||
'createThumbsOnRequest' => true, |
||||
//'filePath' => $this::FILE_ORIGINAL_PATH . '/[[id]].[[extension]]', |
||||
'filePath' => '@staticRoot/origin/posts/[[id]].[[extension]]', |
||||
'fileUrl' => '@static/origin/posts/[[id]].[[extension]]', |
||||
'thumbPath' => '@staticRoot/cache/posts/[[profile]]_[[id]].[[extension]]', |
||||
'thumbUrl' => '@static/cache/posts/[[profile]]_[[id]].[[extension]]', |
||||
'thumbs' => [ |
||||
'blog_list' => ['width' => 750, 'height' => 300], |
||||
'blog_post' => ['width' => 900, 'height' => 300], |
||||
|
||||
'admin' => ['width' => 60, 'height' => 60], |
||||
'thumb' => ['width' => 150, 'height' => 150], |
||||
'list' => ['width' => 200, 'height' => 200], |
||||
'home_slider' => ['width' => 369, 'height' => 343], |
||||
'94_94' => ['width' => 94, 'height' => 94], |
||||
'368_287' => ['width' => 368, 'height' => 287], |
||||
'370_325' => ['width' => 370, 'height' => 325], |
||||
'683_407' => ['width' => 683, 'height' => 407], |
||||
'thumb_gallery_view' => ['width' => 300, 'height' => 170], |
||||
//'widget_list' => ['width' => 228, 'height' => 228], |
||||
//'origin' => ['processor' => [new WaterMarker(1024, 768, '@frontend/web/image/logo.png'), 'process']], |
||||
'origin' => ['width' => 1024, 'height' => 768], |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
|
||||
public function transactions(): array |
||||
{ |
||||
return [ |
||||
self::SCENARIO_DEFAULT => self::OP_ALL, |
||||
]; |
||||
} |
||||
|
||||
public static function find(): BlogPostQuery |
||||
{ |
||||
return new BlogPostQuery(static::class); |
||||
} |
||||
} |
@ -0,0 +1,46 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\entities; |
||||
|
||||
use yii\db\ActiveRecord; |
||||
use yii\caching\TagDependency; |
||||
use Yii; |
||||
|
||||
/** |
||||
* @property integer $id |
||||
* @property string $name |
||||
* @property string $slug |
||||
*/ |
||||
class BlogTag extends ActiveRecord |
||||
{ |
||||
public static function create($name, $slug): self |
||||
{ |
||||
$tag = new static(); |
||||
$tag->name = $name; |
||||
$tag->slug = $slug; |
||||
return $tag; |
||||
} |
||||
|
||||
public function edit($name, $slug): void |
||||
{ |
||||
$this->name = $name; |
||||
if ($slug != $this->slug) |
||||
{ |
||||
TagDependency::invalidate(\Yii::$app->cache, 'blog_tags'); |
||||
} |
||||
$this->slug = $slug; |
||||
} |
||||
|
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'name' => Yii::t('blog', 'Tag Name'), |
||||
'slug' => Yii::t('blog', 'SEO link'), |
||||
]; |
||||
} |
||||
|
||||
public static function tableName(): string |
||||
{ |
||||
return '{{%blog_tags}}'; |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\entities; |
||||
|
||||
use yii\db\ActiveRecord; |
||||
|
||||
/** |
||||
* @property integer $post_id; |
||||
* @property integer $tag_id; |
||||
*/ |
||||
class BlogTagAssignment extends ActiveRecord |
||||
{ |
||||
public static function create($tagId): self |
||||
{ |
||||
$assignment = new static(); |
||||
$assignment->tag_id = $tagId; |
||||
return $assignment; |
||||
} |
||||
|
||||
public function isForTag($id): bool |
||||
{ |
||||
return $this->tag_id == $id; |
||||
} |
||||
|
||||
public static function tableName(): string |
||||
{ |
||||
return '{{%blog_tag_assignments}}'; |
||||
} |
||||
} |
@ -0,0 +1,35 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\entities\queries; |
||||
|
||||
use common\modules\blog\entities\BlogPost; |
||||
use yii\db\ActiveQuery; |
||||
|
||||
class BlogPostQuery extends ActiveQuery |
||||
{ |
||||
/** |
||||
* @param null $alias |
||||
* @return $this |
||||
*/ |
||||
public function active($alias = null) |
||||
{ |
||||
return $this->andWhere([ |
||||
($alias ? $alias . '.' : '') . 'status' => BlogPost::STATUS_ACTIVE, |
||||
]); |
||||
} |
||||
|
||||
public function byType($type) |
||||
{ |
||||
return $this->andWhere(['type_id' => $type]); |
||||
} |
||||
|
||||
public function last() |
||||
{ |
||||
return $this->orderBy(['published_at' => SORT_DESC]); |
||||
} |
||||
|
||||
public function popular() |
||||
{ |
||||
return $this->orderBy(['views' => SORT_DESC]); |
||||
} |
||||
} |
@ -0,0 +1,71 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use core\forms\CompositeForm; |
||||
use core\forms\MetaForm; |
||||
use core\validators\SlugValidator; |
||||
use Yii; |
||||
|
||||
/** |
||||
* @property MetaForm $meta; |
||||
*/ |
||||
class BlogCategoryForm extends CompositeForm |
||||
{ |
||||
public $name; |
||||
public $slug; |
||||
public $title; |
||||
public $description; |
||||
public $sort; |
||||
|
||||
private $_category; |
||||
|
||||
public function __construct(BlogCategory $category = null, $config = []) |
||||
{ |
||||
if ($category) { |
||||
$this->name = $category->name; |
||||
$this->slug = $category->slug; |
||||
$this->title = $category->title; |
||||
$this->description = $category->description; |
||||
$this->sort = $category->sort; |
||||
$this->meta = new MetaForm($category->meta); |
||||
$this->_category = $category; |
||||
} else { |
||||
$this->meta = new MetaForm(); |
||||
$this->sort = BlogCategory::find()->max('sort') + 1; |
||||
} |
||||
parent::__construct($config); |
||||
} |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['name', 'slug'], 'required'], |
||||
[['name', 'slug', 'title'], 'string', 'max' => 255], |
||||
[['description'], 'string'], |
||||
['slug', SlugValidator::class], |
||||
[['name', 'slug'], 'unique', 'targetClass' => BlogCategory::class, 'filter' => $this->_category ? ['<>', 'id', $this->_category->id] : null] |
||||
]; |
||||
} |
||||
|
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'name' => Yii::t('blog', 'Name'), |
||||
'slug' => Yii::t('blog', 'SEO link'), |
||||
'sort' => Yii::t('blog', 'Sort'), |
||||
'title' => Yii::t('blog', 'Title'), |
||||
'description' => Yii::t('blog', 'Description'), |
||||
]; |
||||
} |
||||
|
||||
public function updateSort() { |
||||
$this->sort = BlogCategory::find()->max('sort') + 1; |
||||
} |
||||
|
||||
public function internalForms(): array |
||||
{ |
||||
return ['meta']; |
||||
} |
||||
} |
@ -0,0 +1,37 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms; |
||||
|
||||
use common\modules\blog\entities\BlogComment; |
||||
use yii\base\Model; |
||||
use Yii; |
||||
|
||||
class BlogCommentEditForm extends Model |
||||
{ |
||||
public $parentId; |
||||
public $text; |
||||
|
||||
public function __construct(BlogComment $comment, $config = []) |
||||
{ |
||||
$this->parentId = $comment->parent_id; |
||||
$this->text = $comment->text; |
||||
parent::__construct($config); |
||||
} |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['text'], 'required'], |
||||
['text', 'string'], |
||||
['parentId', 'integer'], |
||||
]; |
||||
} |
||||
|
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'parentId' => Yii::t('blog', 'Parent Comment ID'), |
||||
'text' => Yii::t('blog', 'Comment'), |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,20 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms; |
||||
|
||||
use yii\base\Model; |
||||
|
||||
class BlogCommentForm extends Model |
||||
{ |
||||
public $parentId; |
||||
public $text; |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['text'], 'required'], |
||||
['text', 'string'], |
||||
['parentId', 'integer'], |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,108 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use common\modules\blog\entities\BlogPost; |
||||
use core\forms\CompositeForm; |
||||
use core\forms\MetaForm; |
||||
use core\validators\SlugValidator; |
||||
use yii\helpers\ArrayHelper; |
||||
use yii\web\UploadedFile; |
||||
use Yii; |
||||
|
||||
/** |
||||
* @property MetaForm $meta |
||||
* @property BlogTagForm $tags |
||||
*/ |
||||
class BlogPostForm extends CompositeForm |
||||
{ |
||||
public $category_id; |
||||
public $title; |
||||
public $description; |
||||
public $content; |
||||
public $image; |
||||
public $video; |
||||
public $published_at; |
||||
public $slug; |
||||
public $reset_image; |
||||
|
||||
public $_post; |
||||
|
||||
public function __construct(BlogPost $post = null, $config = []) |
||||
{ |
||||
if ($post) { |
||||
$this->category_id = $post->category_id; |
||||
$this->title = $post->title; |
||||
$this->description = $post->description; |
||||
$this->content = $post->content; |
||||
$this->video = $post->video; |
||||
$this->published_at = $post->published_at; |
||||
$this->slug = $post->slug; |
||||
$this->meta = new MetaForm($post->meta); |
||||
$this->tags = new BlogTagForm($post); |
||||
$this->_post = $post; |
||||
} else { |
||||
$this->meta = new MetaForm(); |
||||
$this->tags = new BlogTagForm(); |
||||
} |
||||
parent::__construct($config); |
||||
} |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['category_id', 'title'], 'required'], |
||||
[['title', 'video'], 'string', 'max' => 255], |
||||
[['category_id'], 'integer'], |
||||
[['description', 'content'], 'string'], |
||||
[['image'], 'image'], |
||||
['reset_image', 'boolean'], |
||||
['published_at', 'safe'], |
||||
['slug', SlugValidator::class], |
||||
[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => $this->_post ? ['<>', 'id', $this->_post->id] : null], |
||||
]; |
||||
} |
||||
|
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'id' => Yii::t('blog', 'ID'), |
||||
'category_id' => Yii::t('blog', 'Category'), |
||||
'published_at' => Yii::t('blog', 'Published At'), |
||||
'created_at' => Yii::t('blog', 'Created At'), |
||||
'updated_at' => Yii::t('blog', 'Updated At'), |
||||
'title' => Yii::t('blog', 'Title'), |
||||
'description' => Yii::t('blog', 'Description'), |
||||
'content' => Yii::t('blog', 'Content'), |
||||
'image' => Yii::t('blog', 'Image'), |
||||
'video' => Yii::t('blog', 'Video'), |
||||
'status' => Yii::t('blog', 'Status'), |
||||
'meta_json' => Yii::t('blog', 'Meta Json'), |
||||
'comments_count' => Yii::t('blog', 'Comments Count'), |
||||
'views' => Yii::t('blog', 'Views'), |
||||
'slug' => Yii::t('blog', 'Slug'), |
||||
'reset_image' => Yii::t('blog', 'Reset Image'), |
||||
]; |
||||
} |
||||
|
||||
public function categoriesList(): array |
||||
{ |
||||
return ArrayHelper::map(BlogCategory::find()->orderBy('sort')->asArray()->all(), 'id', 'name'); |
||||
} |
||||
|
||||
protected function internalForms(): array |
||||
{ |
||||
return ['meta', 'tags']; |
||||
} |
||||
|
||||
public function beforeValidate(): bool |
||||
{ |
||||
if (parent::beforeValidate()) { |
||||
$this->image = UploadedFile::getInstance($this, 'image'); |
||||
$this->published_at = strtotime($this->published_at); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
} |
@ -0,0 +1,46 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms; |
||||
|
||||
use common\modules\blog\entities\BlogPost; |
||||
use common\modules\blog\entities\BlogTag; |
||||
use yii\base\Model; |
||||
use yii\helpers\ArrayHelper; |
||||
|
||||
/** |
||||
* @property array $newNames |
||||
*/ |
||||
class BlogTagForm extends Model |
||||
{ |
||||
public $existing = []; |
||||
public $textNew; |
||||
public $new_tags; |
||||
|
||||
public function __construct(BlogPost $post = null, $config = []) |
||||
{ |
||||
if ($post) { |
||||
$this->existing = ArrayHelper::getColumn($post->blogTagAssignments, 'tag_id'); |
||||
} |
||||
parent::__construct($config); |
||||
} |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
['existing', 'each', 'rule' => ['integer']], |
||||
[['textNew'], 'string'], |
||||
['existing', 'default', 'value' => []], |
||||
['new_tags', 'each', 'rule' => ['string']], |
||||
]; |
||||
} |
||||
|
||||
public function tagsList(): array |
||||
{ |
||||
return ArrayHelper::map(BlogTag::find()->orderBy('name')->asArray()->all(), 'id', 'name'); |
||||
} |
||||
|
||||
public function getNewNames(): array |
||||
{ |
||||
return array_filter(array_map('trim', preg_split('#\s*,\s*#i', $this->textNew))); |
||||
} |
||||
} |
@ -0,0 +1,45 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms; |
||||
|
||||
use common\modules\blog\entities\BlogTag; |
||||
use core\validators\SlugValidator; |
||||
use yii\base\Model; |
||||
use Yii; |
||||
|
||||
class BlogTagSingleForm extends Model |
||||
{ |
||||
public $name; |
||||
public $slug; |
||||
public $type_id; |
||||
|
||||
private $_tag; |
||||
|
||||
public function __construct(BlogTag $tag = null, $config = []) |
||||
{ |
||||
if ($tag) { |
||||
$this->name = $tag->name; |
||||
$this->slug = $tag->slug; |
||||
$this->_tag = $tag; |
||||
} |
||||
parent::__construct($config); |
||||
} |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['name', 'slug'], 'required'], |
||||
[['name', 'slug'], 'string', 'max' => 255], |
||||
['slug', SlugValidator::class], |
||||
[['name', 'slug'], 'unique', 'targetClass' => BlogTag::class, 'filter' => $this->_tag ? ['<>', 'id', $this->_tag->id] : null] |
||||
]; |
||||
} |
||||
|
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'name' => Yii::t('blog', 'Tag Name'), |
||||
'slug' => Yii::t('blog', 'SEO link'), |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,57 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms\search; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use yii\base\Model; |
||||
use yii\data\ActiveDataProvider; |
||||
|
||||
class BlogCategorySearch extends Model |
||||
{ |
||||
public $id; |
||||
public $name; |
||||
public $slug; |
||||
public $title; |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['id'], 'integer'], |
||||
[['name', 'slug', 'title'], 'safe'], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @param array $params |
||||
* @return ActiveDataProvider |
||||
*/ |
||||
public function search(array $params): ActiveDataProvider |
||||
{ |
||||
$query = BlogCategory::find(); |
||||
|
||||
$dataProvider = new ActiveDataProvider([ |
||||
'query' => $query, |
||||
'sort' => [ |
||||
'defaultOrder' => ['sort' => SORT_ASC] |
||||
] |
||||
]); |
||||
|
||||
$this->load($params); |
||||
|
||||
if (!$this->validate()) { |
||||
$query->where('0=1'); |
||||
return $dataProvider; |
||||
} |
||||
|
||||
$query->andFilterWhere([ |
||||
'id' => $this->id, |
||||
]); |
||||
|
||||
$query |
||||
->andFilterWhere(['like', 'name', $this->name]) |
||||
->andFilterWhere(['like', 'slug', $this->slug]) |
||||
->andFilterWhere(['like', 'title', $this->title]); |
||||
|
||||
return $dataProvider; |
||||
} |
||||
} |
@ -0,0 +1,72 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms\search; |
||||
|
||||
use common\modules\blog\entities\BlogComment; |
||||
use Yii; |
||||
use yii\base\Model; |
||||
use yii\data\ActiveDataProvider; |
||||
|
||||
class BlogCommentSearch extends Model |
||||
{ |
||||
public $id; |
||||
public $text; |
||||
public $active; |
||||
public $post_id; |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['id', 'post_id'], 'integer'], |
||||
[['text'], 'safe'], |
||||
[['active'], 'boolean'], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @param array $params |
||||
* @return ActiveDataProvider |
||||
*/ |
||||
public function search(array $params): ActiveDataProvider |
||||
{ |
||||
$query = BlogComment::find()->with(['post']); |
||||
|
||||
$dataProvider = new ActiveDataProvider([ |
||||
'query' => $query, |
||||
'key' => function (BlogComment $comment) { |
||||
return [ |
||||
'post_id' => $comment->post_id, |
||||
'id' => $comment->id, |
||||
]; |
||||
}, |
||||
'sort' => [ |
||||
'defaultOrder' => ['id' => SORT_DESC] |
||||
] |
||||
]); |
||||
|
||||
$this->load($params); |
||||
|
||||
if (!$this->validate()) { |
||||
$query->where('0=1'); |
||||
return $dataProvider; |
||||
} |
||||
|
||||
$query->andFilterWhere([ |
||||
'id' => $this->id, |
||||
'post_id' => $this->post_id, |
||||
]); |
||||
|
||||
$query |
||||
->andFilterWhere(['like', 'text', $this->text]); |
||||
|
||||
return $dataProvider; |
||||
} |
||||
|
||||
public function activeList(): array |
||||
{ |
||||
return [ |
||||
1 => Yii::$app->formatter->asBoolean(true), |
||||
0 => Yii::$app->formatter->asBoolean(false), |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,69 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms\search; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use common\modules\blog\entities\BlogPost; |
||||
use common\modules\blog\helpers\BlogPostHelper; |
||||
use yii\base\Model; |
||||
use yii\data\ActiveDataProvider; |
||||
use yii\helpers\ArrayHelper; |
||||
|
||||
class BlogPostSearch extends Model |
||||
{ |
||||
public $id; |
||||
public $title; |
||||
public $status; |
||||
public $category_id; |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['id', 'status', 'category_id'], 'integer'], |
||||
[['title'], 'safe'], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @param array $params |
||||
* @return ActiveDataProvider |
||||
*/ |
||||
public function search(array $params): ActiveDataProvider |
||||
{ |
||||
$query = BlogPost::find(); |
||||
|
||||
$dataProvider = new ActiveDataProvider([ |
||||
'query' => $query, |
||||
'sort' => [ |
||||
'defaultOrder' => ['id' => SORT_DESC] |
||||
] |
||||
]); |
||||
|
||||
$this->load($params); |
||||
|
||||
if (!$this->validate()) { |
||||
$query->where('0=1'); |
||||
return $dataProvider; |
||||
} |
||||
|
||||
$query->andFilterWhere([ |
||||
'id' => $this->id, |
||||
'category_id' => $this->category_id, |
||||
]); |
||||
|
||||
$query |
||||
->andFilterWhere(['like', 'title', $this->title]); |
||||
|
||||
return $dataProvider; |
||||
} |
||||
|
||||
public function categoriesList(): array |
||||
{ |
||||
return ArrayHelper::map(BlogCategory::find()->orderBy('sort')->asArray()->all(), 'id', 'title'); |
||||
} |
||||
|
||||
public function statusList(): array |
||||
{ |
||||
return BlogPostHelper::statusList(); |
||||
} |
||||
} |
@ -0,0 +1,55 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\forms\search; |
||||
|
||||
use common\modules\blog\entities\BlogTag; |
||||
use yii\base\Model; |
||||
use yii\data\ActiveDataProvider; |
||||
|
||||
class BlogTagSearch extends Model |
||||
{ |
||||
public $id; |
||||
public $name; |
||||
public $slug; |
||||
|
||||
public function rules(): array |
||||
{ |
||||
return [ |
||||
[['id'], 'integer'], |
||||
[['name', 'slug'], 'safe'], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @param array $params |
||||
* @return ActiveDataProvider |
||||
*/ |
||||
public function search(array $params): ActiveDataProvider |
||||
{ |
||||
$query = BlogTag::find(); |
||||
|
||||
$dataProvider = new ActiveDataProvider([ |
||||
'query' => $query, |
||||
'sort' => [ |
||||
'defaultOrder' => ['name' => SORT_ASC] |
||||
] |
||||
]); |
||||
|
||||
$this->load($params); |
||||
|
||||
if (!$this->validate()) { |
||||
$query->where('0=1'); |
||||
return $dataProvider; |
||||
} |
||||
|
||||
$query->andFilterWhere([ |
||||
'id' => $this->id, |
||||
]); |
||||
|
||||
$query |
||||
->andFilterWhere(['like', 'name', $this->name]) |
||||
->andFilterWhere(['like', 'slug', $this->slug]); |
||||
|
||||
return $dataProvider; |
||||
} |
||||
} |
@ -0,0 +1,70 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\helpers; |
||||
|
||||
use core\entities\post\Post; |
||||
use yii\helpers\ArrayHelper; |
||||
use yii\helpers\Html; |
||||
use Yii; |
||||
|
||||
class BlogPostHelper |
||||
{ |
||||
public static function statusList(): array |
||||
{ |
||||
return [ |
||||
Post::STATUS_DRAFT => Yii::t('blog', 'Draft'), |
||||
Post::STATUS_ACTIVE => Yii::t('blog', 'Active'), |
||||
]; |
||||
} |
||||
|
||||
public static function statusName($status): string |
||||
{ |
||||
return ArrayHelper::getValue(self::statusList(), $status); |
||||
} |
||||
|
||||
public static function statusLabel($status): string |
||||
{ |
||||
switch ($status) { |
||||
case Post::STATUS_DRAFT: |
||||
$class = 'label label-default'; |
||||
break; |
||||
case Post::STATUS_ACTIVE: |
||||
$class = 'label label-success'; |
||||
break; |
||||
default: |
||||
$class = 'label label-default'; |
||||
} |
||||
|
||||
return Html::tag('span', ArrayHelper::getValue(self::statusList(), $status), [ |
||||
'class' => $class, |
||||
]); |
||||
} |
||||
|
||||
public static function parseYoutubeUrl($url) |
||||
{ |
||||
$urls = parse_url($url); |
||||
//url is http://youtu.be/xxxx |
||||
if($urls['host'] == 'youtu.be'){ |
||||
$id = ltrim($urls['path'],'/'); |
||||
} |
||||
//url is http://www.youtube.com/embed/xxxx |
||||
else if(strpos($urls['path'],'embed') == 1){ |
||||
$id = end(explode('/',$urls['path'])); |
||||
} |
||||
//url is xxxx only |
||||
else if(strpos($url,'/')===false){ |
||||
$id = $url; |
||||
} |
||||
//http://www.youtube.com/watch?feature=player_embedded&v=m-t4pcO99gI |
||||
//url is http://www.youtube.com/watch?v=xxxx |
||||
else{ |
||||
parse_str($urls['query']); |
||||
/* @var $v */ |
||||
$id = $v; |
||||
if(!empty($feature)){ |
||||
$id = end(explode('v=',$urls['query'])); |
||||
} |
||||
} |
||||
return $id; |
||||
} |
||||
} |
@ -0,0 +1,61 @@
|
||||
<?php |
||||
return [ |
||||
'All Posts' => 'Все статьи', |
||||
'Posts' => 'Статьи', |
||||
'Categories' => 'Категории', |
||||
'Tags' => 'Теги', |
||||
'News' => 'Новости', |
||||
'Comments' => 'Комментарии', |
||||
'Articles' => 'Статьи', |
||||
'Blog' => 'Блог', |
||||
'Blogs' => 'Блоги', |
||||
'Events' => 'События', |
||||
'Gallery' => 'Фотогалерея', |
||||
'Create Post' => 'Новая статья', |
||||
'Create Category' => 'Новая категория', |
||||
'Create Tag' => 'Новый тег', |
||||
'Common' => 'Основное', |
||||
'Title' => 'Заголовок', |
||||
'Description' => 'Описание', |
||||
'Content' => 'Содержание', |
||||
'Image' => 'Изображение', |
||||
'Existing' => 'Существующие', |
||||
'New tag' => 'Новый тег', |
||||
'Category' => 'Категория', |
||||
'Post is already active.' => 'Статья уже опубликована.', |
||||
'Published At' => 'Опубликовано', |
||||
'Created At' => 'Создано', |
||||
'Updated At' => 'Обновлено', |
||||
'Status' => 'Статус', |
||||
'ID' => '№', |
||||
'SEO' => 'МЕТА теги', |
||||
'Tag Name' => 'Тег', |
||||
'SEO link' => 'ЧПУ ссылка', |
||||
'Draft' => 'Черновик', |
||||
'Active' => 'Опубликовано', |
||||
'Activate' => 'Опубликовать', |
||||
'Meta Title' => 'Заголовок', |
||||
'Meta Description' => 'Описание', |
||||
'Meta Keywords' => 'Ключевые слова', |
||||
'Name' => 'Название', |
||||
'Sort' => 'Позиция', |
||||
'Update: {name}' => 'Редактирование: {name}', |
||||
'Types' => 'Типы', |
||||
'Create Type' => 'Новый тип', |
||||
'Singular' => 'Единственное число', |
||||
'Plural' => 'Множественное число', |
||||
'Slug' => 'ЧПУ ссылка', |
||||
'Update Post: {name}' => 'Редактирование: {name}', |
||||
'Update Post Comment: {name}' => 'Редактирование комментария: {name}', |
||||
'Update Tag: {name}' => 'Редактирование тега: {name}', |
||||
'Parent Comment ID' => 'Родительский комментарий', |
||||
'Comment' => 'Комментарий', |
||||
'Published' => 'Опубликовано', |
||||
'User' => 'Пользователь', |
||||
'Post' => 'Статья', |
||||
'YouTube URL' => 'Ссылка YouTube', |
||||
'Add Image' => 'Новое изображение', |
||||
'Video' => 'Видео', |
||||
'If a video link is specified, the image will be used as a preview image' => 'Если указана ссылка на видео, то изображение будет рассматриваться как картинка для предварительного просмотра', |
||||
'Reset Image' => 'Сбросить изображение', |
||||
]; |
@ -0,0 +1,8 @@
|
||||
<?php |
||||
|
||||
return [ |
||||
'Blog' => 'Блог', |
||||
'Read More' => 'Подробнее', |
||||
'Leave a Comment' => 'Комментировать', |
||||
'Categories' => 'Категории', |
||||
]; |
@ -0,0 +1,31 @@
|
||||
<?php |
||||
|
||||
use yii\db\Migration; |
||||
|
||||
/** |
||||
* Handles the creation of table `blog_categories`. |
||||
*/ |
||||
class m180605_184534_create_blog_categories_table extends Migration |
||||
{ |
||||
public function up() |
||||
{ |
||||
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; |
||||
|
||||
$this->createTable('{{%blog_categories}}', [ |
||||
'id' => $this->primaryKey(), |
||||
'name' => $this->string()->notNull(), |
||||
'slug' => $this->string()->notNull(), |
||||
'title' => $this->string(), |
||||
'description' => $this->text(), |
||||
'sort' => $this->integer()->notNull(), |
||||
'meta_json' => 'LONGTEXT NOT NULL', |
||||
], $tableOptions); |
||||
|
||||
$this->createIndex('{{%idx-blog_categories-slug}}', '{{%blog_categories}}', 'slug', true); |
||||
} |
||||
|
||||
public function down() |
||||
{ |
||||
$this->dropTable('{{%blog_categories}}'); |
||||
} |
||||
} |
@ -0,0 +1,42 @@
|
||||
<?php |
||||
|
||||
use yii\db\Migration; |
||||
|
||||
/** |
||||
* Handles the creation of table `blog_posts`. |
||||
*/ |
||||
class m180605_190347_create_blog_posts_table extends Migration |
||||
{ |
||||
public function up() |
||||
{ |
||||
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; |
||||
|
||||
$this->createTable('{{%blog_posts}}', [ |
||||
'id' => $this->primaryKey(), |
||||
'category_id' => $this->integer()->notNull(), |
||||
'published_at' => $this->integer()->unsigned()->notNull(), |
||||
'created_at' => $this->integer()->unsigned(), |
||||
'updated_at' => $this->integer()->unsigned(), |
||||
'title' => $this->string()->notNull(), |
||||
'description' => $this->text(), |
||||
'content' => 'MEDIUMTEXT', |
||||
'image' => $this->string(), |
||||
'video' => $this->string(), |
||||
'status' => $this->integer()->notNull(), |
||||
'meta_json' => 'TEXT NOT NULL', |
||||
'comments_count' => $this->integer()->notNull()->defaultValue(0), |
||||
'views' => $this->integer()->notNull()->defaultValue(0), |
||||
'slug' => $this->string()->notNull(), |
||||
], $tableOptions); |
||||
|
||||
$this->createIndex('{{%idx-blog_posts-category_id}}', '{{%blog_posts}}', 'category_id'); |
||||
$this->createIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}', 'slug', true); |
||||
$this->addForeignKey('{{%fk-blog_posts-category_id}}', '{{%blog_posts}}', 'category_id', '{{%blog_categories}}', 'id'); |
||||
} |
||||
|
||||
public function down() |
||||
{ |
||||
$this->dropForeignKey('{{%fk-blog_posts-category_id}}', '{{%blog_posts}}'); |
||||
$this->dropTable('{{%blog_posts}}'); |
||||
} |
||||
} |
@ -0,0 +1,28 @@
|
||||
<?php |
||||
|
||||
use yii\db\Migration; |
||||
|
||||
/** |
||||
* Handles the creation of table `blog_tags`. |
||||
*/ |
||||
class m180605_193423_create_blog_tags_table extends Migration |
||||
{ |
||||
public function up() |
||||
{ |
||||
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; |
||||
|
||||
$this->createTable('{{%blog_tags}}', [ |
||||
'id' => $this->primaryKey(), |
||||
'name' => $this->string()->notNull(), |
||||
'slug' => $this->string()->notNull(), |
||||
], $tableOptions); |
||||
|
||||
$this->createIndex('{{%idx-blog_tags-slug}}', '{{%blog_tags}}', 'slug', true); |
||||
} |
||||
|
||||
public function down() |
||||
{ |
||||
$this->dropIndex('{{%idx-blog_tags-slug}}', '{{%blog_tags}}'); |
||||
$this->dropTable('{{%blog_tags}}'); |
||||
} |
||||
} |
@ -0,0 +1,36 @@
|
||||
<?php |
||||
|
||||
use yii\db\Migration; |
||||
|
||||
/** |
||||
* Handles the creation of table `blog_tag_assignments`. |
||||
*/ |
||||
class m180605_193748_create_blog_tag_assignments_table extends Migration |
||||
{ |
||||
public function up() |
||||
{ |
||||
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; |
||||
|
||||
$this->createTable('{{%blog_tag_assignments}}', [ |
||||
'post_id' => $this->integer()->notNull(), |
||||
'tag_id' => $this->integer()->notNull(), |
||||
], $tableOptions); |
||||
|
||||
$this->addPrimaryKey('{{%pk-blog_tag_assignments}}', '{{%blog_tag_assignments}}', ['post_id', 'tag_id']); |
||||
|
||||
$this->createIndex('{{%idx-blog_tag_assignments-post_id}}', '{{%blog_tag_assignments}}', 'post_id'); |
||||
$this->createIndex('{{%idx-blog_tag_assignments-tag_id}}', '{{%blog_tag_assignments}}', 'tag_id'); |
||||
|
||||
$this->addForeignKey('{{%fk-blog_tag_assignments-post_id}}', '{{%blog_tag_assignments}}', 'post_id', '{{%blog_posts}}', 'id', 'CASCADE', 'RESTRICT'); |
||||
$this->addForeignKey('{{%fk-blog_tag_assignments-tag_id}}', '{{%blog_tag_assignments}}', 'tag_id', '{{%blog_tags}}', 'id', 'CASCADE', 'RESTRICT'); |
||||
} |
||||
|
||||
public function down() |
||||
{ |
||||
$this->dropIndex('{{%idx-blog_tag_assignments-tag_id}}', '{{%blog_tag_assignments}}'); |
||||
$this->dropIndex('{{%idx-blog_tag_assignments-post_id}}', '{{%blog_tag_assignments}}'); |
||||
$this->dropForeignKey('{{%fk-blog_tag_assignments-tag_id}}', '{{%blog_tag_assignments}}'); |
||||
$this->dropForeignKey('{{%fk-blog_tag_assignments-post_id}}', '{{%blog_tag_assignments}}'); |
||||
$this->dropTable('{{%blog_tag_assignments}}'); |
||||
} |
||||
} |
@ -0,0 +1,43 @@
|
||||
<?php |
||||
|
||||
use yii\db\Migration; |
||||
|
||||
/** |
||||
* Handles the creation of table `blog_comments`. |
||||
*/ |
||||
class m180605_194207_create_blog_comments_table extends Migration |
||||
{ |
||||
public function up() |
||||
{ |
||||
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; |
||||
|
||||
$this->createTable('{{%blog_comments}}', [ |
||||
'id' => $this->primaryKey(), |
||||
'post_id' => $this->integer()->notNull(), |
||||
'user_id' => $this->integer()->notNull(), |
||||
'parent_id' => $this->integer(), |
||||
'created_at' => $this->integer()->unsigned()->notNull(), |
||||
'text' => $this->text()->notNull(), |
||||
'active' => $this->boolean()->notNull(), |
||||
], $tableOptions); |
||||
|
||||
$this->createIndex('{{%idx-blog_comments-post_id}}', '{{%blog_comments}}', 'post_id'); |
||||
$this->createIndex('{{%idx-blog_comments-user_id}}', '{{%blog_comments}}', 'user_id'); |
||||
$this->createIndex('{{%idx-blog_comments-parent_id}}', '{{%blog_comments}}', 'parent_id'); |
||||
|
||||
$this->addForeignKey('{{%fk-blog_comments-post_id}}', '{{%blog_comments}}', 'post_id', '{{%blog_posts}}', 'id', 'CASCADE'); |
||||
$this->addForeignKey('{{%fk-blog_comments-user_id}}', '{{%blog_comments}}', 'user_id', '{{%users}}', 'id', 'CASCADE'); |
||||
$this->addForeignKey('{{%fk-blog_comments-parent_id}}', '{{%blog_comments}}', 'parent_id', '{{%blog_comments}}', 'id', 'CASCADE'); |
||||
} |
||||
|
||||
public function down() |
||||
{ |
||||
$this->dropForeignKey('{{%fk-blog_comments-parent_id}}', '{{%blog_comments}}'); |
||||
$this->dropForeignKey('{{%fk-blog_comments-user_id}}', '{{%blog_comments}}'); |
||||
$this->dropForeignKey('{{%fk-blog_comments-post_id}}', '{{%blog_comments}}'); |
||||
$this->dropIndex('{{%idx-blog_comments-parent_id}}', '{{%blog_comments}}'); |
||||
$this->dropIndex('{{%idx-blog_comments-user_id}}', '{{%blog_comments}}'); |
||||
$this->dropIndex('{{%idx-blog_comments-post_id}}', '{{%blog_comments}}'); |
||||
$this->dropTable('{{%blog_comments}}'); |
||||
} |
||||
} |
@ -0,0 +1,31 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\repositories; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use core\repositories\NotFoundException; |
||||
|
||||
class BlogCategoryRepository |
||||
{ |
||||
public function get($id): BlogCategory |
||||
{ |
||||
if (!$category = BlogCategory::findOne($id)) { |
||||
throw new NotFoundException('Category is not found.'); |
||||
} |
||||
return $category; |
||||
} |
||||
|
||||
public function save(BlogCategory $category): void |
||||
{ |
||||
if (!$category->save()) { |
||||
throw new \RuntimeException('Saving error.'); |
||||
} |
||||
} |
||||
|
||||
public function remove(BlogCategory $category): void |
||||
{ |
||||
if (!$category->delete()) { |
||||
throw new \RuntimeException('Removing error.'); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,36 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\repositories; |
||||
|
||||
use common\modules\blog\entities\BlogPost; |
||||
use core\repositories\NotFoundException; |
||||
|
||||
class BlogRepository |
||||
{ |
||||
public function get($id): BlogPost |
||||
{ |
||||
if (!$post = BlogPost::findOne($id)) { |
||||
throw new NotFoundException('Post is not found.'); |
||||
} |
||||
return $post; |
||||
} |
||||
|
||||
public function existsByCategory($id): bool |
||||
{ |
||||
return BlogPost::find()->andWhere(['category_id' => $id])->exists(); |
||||
} |
||||
|
||||
public function save(BlogPost $post): void |
||||
{ |
||||
if (!$post->save()) { |
||||
throw new \RuntimeException('Saving error.'); |
||||
} |
||||
} |
||||
|
||||
public function remove(BlogPost $post): void |
||||
{ |
||||
if (!$post->delete()) { |
||||
throw new \RuntimeException('Removing error.'); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,36 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\repositories; |
||||
|
||||
use common\modules\blog\entities\BlogTag; |
||||
use core\repositories\NotFoundException; |
||||
|
||||
class BlogTagRepository |
||||
{ |
||||
public function get($id): BlogTag |
||||
{ |
||||
if (!$tag = BlogTag::findOne($id)) { |
||||
throw new NotFoundException('Tag is not found.'); |
||||
} |
||||
return $tag; |
||||
} |
||||
|
||||
public function findByName($name): ?BlogTag |
||||
{ |
||||
return BlogTag::findOne(['name' => $name]); |
||||
} |
||||
|
||||
public function save(BlogTag $tag): void |
||||
{ |
||||
if (!$tag->save()) { |
||||
throw new \RuntimeException('Saving error.'); |
||||
} |
||||
} |
||||
|
||||
public function remove(BlogTag $tag): void |
||||
{ |
||||
if (!$tag->delete()) { |
||||
throw new \RuntimeException('Removing error.'); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,23 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\repositories\read; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
|
||||
class BlogCategoryReadRepository |
||||
{ |
||||
public function getAll(): array |
||||
{ |
||||
return BlogCategory::find()->orderBy('sort')->all(); |
||||
} |
||||
|
||||
public function find($id): ?BlogCategory |
||||
{ |
||||
return BlogCategory::findOne($id); |
||||
} |
||||
|
||||
public function findBySlug($slug): ?BlogCategory |
||||
{ |
||||
return BlogCategory::find()->andWhere(['slug' => $slug])->one(); |
||||
} |
||||
} |
@ -0,0 +1,94 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\repositories\read; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use common\modules\blog\entities\BlogPost; |
||||
use common\modules\blog\entities\BlogTag; |
||||
use yii\data\ActiveDataProvider; |
||||
use yii\data\DataProviderInterface; |
||||
use yii\db\ActiveQuery; |
||||
|
||||
class BlogPostReadRepository |
||||
{ |
||||
public function count(): int |
||||
{ |
||||
return BlogPost::find()->active()->count(); |
||||
} |
||||
|
||||
public function getAllByRange($offset, $limit): array |
||||
{ |
||||
return BlogPost::find()->active()->orderBy(['id' => SORT_ASC])->limit($limit)->offset($offset)->all(); |
||||
} |
||||
|
||||
public function getAll(): DataProviderInterface |
||||
{ |
||||
$query = BlogPost::find()->active()->with('category'); |
||||
return $this->getProvider($query); |
||||
} |
||||
|
||||
public function getAllByCategory(BlogCategory $category): DataProviderInterface |
||||
{ |
||||
$query = BlogPost::find()->active()->andWhere(['category_id' => $category->id])->with('category'); |
||||
return $this->getProvider($query); |
||||
} |
||||
|
||||
public function findNext(int $id): ?BlogPost |
||||
{ |
||||
return BlogPost::find()->active()->andWhere(['>', 'id', $id])->one(); |
||||
} |
||||
|
||||
public function findPrev(int $id): ?BlogPost |
||||
{ |
||||
return BlogPost::find()->active()->andWhere(['<', 'id', $id])->orderBy(['id' => SORT_DESC])->one(); |
||||
} |
||||
|
||||
|
||||
public function getAllByTag(BlogTag $tag): DataProviderInterface |
||||
{ |
||||
$query = BlogPost::find()->alias('p')->active('p')->with('category'); |
||||
$query->joinWith(['blogTagAssignments ta'], false); |
||||
$query->andWhere(['ta.tag_id' => $tag->id]); |
||||
$query->groupBy('p.id'); |
||||
return $this->getProvider($query); |
||||
} |
||||
|
||||
public function getByTagsId(BlogPost $post, array $tag_ids, int $limit = 15): DataProviderInterface |
||||
{ |
||||
$query = BlogPost::find()->alias('p')->active('p')->with('category'); |
||||
$query->joinWith(['blogTagAssignments ta'], false); |
||||
$query->andWhere(['ta.tag_id' => $tag_ids]); |
||||
$query->andWhere(['!=', 'p.id', $post->id]); |
||||
$query->groupBy('p.id'); |
||||
$query->limit($limit); |
||||
return $this->getProvider($query); |
||||
} |
||||
|
||||
public function getLast($limit): array |
||||
{ |
||||
return BlogPost::find()->with('category')->orderBy(['id' => SORT_DESC])->limit($limit)->all(); |
||||
} |
||||
|
||||
public function getPopular($limit): array |
||||
{ |
||||
return BlogPost::find()->with('category')->orderBy(['comments_count' => SORT_DESC])->limit($limit)->all(); |
||||
} |
||||
|
||||
public function find($id): ?BlogPost |
||||
{ |
||||
return BlogPost::find()->active()->andWhere(['id' => $id])->one(); |
||||
} |
||||
|
||||
private function getProvider(ActiveQuery $query): ActiveDataProvider |
||||
{ |
||||
return new ActiveDataProvider([ |
||||
'query' => $query, |
||||
'sort' => ['defaultOrder' => ['created_at' => SORT_DESC]], |
||||
]); |
||||
} |
||||
|
||||
public function findBySlug($slug): ?BlogPost |
||||
{ |
||||
return BlogPost::find()->andWhere(['slug' => $slug])->one(); |
||||
} |
||||
} |
@ -0,0 +1,18 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\repositories\read; |
||||
|
||||
use common\modules\blog\entities\BlogTag; |
||||
|
||||
class BlogTagReadRepository |
||||
{ |
||||
public function find($id): ?BlogTag |
||||
{ |
||||
return BlogTag::findOne($id); |
||||
} |
||||
|
||||
public function findBySlug($slug): ?BlogTag |
||||
{ |
||||
return BlogTag::find()->andWhere(['slug' => $slug])->one(); |
||||
} |
||||
} |
@ -0,0 +1,66 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\services; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use common\modules\blog\forms\BlogCategoryForm; |
||||
use common\modules\blog\repositories\BlogCategoryRepository; |
||||
use common\modules\blog\repositories\BlogRepository; |
||||
use core\entities\Meta; |
||||
|
||||
class BlogCategoryManageService |
||||
{ |
||||
private $categories; |
||||
private $posts; |
||||
|
||||
public function __construct(BlogCategoryRepository $categories, BlogRepository $posts) |
||||
{ |
||||
$this->categories = $categories; |
||||
$this->posts = $posts; |
||||
} |
||||
|
||||
public function create(BlogCategoryForm $form): BlogCategory |
||||
{ |
||||
$category = BlogCategory::create( |
||||
$form->name, |
||||
$form->slug, |
||||
$form->title, |
||||
$form->description, |
||||
$form->sort, |
||||
new Meta( |
||||
$form->meta->title, |
||||
$form->meta->description, |
||||
$form->meta->keywords |
||||
) |
||||
); |
||||
$this->categories->save($category); |
||||
return $category; |
||||
} |
||||
|
||||
public function edit($id, BlogCategoryForm $form): void |
||||
{ |
||||
$category = $this->categories->get($id); |
||||
$category->edit( |
||||
$form->name, |
||||
$form->slug, |
||||
$form->title, |
||||
$form->description, |
||||
$form->sort, |
||||
new Meta( |
||||
$form->meta->title, |
||||
$form->meta->description, |
||||
$form->meta->keywords |
||||
) |
||||
); |
||||
$this->categories->save($category); |
||||
} |
||||
|
||||
public function remove($id): void |
||||
{ |
||||
$category = $this->categories->get($id); |
||||
if ($this->posts->existsByCategory($category->id)) { |
||||
throw new \DomainException('Unable to remove category with posts.'); |
||||
} |
||||
$this->categories->remove($category); |
||||
} |
||||
} |
@ -0,0 +1,37 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\services; |
||||
|
||||
use common\modules\blog\forms\BlogCommentEditForm; |
||||
use common\modules\blog\repositories\BlogRepository; |
||||
|
||||
class BlogCommentManageService |
||||
{ |
||||
private $posts; |
||||
|
||||
public function __construct(BlogRepository $posts) |
||||
{ |
||||
$this->posts = $posts; |
||||
} |
||||
|
||||
public function edit($postId, $id, BlogCommentEditForm $form): void |
||||
{ |
||||
$post = $this->posts->get($postId); |
||||
$post->editComment($id, $form->parentId, $form->text); |
||||
$this->posts->save($post); |
||||
} |
||||
|
||||
public function activate($postId, $id): void |
||||
{ |
||||
$post = $this->posts->get($postId); |
||||
$post->activateComment($id); |
||||
$this->posts->save($post); |
||||
} |
||||
|
||||
public function remove($postId, $id): void |
||||
{ |
||||
$post = $this->posts->get($postId); |
||||
$post->removeComment($id); |
||||
$this->posts->save($post); |
||||
} |
||||
} |
@ -0,0 +1,32 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\services; |
||||
|
||||
use common\modules\blog\entities\BlogComment; |
||||
use common\modules\blog\forms\BlogCommentForm; |
||||
use common\modules\blog\repositories\BlogRepository; |
||||
use core\repositories\user\UserRepository; |
||||
|
||||
class BlogCommentService |
||||
{ |
||||
private $posts; |
||||
private $users; |
||||
|
||||
public function __construct(BlogRepository $posts, UserRepository $users) |
||||
{ |
||||
$this->posts = $posts; |
||||
$this->users = $users; |
||||
} |
||||
|
||||
public function create($postId, $userId, BlogCommentForm $form): BlogComment |
||||
{ |
||||
$post = $this->posts->get($postId); |
||||
$user = $this->users->get($userId); |
||||
|
||||
$comment = $post->addComment($user->id, $form->parentId, $form->text); |
||||
|
||||
$this->posts->save($post); |
||||
|
||||
return $comment; |
||||
} |
||||
} |
@ -0,0 +1,162 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\services; |
||||
|
||||
use common\modules\blog\entities\BlogPost; |
||||
use common\modules\blog\entities\BlogTag; |
||||
use common\modules\blog\forms\BlogPostForm; |
||||
use common\modules\blog\helpers\BlogPostHelper; |
||||
use common\modules\blog\repositories\BlogCategoryRepository; |
||||
use common\modules\blog\repositories\BlogRepository; |
||||
use common\modules\blog\repositories\BlogTagRepository; |
||||
use core\entities\Meta; |
||||
use core\services\TransactionManager; |
||||
use yii\base\Security; |
||||
use yii\helpers\Inflector; |
||||
|
||||
class BlogPostManageService |
||||
{ |
||||
private $posts; |
||||
private $categories; |
||||
private $tags; |
||||
private $transaction; |
||||
|
||||
public function __construct( |
||||
BlogRepository $posts, |
||||
BlogCategoryRepository $categories, |
||||
BlogTagRepository $tags, |
||||
TransactionManager $transaction |
||||
) |
||||
{ |
||||
$this->posts = $posts; |
||||
$this->categories = $categories; |
||||
$this->tags = $tags; |
||||
$this->transaction = $transaction; |
||||
} |
||||
|
||||
public function create(BlogPostForm $form): BlogPost |
||||
{ |
||||
$category = $this->categories->get($form->category_id); |
||||
|
||||
$post = BlogPost::create( |
||||
$category->id, |
||||
$form->title, |
||||
$form->slug, |
||||
$form->description, |
||||
$form->content, |
||||
$form->published_at, |
||||
$form->video, |
||||
new Meta( |
||||
$form->meta->title, |
||||
$form->meta->description, |
||||
$form->meta->keywords |
||||
) |
||||
); |
||||
|
||||
if ($form->image) { |
||||
$post->setImage($form->image); |
||||
} |
||||
else if ($form->video) { |
||||
$src = 'https://i.ytimg.com/vi/' . BlogPostHelper::parseYoutubeUrl($post->video) . '/maxresdefault.jpg'; |
||||
$filename = (new Security())->generateRandomString(15) . '.jpg'; |
||||
copy($src, \Yii::getAlias(BlogPost::FILE_ORIGINAL_PATH . '/' . $post->id . '.jpg')); |
||||
$post->image = $filename; |
||||
} |
||||
|
||||
$this->transaction->wrap(function () use ($post, $form) { |
||||
|
||||
if (is_array($form->tags->new_tags) && !empty($form->tags->new_tags)) { |
||||
foreach ( $form->tags->new_tags as $tag_id => $tag_name ) { |
||||
if ( !$tag = $this->tags->findByName( $tag_name ) ) { |
||||
$tag = BlogTag::create( $tag_name, Inflector::slug( $tag_name, '_' ) ); |
||||
$this->tags->save( $tag ); |
||||
} |
||||
$post->assignTag( $tag->id ); |
||||
} |
||||
} |
||||
$this->posts->save($post); |
||||
}); |
||||
|
||||
return $post; |
||||
} |
||||
|
||||
public function edit($id, BlogPostForm $form): void |
||||
{ |
||||
$post = $this->posts->get($id); |
||||
$category = $this->categories->get($form->category_id); |
||||
|
||||
$post->edit( |
||||
$category->id, |
||||
$form->title, |
||||
$form->slug, |
||||
$form->description, |
||||
$form->content, |
||||
$form->published_at, |
||||
$form->video, |
||||
new Meta( |
||||
$form->meta->title, |
||||
$form->meta->description, |
||||
$form->meta->keywords |
||||
) |
||||
); |
||||
|
||||
if ($form->image) { |
||||
$post->cleanFiles(); |
||||
$post->setImage($form->image); |
||||
} |
||||
elseif ($form->video && (!$post->image || $form->reset_image)) { |
||||
$post->cleanFiles(); |
||||
$src = 'https://i.ytimg.com/vi/' . BlogPostHelper::parseYoutubeUrl($post->video) . '/maxresdefault.jpg'; |
||||
$filename = (new Security())->generateRandomString(15) . '.jpg'; |
||||
copy($src, \Yii::getAlias(BlogPost::FILE_ORIGINAL_PATH . '/' . $post->id . '.jpg')); |
||||
$post->image = $filename; |
||||
} |
||||
elseif ($post->image && $form->reset_image) { |
||||
$post->cleanFiles(); |
||||
//Post::updateAll(['image' => null], ['id' => $post->id]); |
||||
$post->image = null; |
||||
$post->updateAttributes(['image']); |
||||
} |
||||
|
||||
$this->transaction->wrap(function () use ($post, $form) { |
||||
$post->revokeTags(); |
||||
$this->posts->save($post); |
||||
|
||||
$tag_updated = false; |
||||
if (is_array($form->tags->new_tags) && !empty($form->tags->new_tags)) { |
||||
foreach ( $form->tags->new_tags as $tag_id => $tag_name ) { |
||||
if ( ! $tag = $this->tags->findByName( $tag_name ) ) { |
||||
$tag = BlogTag::create( $tag_name, Inflector::slug( $tag_name, '_' ) ); |
||||
$this->tags->save( $tag ); |
||||
} |
||||
$post->assignTag( $tag->id ); |
||||
$tag_updated = true; |
||||
} |
||||
} |
||||
|
||||
if ($tag_updated) { |
||||
$this->posts->save( $post ); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public function activate($id): void |
||||
{ |
||||
$post = $this->posts->get($id); |
||||
$post->activate(); |
||||
$this->posts->save($post); |
||||
} |
||||
|
||||
public function draft($id): void |
||||
{ |
||||
$post = $this->posts->get($id); |
||||
$post->draft(); |
||||
$this->posts->save($post); |
||||
} |
||||
|
||||
public function remove($id): void |
||||
{ |
||||
$post = $this->posts->get($id); |
||||
$this->posts->remove($post); |
||||
} |
||||
} |
@ -0,0 +1,43 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\services; |
||||
|
||||
use common\modules\blog\entities\BlogTag; |
||||
use common\modules\blog\forms\BlogTagSingleForm; |
||||
use common\modules\blog\repositories\BlogTagRepository; |
||||
|
||||
class BlogTagManageService |
||||
{ |
||||
private $tags; |
||||
|
||||
public function __construct(BlogTagRepository $tags) |
||||
{ |
||||
$this->tags = $tags; |
||||
} |
||||
|
||||
public function create(BlogTagSingleForm $form): BlogTag |
||||
{ |
||||
$tag = BlogTag::create( |
||||
$form->name, |
||||
$form->slug |
||||
); |
||||
$this->tags->save($tag); |
||||
return $tag; |
||||
} |
||||
|
||||
public function edit($id, BlogTagSingleForm $form): void |
||||
{ |
||||
$tag = $this->tags->get($id); |
||||
$tag->edit( |
||||
$form->name, |
||||
$form->slug |
||||
); |
||||
$this->tags->save($tag); |
||||
} |
||||
|
||||
public function remove($id): void |
||||
{ |
||||
$tag = $this->tags->get($id); |
||||
$this->tags->remove($tag); |
||||
} |
||||
} |
@ -0,0 +1,91 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\urls; |
||||
|
||||
use yii\caching\TagDependency; |
||||
use common\modules\blog\repositories\read\BlogCategoryReadRepository; |
||||
use yii\base\BaseObject; |
||||
use yii\base\InvalidParamException; |
||||
use yii\caching\Cache; |
||||
use yii\web\UrlNormalizerRedirectException; |
||||
use yii\web\UrlRuleInterface; |
||||
|
||||
class BlogCategoryUrlRule extends BaseObject implements UrlRuleInterface |
||||
{ |
||||
public $prefix = 'blog/category'; |
||||
|
||||
private $repository; |
||||
private $cache; |
||||
|
||||
public function __construct(BlogCategoryReadRepository $repository, Cache $cache, $config = []) |
||||
{ |
||||
parent::__construct($config); |
||||
$this->repository = $repository; |
||||
$this->cache = $cache; |
||||
} |
||||
|
||||
public function parseRequest($manager, $request) |
||||
{ |
||||
if (preg_match('#^' . $this->prefix . '/(.*[a-z])$#is', $request->pathInfo, $matches)) { |
||||
$path = $matches['1']; |
||||
|
||||
$result = $this->cache->getOrSet( [ 'blog_category_route', 'path' => $path ], function () use ( $path ) { |
||||
if ( ! $post = $this->repository->findBySlug( $this->getPathSlug( $path ) ) ) { |
||||
return [ 'id' => null, 'path' => null ]; |
||||
} |
||||
return [ 'id' => $post->id, 'path' => $post->slug ]; |
||||
}, null, new TagDependency(['tags' => ['blog']]) ); |
||||
|
||||
if ( empty( $result['id'] ) ) { |
||||
return false; |
||||
} |
||||
|
||||
if ( $path != $result['path'] ) { |
||||
throw new UrlNormalizerRedirectException( [ |
||||
'blog/post/category', |
||||
'id' => $result['id'], |
||||
], 301 ); |
||||
} |
||||
|
||||
return [ 'blog/post/category', [ 'id' => $result['id'] ] ]; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public function createUrl($manager, $route, $params) |
||||
{ |
||||
if ($route == 'blog/post/category') { |
||||
if (empty($params['id'])) { |
||||
throw new InvalidParamException('Empty id.'); |
||||
} |
||||
$id = $params['id']; |
||||
|
||||
$url = $this->cache->getOrSet(['blog_category_route', 'id' => $id], function () use ($id) { |
||||
if (!$post = $this->repository->find($id)) { |
||||
return null; |
||||
} |
||||
return $post->slug; |
||||
//return $this->getPagePath($post); |
||||
}, null, new TagDependency(['tags' => ['blog']])); |
||||
|
||||
if (!$url) { |
||||
throw new InvalidParamException('Undefined id.'); |
||||
} |
||||
|
||||
$url = $this->prefix . '/' . $url; |
||||
unset($params['id']); |
||||
if (!empty($params) && ($query = http_build_query($params)) !== '') { |
||||
$url .= '?' . $query; |
||||
} |
||||
|
||||
return $url; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private function getPathSlug($path): string |
||||
{ |
||||
$chunks = explode('/', $path); |
||||
return end($chunks); |
||||
} |
||||
} |
@ -0,0 +1,88 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\urls; |
||||
|
||||
use common\modules\blog\repositories\read\BlogPostReadRepository; |
||||
use yii\base\BaseObject; |
||||
use yii\base\InvalidParamException; |
||||
use yii\caching\Cache; |
||||
use yii\caching\TagDependency; |
||||
use yii\web\UrlNormalizerRedirectException; |
||||
use yii\web\UrlRuleInterface; |
||||
use InvalidArgumentException; |
||||
|
||||
class BlogMainUrlRule extends BaseObject implements UrlRuleInterface |
||||
{ |
||||
public $prefix = 'blog/post'; |
||||
|
||||
private $repository; |
||||
private $cache; |
||||
|
||||
public function __construct(BlogPostReadRepository $repository, Cache $cache, $config = []) |
||||
{ |
||||
parent::__construct($config); |
||||
$this->repository = $repository; |
||||
$this->cache = $cache; |
||||
} |
||||
|
||||
public function parseRequest($manager, $request) |
||||
{ |
||||
if (preg_match('#^' . $this->prefix . '/(.*[a-z])$#is', $request->pathInfo, $matches)) { |
||||
$path = $matches['1']; |
||||
|
||||
$result = $this->cache->getOrSet( [ 'blog_main_route', 'path' => $path ], function () use ( $path ) { |
||||
if ( ! $post = $this->repository->findBySlug($this->getPathSlug( $path ) ) ) { |
||||
return [ 'id' => null, 'path' => null ]; |
||||
} |
||||
return [ 'id' => $post->id, 'path' => $post->slug ]; |
||||
}, null, new TagDependency(['tags' => ['blog']]) ); |
||||
|
||||
if ( empty( $result['id'] ) ) { |
||||
return false; |
||||
} |
||||
|
||||
if ( $path != $result['path'] ) { |
||||
throw new UrlNormalizerRedirectException( [ 'blog/post/post', 'id' => $result['id'] ], 301 ); |
||||
} |
||||
|
||||
return ['blog/post/post', ['id' => $result['id']]]; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public function createUrl($manager, $route, $params) |
||||
{ |
||||
if ($route == 'blog/post/post') { |
||||
if (empty($params['id'])) { |
||||
throw new InvalidArgumentException('Empty id.'); |
||||
} |
||||
$id = $params['id']; |
||||
|
||||
$url = $this->cache->getOrSet(['post_main_route', 'id' => $id], function () use ($id) { |
||||
if (!$post = $this->repository->find($id)) { |
||||
return null; |
||||
} |
||||
return $post->slug; |
||||
}, null, new TagDependency(['tags' => ['blog']])); |
||||
|
||||
if (!$url) { |
||||
throw new InvalidParamException('Undefined id.'); |
||||
} |
||||
|
||||
$url = $this->prefix . '/' . $url; |
||||
unset($params['id']); |
||||
if (!empty($params) && ($query = http_build_query($params)) !== '') { |
||||
$url .= '?' . $query; |
||||
} |
||||
|
||||
return $url; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private function getPathSlug($path): string |
||||
{ |
||||
$chunks = explode('/', $path); |
||||
return end($chunks); |
||||
} |
||||
} |
@ -0,0 +1,91 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\urls; |
||||
|
||||
use yii\caching\TagDependency; |
||||
use common\modules\blog\repositories\read\BlogTagReadRepository; |
||||
use yii\base\BaseObject; |
||||
use yii\base\InvalidParamException; |
||||
use yii\caching\Cache; |
||||
use yii\web\UrlNormalizerRedirectException; |
||||
use yii\web\UrlRuleInterface; |
||||
|
||||
class BlogTagUrlRule extends BaseObject implements UrlRuleInterface |
||||
{ |
||||
public $prefix = 'blog/tag'; |
||||
|
||||
private $repository; |
||||
private $cache; |
||||
|
||||
public function __construct(BlogTagReadRepository $repository, Cache $cache, $config = []) |
||||
{ |
||||
parent::__construct($config); |
||||
$this->repository = $repository; |
||||
$this->cache = $cache; |
||||
} |
||||
|
||||
public function parseRequest($manager, $request) |
||||
{ |
||||
if (preg_match('#^' . $this->prefix . '/(.*[a-z])$#is', $request->pathInfo, $matches)) { |
||||
$path = $matches['1']; |
||||
|
||||
$result = $this->cache->getOrSet( [ 'blog_tag_route', 'path' => $path ], function () use ( $path ) { |
||||
if ( ! $post = $this->repository->findBySlug( $this->getPathSlug( $path ) ) ) { |
||||
return [ 'id' => null, 'path' => null ]; |
||||
} |
||||
return [ 'id' => $post->id, 'path' => $post->slug ]; |
||||
}, null, new TagDependency(['tags' => ['blog']]) ); |
||||
|
||||
if ( empty( $result['id'] ) ) { |
||||
return false; |
||||
} |
||||
|
||||
if ( $path != $result['path'] ) { |
||||
throw new UrlNormalizerRedirectException( [ |
||||
'blog/post/tag', |
||||
'id' => $result['id'], |
||||
], 301 ); |
||||
} |
||||
|
||||
return [ 'blog/post/tag', [ 'id' => $result['id'] ] ]; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public function createUrl($manager, $route, $params) |
||||
{ |
||||
if ($route == 'blog/post/tag') { |
||||
if (empty($params['id'])) { |
||||
throw new InvalidParamException('Empty id.'); |
||||
} |
||||
$id = $params['id']; |
||||
|
||||
$url = $this->cache->getOrSet(['blog_tag_route', 'id' => $id], function () use ($id) { |
||||
if (!$post = $this->repository->find($id)) { |
||||
return null; |
||||
} |
||||
return $post->slug; |
||||
//return $this->getPagePath($post); |
||||
}, null, new TagDependency(['tags' => ['blog']])); |
||||
|
||||
if (!$url) { |
||||
throw new InvalidParamException('Undefined id.'); |
||||
} |
||||
|
||||
$url = $this->prefix . '/' . $url; |
||||
unset($params['id']); |
||||
if (!empty($params) && ($query = http_build_query($params)) !== '') { |
||||
$url .= '?' . $query; |
||||
} |
||||
|
||||
return $url; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private function getPathSlug($path): string |
||||
{ |
||||
$chunks = explode('/', $path); |
||||
return end($chunks); |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
<?php |
||||
|
||||
use mihaildev\ckeditor\CKEditor; |
||||
use yii\helpers\Html; |
||||
use yii\widgets\ActiveForm; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $model \common\modules\blog\forms\BlogCategoryForm */ |
||||
/* @var $form yii\widgets\ActiveForm */ |
||||
?> |
||||
|
||||
<div class="category-form"> |
||||
|
||||
<?php $form = ActiveForm::begin(); ?> |
||||
|
||||
<div class="box box-default"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Common') ?></div>
|
||||
<div class="box-body"> |
||||
|
||||
<div class="row"> |
||||
<div class="col-md-2"> |
||||
<?= $form->field($model, 'sort')->textInput(['maxlength' => true]) ?> |
||||
</div> |
||||
<div class="col-md-5"> |
||||
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?> |
||||
</div> |
||||
<div class="col-md-5"> |
||||
<?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?> |
||||
<?= $form->field($model, 'description')->widget(CKEditor::className()) ?> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box box-default"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'SEO') ?></div>
|
||||
<div class="box-body"> |
||||
<?= $form->field($model->meta, 'title')->textInput() ?> |
||||
<?= $form->field($model->meta, 'description')->textarea(['rows' => 2]) ?> |
||||
<?= $form->field($model->meta, 'keywords')->textInput() ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="form-group"> |
||||
<?= Html::submitButton(Yii::t('buttons','Save'), ['class' => 'btn btn-success']) ?> |
||||
</div> |
||||
|
||||
<?php ActiveForm::end(); ?> |
||||
|
||||
</div> |
@ -0,0 +1,17 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $model \common\modules\blog\forms\BlogCategoryForm */ |
||||
|
||||
$title = Yii::t('blog', 'Create Category'); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Categories'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $title; |
||||
?> |
||||
<div class="category-create"> |
||||
|
||||
<?= $this->render('_form', [ |
||||
'model' => $model, |
||||
]) ?> |
||||
|
||||
</div> |
@ -0,0 +1,54 @@
|
||||
<?php |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use yii\grid\ActionColumn; |
||||
use yii\helpers\Html; |
||||
use yii\grid\GridView; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $searchModel \common\modules\blog\forms\search\BlogCategorySearch */ |
||||
/* @var $dataProvider yii\data\ActiveDataProvider */ |
||||
|
||||
$title = Yii::t('blog', 'Categories'); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = $title; |
||||
?> |
||||
<div class="user-index"> |
||||
|
||||
<p> |
||||
<?= Html::a(Yii::t('blog', 'Create Category'), ['create'], ['class' => 'btn btn-success']) ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
<?= GridView::widget([ |
||||
'dataProvider' => $dataProvider, |
||||
'filterModel' => $searchModel, |
||||
'columns' => [ |
||||
[ |
||||
'attribute' => 'sort', |
||||
'options' => ['style' => 'width: 100px;'], |
||||
], |
||||
[ |
||||
'attribute' => 'name', |
||||
'value' => function (BlogCategory $model) { |
||||
return Html::a(Html::encode($model->name), ['view', 'id' => $model->id]); |
||||
}, |
||||
'format' => 'raw', |
||||
], |
||||
[ |
||||
'attribute' => 'slug', |
||||
], |
||||
[ |
||||
'attribute' => 'title', |
||||
], |
||||
[ |
||||
'class' => ActionColumn::class, |
||||
'options' => ['style' => 'width: 100px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
], |
||||
]); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,19 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $category \common\modules\blog\entities\BlogCategory */ |
||||
/* @var $model \common\modules\blog\forms\BlogCategoryForm */ |
||||
|
||||
$title = Yii::t('blog', 'Update: {name}', ['name' => $category->name]); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Categories'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = ['label' => $category->name, 'url' => ['view', 'id' => $category->id]]; |
||||
$this->params['breadcrumbs'][] = Yii::t('buttons', 'Editing'); |
||||
?> |
||||
<div class="category-update"> |
||||
|
||||
<?= $this->render('_form', [ |
||||
'model' => $model, |
||||
]) ?> |
||||
|
||||
</div> |
@ -0,0 +1,70 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\widgets\DetailView; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $category \common\modules\blog\entities\BlogCategory */ |
||||
|
||||
$title = $category->name; |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Categories'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $title; |
||||
?> |
||||
<div class="user-view"> |
||||
|
||||
<p> |
||||
<?= Html::a(Yii::t('blog', 'Categories'), ['index'], ['class' => 'btn btn-default']) ?> |
||||
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $category->id], ['class' => 'btn btn-primary']) ?> |
||||
<?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $category->id], [ |
||||
'class' => 'btn btn-danger', |
||||
'data' => [ |
||||
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'), |
||||
'method' => 'post', |
||||
], |
||||
]) ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Common') ?></div>
|
||||
<div class="box-body"> |
||||
<?= DetailView::widget([ |
||||
'model' => $category, |
||||
'attributes' => [ |
||||
'id', |
||||
'name', |
||||
'slug', |
||||
'title', |
||||
'sort', |
||||
], |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Description') ?></div>
|
||||
<div class="box-body"> |
||||
<?= Yii::$app->formatter->asHtml($category->description, [ |
||||
'Attr.AllowedRel' => array('nofollow'), |
||||
'HTML.SafeObject' => true, |
||||
'Output.FlashCompat' => true, |
||||
'HTML.SafeIframe' => true, |
||||
'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%', |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'SEO') ?></div>
|
||||
<div class="box-body"> |
||||
<?= DetailView::widget([ |
||||
'model' => $category, |
||||
'attributes' => [ |
||||
'meta.title', |
||||
'meta.description', |
||||
'meta.keywords', |
||||
], |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,54 @@
|
||||
<?php |
||||
|
||||
use common\modules\blog\entities\BlogComment; |
||||
use yii\grid\ActionColumn; |
||||
use yii\grid\GridView; |
||||
use yii\helpers\StringHelper; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $searchModel \common\modules\blog\forms\search\BlogCommentSearch */ |
||||
/* @var $dataProvider yii\data\ActiveDataProvider */ |
||||
|
||||
$this->title = Yii::t('blog', 'Comments'); |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="blog-comments-index"> |
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
<?= GridView::widget([ |
||||
'dataProvider' => $dataProvider, |
||||
'filterModel' => $searchModel, |
||||
'columns' => [ |
||||
[ |
||||
'attribute' => 'id', |
||||
'options' => ['style' => 'width: 40px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
[ |
||||
'attribute' => 'text', |
||||
'value' => function (BlogComment $model) { |
||||
return StringHelper::truncate(strip_tags($model->text), 100); |
||||
}, |
||||
], |
||||
[ |
||||
'attribute' => 'created_at', |
||||
'format' => ['datetime', 'php:d.m.Y H:i'], |
||||
'options' => ['style' => 'width: 60px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
[ |
||||
'attribute' => 'active', |
||||
'filter' => $searchModel->activeList(), |
||||
'format' => 'boolean', |
||||
'contentOptions' => ['style' => 'width: 150px'], |
||||
], |
||||
[ |
||||
'class' => ActionColumn::class, |
||||
'options' => ['style' => 'width: 100px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
], |
||||
]); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,34 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\bootstrap\ActiveForm; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $post \common\modules\blog\entities\BlogPost */ |
||||
/* @var $model \common\modules\blog\forms\BlogCommentEditForm */ |
||||
|
||||
$this->title = Yii::t('blog', 'Update Post Comment: {name}', ['name' => $post->title]); |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Comment'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = ['label' => $post->title, 'url' => ['view', 'id' => $post->id]]; |
||||
$this->params['breadcrumbs'][] = Yii::t('buttons', 'Editing'); |
||||
?> |
||||
<div class="post-update"> |
||||
|
||||
<?php $form = ActiveForm::begin([ |
||||
'options' => ['enctype'=>'multipart/form-data'] |
||||
]); ?> |
||||
|
||||
<div class="box box-default"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Common') ?></div>
|
||||
<div class="box-body"> |
||||
<?= $form->field($model, 'parentId')->textInput() ?> |
||||
<?= $form->field($model, 'text')->textarea(['rows' => 20]) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="form-group"> |
||||
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?> |
||||
</div> |
||||
|
||||
<?php ActiveForm::end(); ?> |
||||
</div> |
@ -0,0 +1,71 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\widgets\DetailView; |
||||
use core\entities\user\User; |
||||
use common\modules\blog\entities\BlogComment; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $post \common\modules\blog\entities\BlogPost */ |
||||
/* @var $comment BlogComment */ |
||||
/* @var $modificationsProvider yii\data\ActiveDataProvider */ |
||||
|
||||
$this->title = $post->title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Comments'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="user-view"> |
||||
|
||||
<p> |
||||
<?= Html::a(Yii::t('blog', 'Comments'), ['index'], ['class' => 'btn btn-default']) ?> |
||||
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'post_id' => $post->id, 'id' => $comment->id], ['class' => 'btn btn-primary']) ?> |
||||
<?php if ($comment->isActive()): ?> |
||||
<?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'post_id' => $post->id, 'id' => $comment->id], [ |
||||
'class' => 'btn btn-danger', |
||||
'data' => [ |
||||
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'), |
||||
'method' => 'post', |
||||
], |
||||
]) ?> |
||||
<?php else: ?> |
||||
<?= Html::a(Yii::t('buttons', 'Restore'), ['activate', 'post_id' => $post->id, 'id' => $comment->id], [ |
||||
'class' => 'btn btn-success', |
||||
'data' => [ |
||||
'confirm' => Yii::t('buttons', 'Are you sure you want to activate this item?'), |
||||
'method' => 'post', |
||||
], |
||||
]) ?> |
||||
<?php endif; ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
<?= DetailView::widget([ |
||||
'model' => $comment, |
||||
'attributes' => [ |
||||
'id', |
||||
'created_at:boolean', |
||||
'active:boolean', |
||||
[ |
||||
'attribute' => 'user_id', |
||||
'value' => function(BlogComment $comment) { |
||||
return User::findOne($comment->user_id)->username; |
||||
}, |
||||
], |
||||
'parent_id', |
||||
[ |
||||
'attribute' => 'post_id', |
||||
'value' => $post->title, |
||||
], |
||||
], |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
<?= Yii::$app->formatter->asNtext($comment->text) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
@ -0,0 +1,144 @@
|
||||
<?php |
||||
|
||||
use kartik\file\FileInput; |
||||
use mihaildev\ckeditor\CKEditor; |
||||
use yii\helpers\Html; |
||||
use yii\bootstrap\ActiveForm; |
||||
use yii\web\JsExpression; |
||||
use yii\helpers\Url; |
||||
use yii\helpers\Json; |
||||
use yii\helpers\ArrayHelper; |
||||
use kartik\widgets\DateTimePicker; |
||||
use kartik\widgets\Select2; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $model \common\modules\blog\forms\BlogPostForm */ |
||||
/* @var $form yii\widgets\ActiveForm */ |
||||
|
||||
$fetchUrl = Url::to( [ 'tag-search' ] ); |
||||
|
||||
if (isset($model->_post)) { |
||||
$tagsJson = Json::encode( Json::encode( ArrayHelper::map( $model->_post->tags, 'id', 'name' ) ) ); |
||||
|
||||
$js = <<<JS |
||||
var arr = {$tagsJson}; |
||||
$.each(JSON.parse(arr), function( key, value ) { |
||||
$("#posttagform-new_tags").append("<option value='"+value+"' selected>"+value+"</option>"); |
||||
}); |
||||
$('#posttagform-new_tags').trigger('change'); |
||||
JS; |
||||
$this->registerJs( $js, $this::POS_READY ); |
||||
} |
||||
?> |
||||
|
||||
<div class="post-form"> |
||||
|
||||
<?php $form = ActiveForm::begin([ |
||||
'options' => ['enctype'=>'multipart/form-data'] |
||||
]); ?> |
||||
|
||||
<div class="row"> |
||||
<div class="col-md-6"> |
||||
<div class="box box-default"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Common') ?></div>
|
||||
<div class="box-body"> |
||||
<?= $form->field($model, 'category_id')->dropDownList($model->categoriesList(), ['prompt' => '']) ?> |
||||
<?= $form->field($model, 'published_at')->widget(DateTimePicker::classname(), [ |
||||
'options' => [], |
||||
'pluginOptions' => [ |
||||
'autoclose' => true, |
||||
'format' => 'dd.mm.yyyy hh:ii:ss', |
||||
] |
||||
]); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="col-md-6"> |
||||
<div class="box box-default"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Tags') ?></div>
|
||||
<div class="box-body"> |
||||
<?= $form->field($model->tags, 'new_tags')->widget(Select2::classname(), [ |
||||
'options' => [ |
||||
'placeholder' => Yii::t('blog','Set tags...'), |
||||
'multiple' => true, |
||||
], |
||||
'pluginOptions' => [ |
||||
'tags' => true, |
||||
'tokenSeparators' => [',', ' '], |
||||
'maximumInputLength' => 12, |
||||
'ajax' => [ |
||||
'url' => $fetchUrl, |
||||
'dataType' => 'json', |
||||
'data' => new JsExpression('function(params) { return {q:params.term}; }') |
||||
], |
||||
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'), |
||||
'templateResult' => new JsExpression('function(tag) { return tag.text; }'), |
||||
'templateSelection' => new JsExpression('function (tag) { return tag.text; }'), |
||||
], |
||||
])->label(false); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box box-default"> |
||||
<div class="box-body"> |
||||
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?> |
||||
<?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?> |
||||
<?= $form->field($model, 'description')->textarea(['rows' => 5]) ?> |
||||
<?= $form->field($model, 'content')->widget(CKEditor::className()) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box box-default"> |
||||
<div class="box-body"> |
||||
|
||||
<ul class="nav nav-tabs"> |
||||
<li class="active"><a data-toggle="tab" href="#field_image"><?= Yii::t('blog', 'Image') ?></a></li>
|
||||
<li><a data-toggle="tab" href="#field_video"><?= Yii::t('blog', 'Video') ?></a></li>
|
||||
</ul> |
||||
|
||||
<div class="tab-content"> |
||||
<div id="field_image" class="tab-pane fade in active" style="padding-top: 20px;"> |
||||
<?= $form->field($model, 'image')->label(false)->widget(FileInput::class, [ |
||||
'options' => [ |
||||
'accept' => 'image/*', |
||||
], |
||||
'pluginOptions' => [ |
||||
'showUpload' => false, |
||||
], |
||||
]) ?> |
||||
|
||||
<?php if (isset($model->_post) && $model->_post->image): ?> |
||||
<?= Html::img($model->_post->getThumbFileUrl('image', 'thumb_gallery_view'), [ |
||||
'class' => 'thumbnail', |
||||
'width' => 300, |
||||
]) ?> |
||||
|
||||
<?= $form->field($model, 'reset_image')->checkbox() ?> |
||||
<?php endif; ?> |
||||
</div> |
||||
<div id="field_video" class="tab-pane fade" style="padding-top: 20px;"> |
||||
<?= $form->field($model, 'video')->textInput()->label(Yii::t('blog', 'YouTube URL'))->hint(Yii::t('blog', 'If a video link is specified, the image will be used as a preview image')) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box box-default"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'SEO') ?></div>
|
||||
<div class="box-body"> |
||||
<?= $form->field($model->meta, 'title')->textInput() ?> |
||||
<?= $form->field($model->meta, 'description')->textarea(['rows' => 2]) ?> |
||||
<?= $form->field($model->meta, 'keywords')->textInput() ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="form-group"> |
||||
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?> |
||||
</div> |
||||
|
||||
<?php ActiveForm::end(); ?> |
||||
|
||||
</div> |
@ -0,0 +1,17 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $model \common\modules\blog\forms\BlogPostForm */ |
||||
|
||||
$title = Yii::t('blog', 'Create Post'); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Posts'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $title; |
||||
?> |
||||
<div class="post-create"> |
||||
|
||||
<?= $this->render('_form', [ |
||||
'model' => $model, |
||||
]) ?> |
||||
|
||||
</div> |
@ -0,0 +1,76 @@
|
||||
<?php |
||||
|
||||
use common\modules\blog\entities\BlogPost; |
||||
use common\modules\blog\helpers\BlogPostHelper; |
||||
use yii\helpers\Html; |
||||
use yii\grid\ActionColumn; |
||||
use yii\grid\GridView; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $searchModel \common\modules\blog\forms\search\BlogPostSearch */ |
||||
/* @var $dataProvider yii\data\ActiveDataProvider */ |
||||
|
||||
$title = Yii::t('blog', 'All Posts'); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = $title; |
||||
?> |
||||
<div class="blog-post-index"> |
||||
|
||||
<p> |
||||
<?= Html::a(Yii::t('blog', 'Create Post'), ['create'], ['class' => 'btn btn-success']) ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
<?= GridView::widget([ |
||||
'dataProvider' => $dataProvider, |
||||
'filterModel' => $searchModel, |
||||
'columns' => [ |
||||
[ |
||||
'attribute' => 'id', |
||||
'options' => ['style' => 'width: 40px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
[ |
||||
'attribute' => 'title', |
||||
'value' => function (BlogPost $model) { |
||||
return Html::a(Html::encode($model->title), ['view', 'id' => $model->id]); |
||||
}, |
||||
'format' => 'raw', |
||||
], |
||||
[ |
||||
'attribute' => 'category_id', |
||||
'filter' => $searchModel->categoriesList(), |
||||
'value' => 'category.name', |
||||
], |
||||
[ |
||||
'attribute' => 'published_at', |
||||
'format' => ['datetime', 'php:d.m.Y H:i'], |
||||
'options' => ['style' => 'width: 60px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
[ |
||||
'attribute' => 'status', |
||||
'filter' => $searchModel->statusList(), |
||||
'value' => function (BlogPost $model) { |
||||
return BlogPostHelper::statusLabel($model->status); |
||||
}, |
||||
'format' => 'raw', |
||||
'options' => ['style' => 'width: 120px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
[ |
||||
'class' => ActionColumn::class, |
||||
/*'urlCreator' => function($action, BlogPost $model, $key, $index, $column) { |
||||
$params = is_array($key) ? $key : ['id' => (string) $key]; |
||||
$params[0] = $column->controller ? $column->controller . '/' . $action : $action; |
||||
return Url::toRoute($params); |
||||
},*/ |
||||
'options' => ['style' => 'width: 100px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
], |
||||
]); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,21 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $post \common\modules\blog\entities\BlogPost */ |
||||
/* @var $model \common\modules\blog\forms\BlogPostForm */ |
||||
|
||||
use yii\helpers\StringHelper; |
||||
|
||||
$title = Yii::t('blog', 'Update Post: {name}', ['name' => StringHelper::truncateWords($post->title, 6, '...')]); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Posts'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = ['label' => StringHelper::truncateWords($post->title, 4, '...'), 'url' => ['view', 'id' => $post->id]]; |
||||
$this->params['breadcrumbs'][] = Yii::t('buttons', 'Editing'); |
||||
?> |
||||
<div class="post-update"> |
||||
|
||||
<?= $this->render('_form', [ |
||||
'model' => $model, |
||||
]) ?> |
||||
|
||||
</div> |
@ -0,0 +1,138 @@
|
||||
<?php |
||||
|
||||
use common\modules\blog\helpers\BlogPostHelper; |
||||
use yii\helpers\ArrayHelper; |
||||
use yii\helpers\Html; |
||||
use yii\widgets\DetailView; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $post \common\modules\blog\entities\BlogPost */ |
||||
/* @var $modificationsProvider yii\data\ActiveDataProvider */ |
||||
|
||||
$title = $post->title; |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Posts'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $title; |
||||
?> |
||||
<div class="post-view"> |
||||
|
||||
<p> |
||||
<?= Html::a(Yii::t('blog', 'All Posts'), ['index'], ['class' => 'btn btn-default']) ?> |
||||
<?php if ($post->isActive()): ?> |
||||
<?= Html::a(Yii::t('blog', 'Draft'), ['draft', 'id' => $post->id], ['class' => 'btn btn-primary', 'data-method' => 'post']) ?> |
||||
<?php else: ?> |
||||
<?= Html::a(Yii::t('blog', 'Activate'), ['activate', 'id' => $post->id], ['class' => 'btn btn-success', 'data-method' => 'post']) ?> |
||||
<?php endif; ?> |
||||
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $post->id], ['class' => 'btn btn-primary']) ?> |
||||
<?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $post->id], [ |
||||
'class' => 'btn btn-danger', |
||||
'data' => [ |
||||
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'), |
||||
'method' => 'post', |
||||
], |
||||
]) ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Common') ?></div>
|
||||
<div class="box-body"> |
||||
<?= DetailView::widget([ |
||||
'model' => $post, |
||||
'attributes' => [ |
||||
'id', |
||||
[ |
||||
'attribute' => 'status', |
||||
'value' => BlogPostHelper::statusLabel($post->status), |
||||
'format' => 'raw', |
||||
], |
||||
'title', |
||||
[ |
||||
'attribute' => 'category_id', |
||||
'value' => ArrayHelper::getValue($post, 'category.name'), |
||||
], |
||||
[ |
||||
'label' => Yii::t('post', 'Tags'), |
||||
'value' => implode(', ', ArrayHelper::getColumn($post->tags, 'name')), |
||||
], |
||||
], |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php if ($post->image): ?> |
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Image') ?></div>
|
||||
<div class="box-body"> |
||||
<?= Html::img($post->getThumbFileUrl('image', 'thumb_gallery_view'), [ |
||||
'class' => 'thumbnail', |
||||
'width' => 300, |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
<?php if (!$post->image && $post->video): ?> |
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Image') ?></div>
|
||||
<div class="box-body"> |
||||
<?= Html::img('https://i.ytimg.com/vi/' . BlogPostHelper::parseYoutubeUrl($post->video) . '/maxresdefault.jpg', [ |
||||
'width' => 300, |
||||
'class' => 'thumbnail', |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
<?php if ($post->video): ?> |
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Video') ?></div>
|
||||
<div class="box-body"> |
||||
<iframe class="embed-responsive-item" src="https://www.youtube.com/embed/<?= BlogPostHelper::parseYoutubeUrl($post->video) ?>?rel=0" frameborder="0" allowfullscreen></iframe>
|
||||
</div> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Description') ?></div>
|
||||
<div class="box-body"> |
||||
<?= Yii::$app->formatter->asNtext($post->description) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'Content') ?></div>
|
||||
<div class="box-body"> |
||||
<?= Yii::$app->formatter->asHtml($post->content, [ |
||||
'Attr.AllowedRel' => array('nofollow'), |
||||
'HTML.SafeObject' => true, |
||||
'Output.FlashCompat' => true, |
||||
'HTML.SafeIframe' => true, |
||||
'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%', |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="box"> |
||||
<div class="box-header with-border"><?= Yii::t('blog', 'SEO') ?></div>
|
||||
<div class="box-body"> |
||||
<?= DetailView::widget([ |
||||
'model' => $post, |
||||
'attributes' => [ |
||||
[ |
||||
'attribute' => 'meta.title', |
||||
'value' => $post->meta->title, |
||||
], |
||||
[ |
||||
'attribute' => 'meta.description', |
||||
'value' => $post->meta->description, |
||||
], |
||||
[ |
||||
'attribute' => 'meta.keywords', |
||||
'value' => $post->meta->keywords, |
||||
], |
||||
], |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
@ -0,0 +1,29 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\widgets\ActiveForm; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $model \common\modules\blog\forms\BlogTagSingleForm */ |
||||
/* @var $form yii\widgets\ActiveForm */ |
||||
?> |
||||
|
||||
<div class="tag-form"> |
||||
|
||||
<?php $form = ActiveForm::begin(); ?> |
||||
|
||||
<div class="box box-default"> |
||||
<div class="box-body"> |
||||
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?> |
||||
<?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
<div class="form-group"> |
||||
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?> |
||||
</div> |
||||
|
||||
<?php ActiveForm::end(); ?> |
||||
|
||||
</div> |
@ -0,0 +1,17 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $model \common\modules\blog\forms\BlogTagSingleForm */ |
||||
|
||||
$title = Yii::t('blog', 'Create Tag'); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Tags'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="tag-create"> |
||||
|
||||
<?= $this->render('_form', [ |
||||
'model' => $model, |
||||
]) ?> |
||||
|
||||
</div> |
@ -0,0 +1,47 @@
|
||||
<?php |
||||
|
||||
use common\modules\blog\entities\BlogTag; |
||||
use yii\grid\ActionColumn; |
||||
use yii\helpers\Html; |
||||
use yii\grid\GridView; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $searchModel \common\modules\blog\forms\search\BlogTagSearch */ |
||||
/* @var $dataProvider yii\data\ActiveDataProvider */ |
||||
|
||||
$title = Yii::t('blog', 'Tags'); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = $title; |
||||
?> |
||||
<div class="blog-tags-index"> |
||||
|
||||
<p> |
||||
<?= Html::a(Yii::t('blog', 'Create Tag'), ['create'], ['class' => 'btn btn-success']) ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
<?= GridView::widget([ |
||||
'dataProvider' => $dataProvider, |
||||
'filterModel' => $searchModel, |
||||
'columns' => [ |
||||
[ |
||||
'attribute' => 'name', |
||||
'value' => function (BlogTag $model) { |
||||
return Html::a(Html::encode($model->name), ['view', 'id' => $model->id]); |
||||
}, |
||||
'format' => 'raw', |
||||
], |
||||
[ |
||||
'attribute' => 'slug', |
||||
], |
||||
[ |
||||
'class' => ActionColumn::class, |
||||
'options' => ['style' => 'width: 100px;'], |
||||
'contentOptions' => ['class' => 'text-center'], |
||||
], |
||||
], |
||||
]); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,19 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $tag \common\modules\blog\entities\BlogTag */ |
||||
/* @var $model \common\modules\blog\forms\BlogTagSingleForm */ |
||||
|
||||
$title = Yii::t('blog', 'Update Tag: {name}', ['name' => $tag->name]); |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Tags'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = ['label' => $tag->name, 'url' => ['view', 'id' => $tag->id]]; |
||||
$this->params['breadcrumbs'][] = Yii::t('buttons', 'Editing'); |
||||
?> |
||||
<div class="tag-update"> |
||||
|
||||
<?= $this->render('_form', [ |
||||
'model' => $model, |
||||
]) ?> |
||||
|
||||
</div> |
@ -0,0 +1,39 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\widgets\DetailView; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $tag \common\modules\blog\entities\BlogTag */ |
||||
|
||||
$title = $tag->name; |
||||
$this->title = $title; |
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Tags'), 'url' => ['index']]; |
||||
$this->params['breadcrumbs'][] = $title; |
||||
?> |
||||
<div class="user-view"> |
||||
|
||||
<p> |
||||
<?= Html::a(Yii::t('blog', 'Tags'), ['index'], ['class' => 'btn btn-default']) ?> |
||||
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $tag->id], ['class' => 'btn btn-primary']) ?> |
||||
<?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $tag->id], [ |
||||
'class' => 'btn btn-danger', |
||||
'data' => [ |
||||
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'), |
||||
'method' => 'post', |
||||
], |
||||
]) ?> |
||||
</p> |
||||
|
||||
<div class="box"> |
||||
<div class="box-body"> |
||||
<?= DetailView::widget([ |
||||
'model' => $tag, |
||||
'attributes' => [ |
||||
'name', |
||||
'slug', |
||||
], |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,42 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $dataProvider yii\data\DataProviderInterface */ |
||||
|
||||
?> |
||||
|
||||
<article class="heading-component"> |
||||
<div class="heading-component-inner"> |
||||
<h5 class="heading-component-title"><?= Yii::t('blog', 'All Posts') ?></h5>
|
||||
</div> |
||||
</article> |
||||
|
||||
<?= \yii\widgets\ListView::widget([ |
||||
'dataProvider' => $dataProvider, |
||||
'layout' => "<div class='row row-30'>{items}</div>\n<nav class='pagination-wrap' aria-label='Page navigation'>{pager}</nav>", |
||||
'itemView' => '_post', |
||||
'pager' => [ |
||||
//'pagination' => null, |
||||
'maxButtonCount' => 7, |
||||
'pageCssClass' => 'page-item', |
||||
'options' => [ |
||||
'class' => 'pagination', |
||||
], |
||||
'disabledListItemSubTagOptions' => ['tag' => 'div', 'class' => 'disabled'], |
||||
'activePageCssClass' => 'active', |
||||
'linkOptions' => [ |
||||
'class' => 'page-link', |
||||
], |
||||
'prevPageLabel' => '<span class="fa fa-angle-left"></span>', |
||||
'nextPageLabel' => '<span class="fa fa-angle-right"></span>', |
||||
], |
||||
'itemOptions' => [ |
||||
'tag' => false |
||||
], |
||||
'options' => [ |
||||
'tag' => false, |
||||
'class' => 'row row-30', |
||||
'id' => false, |
||||
], |
||||
]) ?> |
||||
|
@ -0,0 +1,51 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $model \common\modules\blog\entities\BlogPost */ |
||||
|
||||
use yii\helpers\Html; |
||||
use yii\helpers\Url; |
||||
use yii\helpers\StringHelper; |
||||
|
||||
$url = Url::to(['blog/post/post', 'id' =>$model->id]); |
||||
$url_full = Yii::$app->params['frontendHostInfo'] . Url::to(['blog/post/post', 'id' =>$model->id]); |
||||
?> |
||||
|
||||
|
||||
<div class="col-md-6"> |
||||
<article class="post-future"> |
||||
<a class="post-future-figure" href="<?= $url ?>">
|
||||
<img src="<?= Html::encode($model->getThumbFileUrl('image', '368_287')) ?>" alt="<?= Html::encode($model->title) ?>" />
|
||||
</a> |
||||
<div class="post-future-main"> |
||||
<h4 class="post-future-title"><a href="<?= $url ?>"><?= Html::encode($model->title) ?></a></h4>
|
||||
<div class="post-future-meta"> |
||||
<!-- Badge--> |
||||
<div class="badge badge-secondary"><?= $model->category->name ?></div>
|
||||
<div class="post-future-time"><span class="icon fa fa-calendar"></span> |
||||
<time datetime="<?= date('Y') ?>"><?= Yii::$app->formatter->asDate($model->published_at, 'php:d F, Y') ?></time>
|
||||
</div> |
||||
</div> |
||||
<hr/> |
||||
<div class="post-future-text"> |
||||
<p><?= StringHelper::truncateWords(Html::encode($model->description), 12, '...') ?></p>
|
||||
</div> |
||||
<div class="post-future-footer group-flex group-flex-xs"><a class="button button-gray-outline" href="#"><?= Yii::t('blog', 'Read more') ?></a>
|
||||
<div class="post-future-share"> |
||||
<div class="inline-toggle-parent"> |
||||
<div class="inline-toggle icon fa fa-share-alt" title="<?= Yii::t('blog', 'Share') ?>"></div>
|
||||
<div class="inline-toggle-element"> |
||||
<ul class="list-inline"> |
||||
<li><span class="fa fa-share-alt"></span></li> |
||||
<li><a target="_blank" class="icon fa fa-facebook" href="https://www.facebook.com/sharer.php?src=sp&u=<?= urlencode($url_full) ?>"></a></li>
|
||||
<li><a target="_blank" class="icon fa fa-odnoklassniki" href="https://connect.ok.ru/offer?url=<?= urlencode($url_full) ?>"></a></li>
|
||||
<li><a target="_blank" class="icon fa fa-google-plus" href="https://plus.google.com/share?url=<?= urlencode($url_full) ?>"></a></li>
|
||||
<li><a target="_blank" class="icon fa fa-vk" href="https://vk.com/share.php?url=<?= urlencode($url_full) ?>"></a></li>
|
||||
</ul> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</article> |
||||
</div> |
@ -0,0 +1,40 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $dataProvider yii\data\DataProviderInterface */ |
||||
/* @var $category \common\modules\blog\entities\BlogCategory */ |
||||
|
||||
use yii\helpers\Html; |
||||
|
||||
$this->title = $category->getSeoTitle(); |
||||
|
||||
$this->registerMetaTag(['name' =>'description', 'content' => $category->meta->description]); |
||||
$this->registerMetaTag(['name' =>'keywords', 'content' => $category->meta->keywords]); |
||||
|
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Blog'), 'url' => ['blog/post/index']]; |
||||
$this->params['breadcrumbs'][] = $category->name; |
||||
|
||||
$this->params['active_category'] = $category; |
||||
?> |
||||
|
||||
<h1><?= Html::encode($category->getHeadingTile()) ?></h1>
|
||||
|
||||
<?php if (trim($category->description)): ?> |
||||
<div class="panel panel-default"> |
||||
<div class="panel-body"> |
||||
<?= Yii::$app->formatter->asHtml($category->description, [ |
||||
'Attr.AllowedRel' => array('nofollow'), |
||||
'HTML.SafeObject' => true, |
||||
'Output.FlashCompat' => true, |
||||
'HTML.SafeIframe' => true, |
||||
'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%', |
||||
]) ?> |
||||
</div> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
<?= $this->render('_list', [ |
||||
'dataProvider' => $dataProvider |
||||
]) ?> |
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $dataProvider yii\data\DataProviderInterface */ |
||||
|
||||
|
||||
$this->title = Yii::t('blog', 'Blog'); |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
|
||||
<?= $this->render('_list', [ |
||||
'dataProvider' => $dataProvider |
||||
]) ?> |
@ -0,0 +1,114 @@
|
||||
<?php |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $post \common\modules\blog\entities\BlogPost */ |
||||
|
||||
use frontend\widgets\post\CommentsWidget; |
||||
use yii\helpers\Html; |
||||
use yii\helpers\Url; |
||||
|
||||
$this->title = $post->getSeoTitle(); |
||||
|
||||
$this->registerMetaTag(['name' =>'description', 'content' => $post->meta->description]); |
||||
$this->registerMetaTag(['name' =>'keywords', 'content' => $post->meta->keywords]); |
||||
|
||||
$this->params['breadcrumbs'][] = ['label' => Yii::t('blog', 'Blog'), 'url' => ['blog/post/index']]; |
||||
$this->params['breadcrumbs'][] = ['label' => $post->category->name, 'url' => ['blog/post/category', 'id' => $post->category->id]]; |
||||
$this->params['breadcrumbs'][] = $post->title; |
||||
|
||||
$this->params['active_category'] = $post->category; |
||||
|
||||
$tagLinks = []; |
||||
foreach ($post->tags as $tag) { |
||||
$tagLinks[] = '<li>' . Html::a(Html::encode($tag->name), ['tag', 'slug' => $tag->slug]) . '</li>'; |
||||
} |
||||
|
||||
$url = Url::to(['blog/post/post', 'id' =>$post->id]); |
||||
$url_full = Yii::$app->params['frontendHostInfo'] . Url::to(['blog/post/post', 'id' =>$post->id]); |
||||
|
||||
$js = <<<JS |
||||
jQuery(document).ready(function($) { |
||||
if (device.desktop() || device.tablet()) { |
||||
var relative_slider = $('#relative_carousel').bxSlider({ |
||||
infiniteLoop: true, |
||||
hideControlOnEnd: true, |
||||
minSlides: 2, |
||||
maxSlides: 2, |
||||
moveSlides: 1, |
||||
slideMargin: 0, |
||||
pager: false, |
||||
prevText: '', |
||||
nextText: '', |
||||
controls: false |
||||
}); |
||||
|
||||
$('#relative-button-prev').on('click', function(){ |
||||
relative_slider.goToPrevSlide(); |
||||
return false; |
||||
}); |
||||
|
||||
$('#relative-button-next').on('click', function(){ |
||||
relative_slider.goToNextSlide(); |
||||
return false; |
||||
}) |
||||
} |
||||
}); |
||||
|
||||
JS; |
||||
$this->registerJs($js, $this::POS_READY); |
||||
?> |
||||
|
||||
|
||||
<div class="blog-post"> |
||||
<!-- Badge--> |
||||
<div class="badge badge-secondary"><?= $post->category->name ?> |
||||
</div> |
||||
<h3 class="blog-post-title"><?= Html::encode($post->title) ?></h3>
|
||||
<div class="blog-post-header"> |
||||
<div class="blog-post-meta"> |
||||
<time class="blog-post-time" datetime="<?= date('Y') ?>"><span class="icon fa fa-calendar"></span><?= Yii::$app->formatter->asDate($post->published_at, 'php:d F, Y') ?></time>
|
||||
<div class="blog-post-comment"><span class="icon fa fa-comment"></span><?= $post->comments_count ?></div>
|
||||
<div class="blog-post-view"><span class="icon fa fa-eye"></span><?= $post->views ?></div>
|
||||
</div> |
||||
</div> |
||||
<div class="blog-post-author-quote"> |
||||
<p><?= $post->description ?></p>
|
||||
</div> |
||||
<div class="blog-post-share"> |
||||
<p><?= Yii::t('blog', 'Share') ?></p>
|
||||
<ul class="group"> |
||||
<li><a target="_blank" class="icon fa fa-facebook" href="https://www.facebook.com/sharer.php?src=sp&u=<?= urlencode($url_full) ?>"></a></li>
|
||||
<li><a target="_blank" class="icon fa fa-odnoklassniki" href="https://connect.ok.ru/offer?url=<?= urlencode($url_full) ?>"></a></li>
|
||||
<li><a target="_blank" class="icon fa fa-google-plus" href="https://plus.google.com/share?url=<?= urlencode($url_full) ?>"></a></li>
|
||||
<li><a target="_blank" class="icon fa fa-vk" href="https://vk.com/share.php?url=<?= urlencode($url_full) ?>"></a></li>
|
||||
</ul> |
||||
</div> |
||||
<div class="blog-post-content"> |
||||
|
||||
<img src="<?= Html::encode($post->getThumbFileUrl('image', '683_407')) ?>" alt="<?= Html::encode($post->title) ?>" width="683" height="407" />
|
||||
|
||||
<?= Yii::$app->formatter->asHtml($post->content, [ |
||||
'Attr.AllowedRel' => array('nofollow'), |
||||
'HTML.SafeObject' => true, |
||||
'Output.FlashCompat' => true, |
||||
'HTML.SafeIframe' => true, |
||||
'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%', |
||||
]) ?> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
<?= \frontend\widgets\post\PostByTagsWidget::widget([ |
||||
'count' => 10, |
||||
'view' => 'slider-relative', |
||||
'post' => $post, |
||||
]) ?> |
||||
|
||||
|
||||
<ul class="list-tags" style="margin-top:20px"><?= implode(', ', $tagLinks) ?></ul>
|
||||
|
||||
<?= CommentsWidget::widget([ |
||||
'post' => $post, |
||||
]) ?> |
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\widgets; |
||||
|
||||
use common\modules\blog\entities\BlogCategory; |
||||
use common\modules\blog\repositories\read\BlogCategoryReadRepository; |
||||
use yii\base\Widget; |
||||
use yii\helpers\Html; |
||||
|
||||
class CategoriesWidget extends Widget |
||||
{ |
||||
/** @var BlogCategory|null */ |
||||
public $active; |
||||
|
||||
private $categories; |
||||
|
||||
public function __construct(BlogCategoryReadRepository $categories, $config = []) |
||||
{ |
||||
parent::__construct($config); |
||||
$this->categories = $categories; |
||||
} |
||||
|
||||
public function run(): string |
||||
{ |
||||
return $this->render('categories/categories', [ |
||||
'categories' => $this->categories->getAll(), |
||||
]); |
||||
} |
||||
} |
@ -0,0 +1,20 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\widgets; |
||||
|
||||
use common\modules\blog\entities\BlogComment; |
||||
|
||||
class CommentView |
||||
{ |
||||
public $comment; |
||||
/** |
||||
* @var self[] |
||||
*/ |
||||
public $children; |
||||
|
||||
public function __construct(BlogComment $comment, array $children) |
||||
{ |
||||
$this->comment = $comment; |
||||
$this->children = $children; |
||||
} |
||||
} |
@ -0,0 +1,57 @@
|
||||
<?php |
||||
|
||||
namespace common\modules\blog\widgets; |
||||
|
||||
use common\modules\blog\entities\BlogComment; |
||||
use common\modules\blog\entities\BlogPost; |
||||
use common\modules\blog\forms\BlogCommentForm; |
||||
use yii\base\InvalidConfigException; |
||||
use yii\base\Widget; |
||||
|
||||
class CommentsWidget extends Widget |
||||
{ |
||||
/** |
||||
* @var BlogPost |
||||
*/ |
||||
public $post; |
||||
|
||||
public function init(): void |
||||
{ |
||||
if (!$this->post) { |
||||
throw new InvalidConfigException('Specify the post.'); |
||||
} |
||||
} |
||||
|
||||
public function run(): string |
||||
{ |
||||
$form = new BlogCommentForm(); |
||||
|
||||
$comments = $this->post->getBlogComments() |
||||
->orderBy(['parent_id' => SORT_ASC, 'id' => SORT_ASC]) |
||||
->all(); |
||||
|
||||
$items = $this->treeRecursive($comments, null); |
||||
|
||||
return $this->render('comments/comments', [ |
||||
'post' => $this->post, |
||||
'items' => $items, |
||||
'commentForm' => $form, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* @param BlogComment[] $comments |
||||
* @param integer $parentId |
||||
* @return CommentView[] |
||||
*/ |
||||
public function treeRecursive(&$comments, $parentId): array |
||||
{ |
||||
$items = []; |
||||
foreach ($comments as $comment) { |
||||
if ($comment->parent_id == $parentId) { |
||||
$items[] = new CommentView($comment, $this->treeRecursive($comments, $comment->id)); |
||||
} |
||||
} |
||||
return $items; |
||||
} |
||||
} |
@ -0,0 +1,39 @@
|
||||
<?php |
||||
/** |
||||
* Created by Error202 |
||||
* Date: 30.01.2018 |
||||
*/ |
||||
|
||||
namespace common\modules\blog\widgets; |
||||
|
||||
use common\modules\blog\entities\BlogPost; |
||||
use yii\base\Widget; |
||||
|
||||
class TagWidget extends Widget |
||||
{ |
||||
public $post_id; |
||||
|
||||
public function run() { |
||||
|
||||
// tags from categories with assignments, ordered by count |
||||
$tags = BlogPost::find()->select('t.name as name, count(t.id) as cnt, t.id as id') |
||||
->from('blog_posts as p, blog_tag_assignments as a, blog_tags as t') |
||||
->andWhere('p.id = a.post_id') |
||||
->andWhere('t.id = a.tag_id') |
||||
->andWhere(isset($this->post_id) ? 'p.id = ' . $this->post_id : '') |
||||
->groupBy('t.id') |
||||
->orderBy('cnt DESC') |
||||
->limit(20) |
||||
->asArray() |
||||
->all(); |
||||
|
||||
if ($tags) { |
||||
return $this->render( 'tags/tags', [ |
||||
'tags' => $tags, |
||||
] ); |
||||
} |
||||
else { |
||||
return ''; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,32 @@
|
||||
<?php |
||||
/** |
||||
* Created by Error202 |
||||
* Date: 21.06.2018 |
||||
*/ |
||||
|
||||
use yii\helpers\Html; |
||||
|
||||
/** |
||||
* @var $this \yii\web\View |
||||
* @var $categories \common\modules\blog\entities\BlogCategory[] |
||||
*/ |
||||
|
||||
?> |
||||
|
||||
<!-- Categories Widget --> |
||||
<div class="card my-4"> |
||||
<h5 class="card-header"><?= Yii::t('blog_public', 'Categories') ?></h5>
|
||||
<div class="card-body"> |
||||
<div class="row"> |
||||
<div class="col-lg-12"> |
||||
<ul class="list-unstyled mb-0 blog-categories-widget-list"> |
||||
<?php foreach ($categories as $category): ?> |
||||
<li> |
||||
<?= Html::a($category->name, ['/blog/post/category', 'id' => $category->id]) ?> |
||||
</li> |
||||
<?php endforeach; ?> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,82 @@
|
||||
<?php |
||||
|
||||
use core\components\avatar_generator\AvatarGenerator; |
||||
|
||||
/* @var $item \common\modules\blog\widgets\CommentView */ |
||||
/* @var $child integer */ |
||||
|
||||
$avatar = new AvatarGenerator(); |
||||
?> |
||||
|
||||
<div data-id="<?= $item->comment->id ?>" class="blog-comment <?= $child ? 'blog-comment-child' : 'blog-comment-parent' ?>" style="margin-left: <?= $child * 30 ?>px">
|
||||
|
||||
<div class="media mb-4"> |
||||
<img class="d-flex mr-3 rounded-circle blog-comment-avatar" src="<?= $avatar->avatar($item->comment->user->id) ?>" alt="">
|
||||
<div class="media-body"> |
||||
<a name="comment_<?= $item->comment->id ?>"></a>
|
||||
<h5 class="mt-0"><?= $item->comment->user->username ?> |
||||
<time class="blog-comment-time" datetime="<?= date('Y', $item->comment->created_at) ?>">
|
||||
<?php |
||||
$date = ($item->comment->created_at > time() - 60*60*24*365*50 |
||||
? Yii::$app->formatter->asRelativeTime($item->comment->created_at) |
||||
: Yii::$app->formatter->asDatetime($item->comment->created_at)); |
||||
?> |
||||
<?= $date ?> |
||||
</time> |
||||
</h5> |
||||
<p> |
||||
<?php if ($item->comment->isActive()): ?> |
||||
<?= Yii::$app->formatter->asNtext($item->comment->text) ?> |
||||
<?php else: ?> |
||||
<i>Comment is deleted.</i> |
||||
<?php endif; ?> |
||||
</p> |
||||
<div class="blog-comment-footer"> |
||||
<?php if (!Yii::$app->user->isGuest): ?> |
||||
<div class="blog-comment-reply"><a href="#"><?= Yii::t('post', 'Reply') ?></a></div>
|
||||
<?php endif; ?> |
||||
</div> |
||||
<div class="reply-block"></div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<!-- |
||||
<div class="post-comment-main"> |
||||
<div class="post-comment-header"> |
||||
<a name="comment_<?= $item->comment->id ?>"></a>
|
||||
<h5 class="author-name"><?= $item->comment->user->username ?></h5>
|
||||
<time class="post-comment-time" datetime="<?= date('Y', $item->comment->created_at) ?>">
|
||||
<?php |
||||
$date = ($item->comment->created_at > time() - 60*60*24*365*50 |
||||
? Yii::$app->formatter->asRelativeTime($item->comment->created_at) |
||||
: Yii::$app->formatter->asDatetime($item->comment->created_at)); |
||||
?> |
||||
<?= $date ?> |
||||
</time> |
||||
</div> |
||||
<div class="post-comment-text"> |
||||
<p> |
||||
<?php if ($item->comment->isActive()): ?> |
||||
<?= Yii::$app->formatter->asNtext($item->comment->text) ?> |
||||
<?php else: ?> |
||||
<i>Comment is deleted.</i> |
||||
<?php endif; ?> |
||||
</p> |
||||
</div> |
||||
<div class="post-comment-footer"> |
||||
<?php if (!Yii::$app->user->isGuest): ?> |
||||
<div class="comment-reply"><span class="icon fa fa-comment"></span><a href="#"><?= Yii::t('post', 'Reply') ?></a></div>
|
||||
<?php endif; ?> |
||||
</div> |
||||
|
||||
<div class="reply-block"></div> |
||||
|
||||
</div>--> |
||||
</div> |
||||
|
||||
|
||||
|
||||
<?php foreach ($item->children as $children): ?> |
||||
<?= $this->render('_comment', ['item' => $children, 'child' => $child + 1]) ?> |
||||
<?php endforeach; ?> |
@ -0,0 +1,103 @@
|
||||
<?php |
||||
|
||||
use yii\bootstrap\ActiveForm; |
||||
use yii\helpers\Html; |
||||
|
||||
/* @var $this yii\web\View */ |
||||
/* @var $post GuzzleHttp\Post\ */ |
||||
/* @var $items \common\modules\blog\widgets\CommentView[] */ |
||||
/* @var $count integer */ |
||||
/* @var $commentForm \common\modules\blog\forms\BlogCommentForm */ |
||||
|
||||
$css = <<<CSS |
||||
a.reply-block-start { |
||||
display: block; |
||||
position: relative; |
||||
top: -100px; |
||||
visibility: hidden; |
||||
} |
||||
a#send-comment { |
||||
font-size: 14px; |
||||
font-weight: normal; |
||||
} |
||||
.heading-component { |
||||
margin-bottom: 20px; |
||||
} |
||||
CSS; |
||||
$this->registerCss( $css ); |
||||
?> |
||||
|
||||
<div class="row"> |
||||
<div class="col-sm-12"> |
||||
<!-- Heading Component--> |
||||
<article class="heading-component"> |
||||
<div class="heading-component-inner"> |
||||
<h5 class="heading-component-title"> |
||||
<?= Yii::t( 'post', 'Comments: {count}', [ 'count' => $post->comments_count ] ) ?> |
||||
|
||||
<?php if ( ! Yii::$app->user->isGuest ): ?> |
||||
<a id="send-comment" href="#reply-block-start" |
||||
class="pull-right"><?= Yii::t( 'post', 'Send comment' ) ?></a>
|
||||
<?php endif; ?> |
||||
</h5> |
||||
</div> |
||||
</article> |
||||
|
||||
<?php if ( count( $items ) > 0 ): ?> |
||||
<div class="blog-post-comments"> |
||||
<?php foreach ( $items as $item ): ?> |
||||
<?= $this->render( '_comment', [ 'item' => $item, 'child' => 0 ] ) ?> |
||||
<?php endforeach; ?> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
<?php if ( ! Yii::$app->user->isGuest ): ?> |
||||
|
||||
<div id="reply-container"> |
||||
<a name="reply-block-start" class="reply-block-start"></a> |
||||
<div id="reply-block" class="leave-reply"> |
||||
|
||||
<?php $form = ActiveForm::begin( [ |
||||
'action' => [ 'comment', 'id' => $post->id ], |
||||
] ); ?> |
||||
|
||||
<?= Html::activeHiddenInput( $commentForm, 'parentId' ) ?> |
||||
<?= $form->field( $commentForm, 'text' )->textarea( [ 'rows' => 5 ] )->label( Yii::t( 'post', 'Comment' ) ) ?> |
||||
|
||||
<div class="form-group"> |
||||
<?= Html::submitButton( Yii::t( 'post', 'Submit' ), [ 'class' => 'btn btn-primary' ] ) ?> |
||||
</div> |
||||
|
||||
<?php ActiveForm::end(); ?> |
||||
</div> |
||||
</div> |
||||
<?php else: ?> |
||||
<div style="text-align: center; padding: 20px;"> |
||||
<?= Yii::t('post', 'Please {login} for writing a comment.', ['login' => Html::a(Yii::t('auth', 'Log in'), ['/auth/auth/login'])]) ?> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
<?php $this->registerJs( " |
||||
jQuery(document).on('click', '.blog-post-comments .blog-comment-reply', function () { |
||||
var link = jQuery(this); |
||||
var form = jQuery('#reply-block'); |
||||
var comment = link.closest('.blog-comment'); |
||||
jQuery('#blogcommentform-parentid').val(comment.data('id')); |
||||
form.detach().appendTo(comment.find('.reply-block:first')); |
||||
return false; |
||||
}); |
||||
|
||||
jQuery(document).on('click', '#send-comment', function () { |
||||
var form = jQuery('#reply-block'); |
||||
jQuery('#blogcommentform-parentid').val(''); |
||||
form.detach().appendTo('#reply-container'); |
||||
//return false; |
||||
}); |
||||
" ); ?> |
||||
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
<?php |
||||
/** |
||||
* Created by Error202 |
||||
* Date: 21.06.2018 |
||||
*/ |
||||
|
||||
use yii\helpers\Html; |
||||
|
||||
/** |
||||
* @var $this \yii\web\View |
||||
* @var $tags array |
||||
*/ |
||||
|
||||
?> |
||||
|
||||
<hr> |
||||
<ul class="list-unstyled"> |
||||
<?php foreach ($tags as $tag): ?> |
||||
<li class="list-inline-item"><i class="fa fa-tag" aria-hidden="true"></i> <?= Html::a($tag['name'], ['/blog/post/tag', 'id' => $tag['id']]) ?></li>
|
||||
<?php endforeach; ?> |
||||
</ul> |
@ -1 +0,0 @@
|
||||
a:2:{i:0;a:2:{s:2:"id";N;s:4:"path";N;}i:1;N;} |
@ -1 +0,0 @@
|
||||
a:2:{i:0;a:2:{s:2:"id";N;s:4:"path";N;}i:1;N;} |
@ -1 +0,0 @@
|
||||
a:2:{i:0;a:2:{s:3:"tid";N;s:4:"path";N;}i:1;N;} |
@ -1 +0,0 @@
|
||||
a:2:{i:0;a:2:{s:3:"tid";N;s:4:"path";N;}i:1;N;} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue