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 |
<?php |
||||||
return [ |
return [ |
||||||
'supportEmail' => 'info@zertex.ru', |
|
||||||
'adminEmail' => 'info@zertex.ru', |
|
||||||
'user.passwordResetTokenExpire' => 3600, |
'user.passwordResetTokenExpire' => 3600, |
||||||
'user.rememberMeDuration' => 3600 * 24 * 30, |
'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